This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Continuing this thread from March: Richard Sandiford <rdsandiford@googlemail.com> writes: > "Maciej W. Rozycki" <macro@codesourcery.com> writes: >> As it has turned out in the course of sorting out some earlier concerns >> the microMIPS change needs a couple of updates. For your reference I'm >> sending the current version of the original patch as it had to be >> regenerated. On top of this I'm sending the following updates: > > Everything except binutils-gas-umips-swap.diff is OK (as one commit, > like you say), with the changes below. It seemed a shame to get to the point of an approved version and not actually commit it. I've now updated and regenerated the patch series, made the changes from this approval, and applied a few other things I noticed. I've attached the three patches separately. Tested on mips64-elf mips64el-unknown-kfreebsd-gnu mips64-linux-gnu mips64octeon-linux-gnu mips64-unknown-kfreebsd-gnu mipsel-unknown-kfreebsd-gnu mipsisa32el-linux-gnu mipsisa64-elf mips-linux-gnu mips-unknown-kfreebsd-gnu mips-wrs-vxworks Applied to trunk along with: http://sourceware.org/ml/binutils/2010-12/msg00399.html http://sourceware.org/ml/binutils/2011-02/msg00318.html Maciej: I regenerated and updated each of your patches separately, so if you'd like a copy of those individual patches, I can send them privately. I went on to say: > If you don't agree with some of the requested changes, let me know. and I gather from an off-list discussion a couple of months ago that there were indeed some things that you didn't like. But I think it'd be easier to deal with them as follow-ups. Please feel free to send patches against trunk. Or, if you tell me what it is you disagree with, I can try to fix it myself. I'm sure there are things that we've both missed, but again, we can deal with them as follow-ups. Last, but not least, thanks for all your hard work on this series. Thanks especially for perservering in the face of all my annoying niggles. :-) Richard The regenerated version of your patch series (excluding umips-swap, as per above):
Attachment:
combined.diff.bz2
Description: Binary data
The changes I asked for:
Index: bfd/elfxx-mips.c =================================================================== --- bfd/elfxx-mips.c 2011-07-24 15:06:40.000000000 +0100 +++ bfd/elfxx-mips.c 2011-07-24 15:07:48.000000000 +0100 @@ -5162,7 +5162,7 @@ mips_elf_calculate_relocation (bfd *abfd target_is_16_bit_code_p = ELF_ST_IS_MIPS16 (h->root.other); /* If the output section is the PLT section, then the target is not microMIPS. */ - target_is_micromips_code_p = ((htab->splt != sec) + target_is_micromips_code_p = (htab->splt != sec && ELF_ST_IS_MICROMIPS (h->root.other)); } @@ -11910,18 +11910,9 @@ mips_elf_relax_delete_bytes (bfd *abfd, symtab_hdr = &elf_tdata (abfd)->symtab_hdr; isym = (Elf_Internal_Sym *) symtab_hdr->contents; for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++) - { - bfd_vma value; - - if (isym->st_shndx != sec_shndx) - continue; - - value = isym->st_value; - if (ELF_ST_IS_MICROMIPS (isym->st_other)) - value &= MINUS_TWO; - if (value > addr) - isym->st_value -= count; - } + if (isym->st_shndx == sec_shndx + && isym->st_value > addr) + isym->st_value -= count; /* Now adjust the global symbols defined in this section. */ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) @@ -11932,18 +11923,19 @@ mips_elf_relax_delete_bytes (bfd *abfd, for (; sym_hashes < end_hashes; sym_hashes++) { struct elf_link_hash_entry *sym_hash = *sym_hashes; - bfd_vma value; - - if ((sym_hash->root.type != bfd_link_hash_defined - && sym_hash->root.type != bfd_link_hash_defweak) - || sym_hash->root.u.def.section != sec) - continue; - value = sym_hash->root.u.def.value; - if (ELF_ST_IS_MICROMIPS (sym_hash->other)) - value &= MINUS_TWO; - if (value > addr) - sym_hash->root.u.def.value -= count; + if ((sym_hash->root.type == bfd_link_hash_defined + || sym_hash->root.type == bfd_link_hash_defweak) + && sym_hash->root.u.def.section == sec) + { + bfd_vma value; + + value = sym_hash->root.u.def.value; + if (ELF_ST_IS_MICROMIPS (sym_hash->other)) + value &= MINUS_TWO; + if (value > addr) + sym_hash->root.u.def.value -= count; + } } return TRUE; @@ -12279,6 +12271,27 @@ #define IS_BITSIZE(val, N) \ (((((val) & ((1ULL << (N)) - 1)) ^ (1ULL << ((N) - 1))) \ - (1ULL << ((N) - 1))) == (val)) +/* See if relocations [INTERNAL_RELOCS, IRELEND) confirm that there + is a 4-byte branch at offset OFFSET. */ + +static bfd_boolean +check_4byte_branch (Elf_Internal_Rela *internal_relocs, + Elf_Internal_Rela *irelend, bfd_vma offset) +{ + Elf_Internal_Rela *irel; + unsigned long r_type; + + for (irel = internal_relocs; irel < irelend; irel++) + if (irel->r_offset == offset) + { + r_type = ELF32_R_TYPE (irel->r_info); + if (r_type == R_MICROMIPS_26_S1 + || r_type == R_MICROMIPS_PC16_S1 + || r_type == R_MICROMIPS_JALR) + return TRUE; + } + return FALSE; +} bfd_boolean _bfd_mips_elf_relax_section (bfd *abfd, asection *sec, @@ -12439,12 +12452,8 @@ _bfd_mips_elf_relax_section (bfd *abfd, out the offset). */ if (r_type == R_MICROMIPS_HI16 && MATCH (opcode, lui_insn)) { - Elf_Internal_Rela *ibrrel; - bfd_boolean brc = FALSE; - unsigned int br_r_type; unsigned long nextopc; unsigned long reg; - int bdsize = -1; bfd_vma offset; /* Give up if the previous reloc was a HI16 against this symbol @@ -12466,58 +12475,20 @@ _bfd_mips_elf_relax_section (bfd *abfd, && ELF32_R_SYM (irel[2].r_info) == r_symndx) continue; - /* See if there is a jump or a branch reloc preceding the - LUI instruction immediately. */ - for (ibrrel = internal_relocs; ibrrel < irelend; ibrrel++) - { - offset = irel->r_offset - ibrrel->r_offset; - if (offset != 2 && offset != 4) - continue; - - br_r_type = ELF32_R_TYPE (ibrrel->r_info); - if (offset == 2 - && (br_r_type == R_MICROMIPS_PC7_S1 - || br_r_type == R_MICROMIPS_PC10_S1 - || br_r_type == R_MICROMIPS_JALR)) - break; - if (offset == 4 - && (br_r_type == R_MICROMIPS_26_S1 - || br_r_type == R_MICROMIPS_PC16_S1 - || br_r_type == R_MICROMIPS_JALR)) - { - bfd_byte *ptr = contents + ibrrel->r_offset; - unsigned long bropc; - - bropc = bfd_get_16 (abfd, ptr); - bropc <<= 16; - bropc |= bfd_get_16 (abfd, ptr + 2); - /* Compact branches are OK. */ - if (find_match (opcode, bzc_insns_32) >= 0) - brc = TRUE; - break; - } - } - /* A delay slot was found, give up, sigh... */ - if (!brc && ibrrel < irelend) + /* See if the LUI instruction *might* be in a branch delay slot. */ + if (irel->r_offset >= 2 + && check_br16_dslot (abfd, contents + irel->r_offset - 2) > 0 + && !(irel->r_offset >= 4 + /* If the instruction is actually a 4-byte branch, + the value of check_br16_dslot doesn't matter. + We should use check_br32_dslot to check whether + the branch has a delay slot. */ + && check_4byte_branch (internal_relocs, irelend, + irel->r_offset - 4))) + continue; + if (irel->r_offset >= 4 + && check_br32_dslot (abfd, contents + irel->r_offset - 4) > 0) continue; - - /* Otherwise see if the LUI instruction *might* be in a - branch delay slot. */ - if (!brc) - { - bfd_byte *ptr = contents + irel->r_offset; - - if (irel->r_offset >= 2) - bdsize = check_br16_dslot (abfd, ptr - 2); - /* A branch possibly found, give up, sigh... */ - if (bdsize > 0) - continue; - if (irel->r_offset >= 4) - bdsize = check_br32_dslot (abfd, ptr - 4); - /* A branch possibly found, give up, sigh... */ - if (bdsize > 0) - continue; - } reg = OP32_SREG (opcode); @@ -12545,7 +12516,8 @@ _bfd_mips_elf_relax_section (bfd *abfd, nextopc = bfd_get_16 (abfd, contents + irel[1].r_offset ) << 16; nextopc |= bfd_get_16 (abfd, contents + irel[1].r_offset + 2); - /* Give up unless the same register used with both relocations. */ + /* Give up unless the same register is used with both + relocations. */ if (OP32_SREG (nextopc) != reg) continue; Index: gas/config/tc-mips.c =================================================================== --- gas/config/tc-mips.c 2011-07-24 15:07:45.000000000 +0100 +++ gas/config/tc-mips.c 2011-07-24 15:07:48.000000000 +0100 @@ -2150,7 +2150,7 @@ reglist_lookup (char **s, unsigned int t unsigned int regmask; unsigned int regno; char *s_reset = *s; - char *s_comma = *s; + char *s_end_of_list = *s; while (reg_lookup (s, types, ®no)) { @@ -2175,14 +2175,14 @@ reglist_lookup (char **s, unsigned int t regmask ^= (1 << regno) - 1; reglist |= regmask; - s_comma = *s; + s_end_of_list = *s; if (**s != ',') break; (*s)++; } if (ok) - *s = s_comma; + *s = s_end_of_list; else *s = s_reset; if (reglistp) @@ -2663,24 +2663,41 @@ micromips_reloc_p (bfd_reloc_code_real_t static inline bfd_boolean got16_reloc_p (bfd_reloc_code_real_type reloc) { - return (reloc == BFD_RELOC_MIPS_GOT16 || reloc == BFD_RELOC_MIPS16_GOT16 + return (reloc == BFD_RELOC_MIPS_GOT16 + || reloc == BFD_RELOC_MIPS16_GOT16 || reloc == BFD_RELOC_MICROMIPS_GOT16); } static inline bfd_boolean hi16_reloc_p (bfd_reloc_code_real_type reloc) { - return (reloc == BFD_RELOC_HI16_S || reloc == BFD_RELOC_MIPS16_HI16_S + return (reloc == BFD_RELOC_HI16_S + || reloc == BFD_RELOC_MIPS16_HI16_S || reloc == BFD_RELOC_MICROMIPS_HI16_S); } static inline bfd_boolean lo16_reloc_p (bfd_reloc_code_real_type reloc) { - return (reloc == BFD_RELOC_LO16 || reloc == BFD_RELOC_MIPS16_LO16 + return (reloc == BFD_RELOC_LO16 + || reloc == BFD_RELOC_MIPS16_LO16 || reloc == BFD_RELOC_MICROMIPS_LO16); } +static inline bfd_boolean +jmp_reloc_p (bfd_reloc_code_real_type reloc) +{ + return (reloc == BFD_RELOC_MIPS_JMP + || reloc == BFD_RELOC_MICROMIPS_JMP); +} + +static inline bfd_boolean +jalr_reloc_p (bfd_reloc_code_real_type reloc) +{ + return (reloc == BFD_RELOC_MIPS_JALR + || reloc == BFD_RELOC_MICROMIPS_JALR); +} + /* Return true if the given relocation might need a matching %lo(). This is only "might" because SVR4 R_MIPS_GOT16 relocations only need a matching %lo() when applied to local symbols. */ @@ -3761,7 +3778,7 @@ can_swap_branch_p (struct mips_cl_insn * return FALSE; /* If the previous instruction has an incorrect size for a fixed - branch delay slot in the microMIPS mode, we cannot swap. */ + branch delay slot in microMIPS mode, we cannot swap. */ if (mips_opts.micromips) { pinfo2 = ip->insn_mo->pinfo; @@ -4030,11 +4047,9 @@ append_insn (struct mips_cl_insn *ip, ex case BFD_RELOC_MIPS_JMP: { - bfd_reloc_code_real_type reloc; int shift; - reloc = micromips_map_reloc (*reloc_type); - shift = reloc == BFD_RELOC_MICROMIPS_JMP ? 1 : 2; + shift = mips_opts.micromips ? 1 : 2; if ((address_expr->X_add_number & ((1 << shift) - 1)) != 0) as_bad (_("jump to misaligned address (0x%lx)"), (unsigned long) address_expr->X_add_number); @@ -4057,11 +4072,9 @@ append_insn (struct mips_cl_insn *ip, ex case BFD_RELOC_16_PCREL_S2: { - bfd_reloc_code_real_type reloc; int shift; - reloc = micromips_map_reloc (*reloc_type); - shift = reloc == BFD_RELOC_MICROMIPS_16_PCREL_S1 ? 1 : 2; + shift = mips_opts.micromips ? 1 : 2; if ((address_expr->X_add_number & ((1 << shift) - 1)) != 0) as_bad (_("branch to misaligned address (0x%lx)"), (unsigned long) address_expr->X_add_number); @@ -4313,32 +4326,32 @@ append_insn (struct mips_cl_insn *ip, ex if (!ip->complete_p && *reloc_type < BFD_RELOC_UNUSED) { - bfd_reloc_code_real_type reloc; + bfd_reloc_code_real_type final_type[3]; reloc_howto_type *howto; int i; + /* Perform any necessary conversion to microMIPS relocations + and find out how many relocations there actually are. */ + for (i = 0; i < 3 && reloc_type[i] != BFD_RELOC_UNUSED; i++) + final_type[i] = micromips_map_reloc (reloc_type[i]); + /* In a compound relocation, it is the final (outermost) operator that determines the relocated field. */ - for (i = 1; i < 3; i++) - if (reloc_type[i] == BFD_RELOC_UNUSED) - break; - - reloc = micromips_map_reloc (reloc_type[i - 1]); - howto = bfd_reloc_type_lookup (stdoutput, reloc); + howto = bfd_reloc_type_lookup (stdoutput, final_type[i - 1]); if (howto == NULL) { /* To reproduce this failure try assembling gas/testsuites/ gas/mips/mips16-intermix.s with a mips-ecoff targeted assembler. */ - as_bad (_("Unsupported MIPS relocation number %d"), reloc); + as_bad (_("Unsupported MIPS relocation number %d"), + final_type[i - 1]); howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16); } ip->fixp[0] = fix_new_exp (ip->frag, ip->where, bfd_get_reloc_size (howto), address_expr, - howto->pc_relative, - micromips_map_reloc (reloc_type[0])); + howto->pc_relative, final_type[0]); /* Tag symbols that have a R_MIPS16_26 relocation against them. */ if (reloc_type[0] == BFD_RELOC_MIPS16_JMP @@ -4352,7 +4365,6 @@ append_insn (struct mips_cl_insn *ip, ex && (reloc_type[0] == BFD_RELOC_16 || reloc_type[0] == BFD_RELOC_32 || reloc_type[0] == BFD_RELOC_MIPS_JMP - || reloc_type[0] == BFD_RELOC_MICROMIPS_JMP || reloc_type[0] == BFD_RELOC_GPREL16 || reloc_type[0] == BFD_RELOC_MIPS_LITERAL || reloc_type[0] == BFD_RELOC_GPREL32 @@ -4401,8 +4413,8 @@ append_insn (struct mips_cl_insn *ip, ex if (reloc_type[i] != BFD_RELOC_UNUSED) { ip->fixp[i] = fix_new (ip->frag, ip->where, - ip->fixp[0]->fx_size, NULL, 0, FALSE, - micromips_map_reloc (reloc_type[i])); + ip->fixp[0]->fx_size, NULL, 0, + FALSE, final_type[i]); /* Use fx_tcbit to mark compound relocs. */ ip->fixp[0]->fx_tcbit = 1; @@ -17323,7 +17335,7 @@ md_estimate_size_before_relax (fragS *fr length = relaxed_micromips_16bit_branch_length (fragp, segtype, FALSE); if (length == 4 && RELAX_MICROMIPS_RELAX32 (fragp->fr_subtype)) length = relaxed_micromips_32bit_branch_length (fragp, segtype, FALSE); - fragp->fr_var= length; + fragp->fr_var = length; return length; } @@ -17385,9 +17397,7 @@ mips_fix_adjustable (fixS *fixp) the in-place relocatable field if recalculated against the start address of the symbol's containing section. */ if (HAVE_IN_PLACE_ADDENDS - && (fixp->fx_pcrel - || fixp->fx_r_type == BFD_RELOC_MIPS_JALR - || fixp->fx_r_type == BFD_RELOC_MICROMIPS_JALR)) + && (fixp->fx_pcrel || jalr_reloc_p (fixp->fx_r_type))) return 0; #ifdef OBJ_ELF @@ -17439,8 +17449,7 @@ mips_fix_adjustable (fixS *fixp) || *symbol_get_tc (fixp->fx_addsy) || (HAVE_IN_PLACE_ADDENDS && ELF_ST_IS_MICROMIPS (S_GET_OTHER (fixp->fx_addsy)) - && (fixp->fx_r_type == BFD_RELOC_MIPS_JMP - || fixp->fx_r_type == BFD_RELOC_MICROMIPS_JMP)))) + && jmp_reloc_p (fixp->fx_r_type)))) return 0; #endif @@ -17781,12 +17790,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNU bfd_boolean compact = RELAX_MICROMIPS_COMPACT (fragp->fr_subtype); bfd_boolean al = RELAX_MICROMIPS_LINK (fragp->fr_subtype); int type = RELAX_MICROMIPS_TYPE (fragp->fr_subtype); - - /* Default to the long-delay-slot versions. */ - unsigned long jal = 0xf4000000; /* jal */ - unsigned long jalr = 0x45c0; /* jalr */ - - unsigned long jr = compact ? 0x45a0 : 0x4580; /* jr/c */ + unsigned long jal, jalr, jr; unsigned long insn; expressionS exp; @@ -17798,7 +17802,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNU fragp->fr_fix += fragp->fr_var; - /* Handle 16-bit branches that fit or forced to fit. */ + /* Handle 16-bit branches that fit or are forced to fit. */ if (type != 0 && !RELAX_MICROMIPS_TOOFAR16 (fragp->fr_subtype)) { /* We generate a fixup instead of applying it right now, @@ -17906,6 +17910,12 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNU jal = 0x74000000; /* jals */ jalr = 0x45e0; /* jalrs */ } + else + { + jal = 0xf4000000; /* jal */ + jalr = 0x45c0; /* jalr */ + } + jr = compact ? 0x45a0 : 0x4580; /* jr/c */ if (!RELAX_MICROMIPS_UNCOND (fragp->fr_subtype)) { Index: include/opcode/mips.h =================================================================== --- include/opcode/mips.h 2011-07-24 15:06:40.000000000 +0100 +++ include/opcode/mips.h 2011-07-24 15:07:48.000000000 +0100 @@ -1330,7 +1330,7 @@ #define MIPS16_INSN_COND_BRANCH 0x0 extern const int bfd_mips16_num_opcodes; /* These are the bitmasks and shift counts used for the different - fields in the instruction formats. Other than OP, no masks are + fields in the instruction formats. Other than MAJOR, no masks are provided for the fixed portions of an instruction, since they are not needed. */
The other stuff I noticed while testing:
Index: gas/config/tc-mips.c =================================================================== --- gas/config/tc-mips.c 2011-07-24 15:07:48.000000000 +0100 +++ gas/config/tc-mips.c 2011-07-24 15:07:51.000000000 +0100 @@ -203,9 +203,6 @@ static bfd_boolean mips_in_shared = TRUE pseudo-op. We use a struct so that .set push and .set pop are more reliable. */ -/* Whether or not we emit branch likely macros. */ -static bfd_boolean emit_branch_likely_macro = FALSE; - struct mips_set_options { /* MIPS ISA (Instruction Set Architecture) level. This is set to -1 @@ -644,7 +641,7 @@ static struct hash_control *op_hash = NU /* The opcode hash table we use for the mips16. */ static struct hash_control *mips16_op_hash = NULL; -/* The opcode hash table we use for the micromips. */ +/* The opcode hash table we use for the microMIPS ASE. */ static struct hash_control *micromips_op_hash = NULL; /* This array holds the chars that always start a comment. If the @@ -745,7 +742,7 @@ #define MAX_NOPS 4 #define NOP_INSN (mips_opts.mips16 ? &mips16_nop_insn \ : (mips_opts.micromips ? µmips_nop16_insn : &nop_insn)) -/* The number of bytes NOP takes for the current mode. */ +/* The size of NOP_INSN in bytes. */ #define NOP_INSN_SIZE (HAVE_CODE_COMPRESSION ? 2 : 4) /* If this is set, it points to a frag holding nop instructions which @@ -1251,6 +1248,9 @@ #define MIPS16_EXTRACT_OPERAND(FIELD, IN MIPS16OP_MASK_##FIELD, \ MIPS16OP_SH_##FIELD) +/* Whether or not we are emitting a branch-likely macro. */ +static bfd_boolean emit_branch_likely_macro = FALSE; + /* Global variables used when generating relaxable macros. See the comment above RELAX_ENCODE for more details about how relaxation is used. */ @@ -1292,12 +1292,14 @@ #define MIPS16_EXTRACT_OPERAND(FIELD, IN is the length of the first instruction of the second alternative. For non-relaxable macros, both elements give the length of the first instruction in bytes. + Set to zero if we haven't yet seen the first instruction. */ unsigned int first_insn_sizes[2]; /* For relaxable macros, insns[0] is the number of instructions for the first alternative and insns[1] is the number of instructions for the second alternative. + For non-relaxable macros, both elements give the number of instructions for the macro. */ unsigned int insns[2]; @@ -1542,10 +1544,11 @@ mips_clear_insn_labels (void) } } +/* Mark instruction labels in MIPS16/microMIPS mode. */ + static inline void mips_mark_labels (void) { - /* Mark instruction labels in MIPS16/microMIPS mode. */ if (HAVE_CODE_COMPRESSION) mips_compressed_mark_labels (); } @@ -2071,7 +2074,6 @@ static const struct regname reg_names_n3 {0, 0} }; - /* Check if S points at a valid register specifier according to TYPES. If so, then return 1, advance S to consume the specifier and store the register's number in REGNOP, otherwise return 0. */ @@ -3973,7 +3975,8 @@ micromips_map_reloc (bfd_reloc_code_real /* Output an instruction. IP is the instruction information. ADDRESS_EXPR is an operand of the instruction to be used with - RELOC_TYPE. */ + RELOC_TYPE. EXPANSIONP is true if the instruction is part of + a macro expansion. */ static void append_insn (struct mips_cl_insn *ip, expressionS *address_expr, @@ -4209,12 +4212,12 @@ append_insn (struct mips_cl_insn *ip, ex 16-bit/32-bit instructions. */ && !forced_insn_length); - if (address_expr + if (!HAVE_CODE_COMPRESSION + && address_expr && relax32 && *reloc_type == BFD_RELOC_16_PCREL_S2 && (pinfo & INSN_UNCOND_BRANCH_DELAY || pinfo & INSN_COND_BRANCH_DELAY - || pinfo & INSN_COND_BRANCH_LIKELY) - && !HAVE_CODE_COMPRESSION) + || pinfo & INSN_COND_BRANCH_LIKELY)) { relaxed_branch = TRUE; add_relaxed_insn (ip, (relaxed_branch_length @@ -4232,14 +4235,14 @@ append_insn (struct mips_cl_insn *ip, ex address_expr->X_add_number); *reloc_type = BFD_RELOC_UNUSED; } - else if (address_expr + else if (mips_opts.micromips + && address_expr && ((relax32 && *reloc_type == BFD_RELOC_16_PCREL_S2) || *reloc_type > BFD_RELOC_UNUSED) && (pinfo & INSN_UNCOND_BRANCH_DELAY || pinfo & INSN_COND_BRANCH_DELAY || (pinfo2 & ~INSN2_ALIAS) == INSN2_UNCOND_BRANCH - || pinfo2 & INSN2_COND_BRANCH) - && mips_opts.micromips) + || pinfo2 & INSN2_COND_BRANCH)) { bfd_boolean relax16 = *reloc_type > BFD_RELOC_UNUSED; int type = relax16 ? *reloc_type - BFD_RELOC_UNUSED : 0; @@ -4348,6 +4351,7 @@ append_insn (struct mips_cl_insn *ip, ex howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16); } + howto = bfd_reloc_type_lookup (stdoutput, final_type[0]); ip->fixp[0] = fix_new_exp (ip->frag, ip->where, bfd_get_reloc_size (howto), address_expr, @@ -4503,12 +4507,10 @@ append_insn (struct mips_cl_insn *ip, ex && (history[0].insn_mo->pinfo & MIPS16_INSN_UNCOND_BRANCH))) mips_no_prev_insn (); - /* For branch likely macro, we need to emit a label at the end. */ + /* We need to emit a label at the end of branch-likely macros. */ if (emit_branch_likely_macro) { emit_branch_likely_macro = FALSE; - - /* We need to generate a label. */ micromips_add_label (); } @@ -4723,8 +4725,7 @@ macro_end (void) relax_substateT s; const char *msg; - s = (subtype - & (RELAX_SECOND_LONGER | RELAX_NOMACRO | RELAX_DELAY_SLOT)); + s = subtype & (RELAX_SECOND_LONGER | RELAX_NOMACRO | RELAX_DELAY_SLOT); msg = macro_warning (s); if (msg != NULL) as_warn ("%s", msg); @@ -5259,7 +5260,7 @@ macro_build_jalr (expressionS *ep, int c static const bfd_reloc_code_real_type jalr_relocs[2] = { BFD_RELOC_MIPS_JALR, BFD_RELOC_MICROMIPS_JALR }; bfd_reloc_code_real_type jalr_reloc = jalr_relocs[mips_opts.micromips]; - const char *jalr = mips_opts.noreorder && !cprestore ? "jalr" : "jalrs"; + const char *jalr; char *f = NULL; if (MIPS_JALR_HINT_P (ep)) @@ -5269,10 +5270,14 @@ macro_build_jalr (expressionS *ep, int c } if (!mips_opts.micromips) macro_build (NULL, "jalr", "d,s", RA, PIC_CALL_REG); - else if (MIPS_JALR_HINT_P (ep)) - macro_build (NULL, jalr, "t,s", RA, PIC_CALL_REG); else - macro_build (NULL, jalr, "mj", PIC_CALL_REG); + { + jalr = mips_opts.noreorder && !cprestore ? "jalr" : "jalrs"; + if (MIPS_JALR_HINT_P (ep)) + macro_build (NULL, jalr, "t,s", RA, PIC_CALL_REG); + else + macro_build (NULL, jalr, "mj", PIC_CALL_REG); + } if (MIPS_JALR_HINT_P (ep)) fix_new_exp (frag_now, f - frag_now->fr_literal, 4, ep, FALSE, jalr_reloc); } @@ -6031,23 +6036,28 @@ add_got_offset_hilo (int dest, expressio /* Emit a sequence of instructions to emulate a branch likely operation. BR is an ordinary branch corresponding to one to be emulated. BRNEG is its complementing branch with the original condition negated. - CALL is set if the original branch specified the link operation. EP, - FMT, SREG and TREG specify the usual macro_build() parameters. + CALL is set if the original branch specified the link operation. + EP, FMT, SREG and TREG specify the usual macro_build() parameters. Code like this is produced in the noreorder mode: + BRNEG <args>, 1f nop b <sym> delay slot (executed only if branch taken) 1: - or: + + or, if CALL is set: + BRNEG <args>, 1f nop bal <sym> delay slot (executed only if branch taken) 1: - if CALL is set. In the reorder mode the delay slot would be filled - with a nop anyway, so code produced is simply: + + In the reorder mode the delay slot would be filled with a nop anyway, + so code produced is simply: + BR <args>, <sym> nop Index: gas/testsuite/gas/mips/dli.s =================================================================== --- gas/testsuite/gas/mips/dli.s 2011-07-24 15:01:44.000000000 +0100 +++ gas/testsuite/gas/mips/dli.s 2011-07-24 15:07:51.000000000 +0100 @@ -62,6 +62,4 @@ foo: dli $4,0x003ffc03ffffc000 # Round to a 16 byte boundary, for ease in testing multiple targets. - nop - nop - nop + .p2align 4 Index: gas/testsuite/gas/mips/micromips-trap.d =================================================================== --- gas/testsuite/gas/mips/micromips-trap.d 2011-07-24 15:05:46.000000000 +0100 +++ gas/testsuite/gas/mips/micromips-trap.d 2011-07-24 15:07:52.000000000 +0100 @@ -1,6 +1,6 @@ #objdump: -dr --show-raw-insn #name: microMIPS for MIPS32r2 (w/traps) -#as: -mips32r2 -32 -trap -mfp64 +#as: -mips32r2 -32 -trap -mfp64 -EB #stderr: micromips.l #source: micromips.s Index: gas/testsuite/gas/mips/micromips.d =================================================================== --- gas/testsuite/gas/mips/micromips.d 2011-07-24 15:05:46.000000000 +0100 +++ gas/testsuite/gas/mips/micromips.d 2011-07-24 15:07:52.000000000 +0100 @@ -1,6 +1,6 @@ #objdump: -dr --show-raw-insn #name: microMIPS for MIPS32r2 -#as: -mips32r2 -32 -mfp64 +#as: -mips32r2 -32 -mfp64 -EB #stderr: micromips.l #source: micromips.s Index: gas/testsuite/gas/mips/micromips@dli.d =================================================================== --- gas/testsuite/gas/mips/micromips@dli.d 2011-07-24 15:05:46.000000000 +0100 +++ gas/testsuite/gas/mips/micromips@dli.d 2011-07-24 15:07:51.000000000 +0100 @@ -113,7 +113,4 @@ Disassembly of section \.text: [0-9a-f]+ <[^>]*> 5084 ffff ori a0,a0,0xffff [0-9a-f]+ <[^>]*> 5884 8000 dsll a0,a0,0x10 [0-9a-f]+ <[^>]*> 5084 c000 ori a0,a0,0xc000 -[0-9a-f]+ <[^>]*> 0c00 nop -[0-9a-f]+ <[^>]*> 0c00 nop -[0-9a-f]+ <[^>]*> 0c00 nop -[0-9a-f]+ <[^>]*> 0c00 nop + \.\.\. Index: gas/testsuite/gas/mips/micromips@elfel-rel2.d =================================================================== --- /dev/null 2011-07-24 10:34:17.994719526 +0100 +++ gas/testsuite/gas/mips/micromips@elfel-rel2.d 2011-07-24 15:07:52.000000000 +0100 @@ -0,0 +1,28 @@ +#objdump: -sr -j .text +#name: MIPS ELF reloc 2 +#source: elf-rel2.s +#as: -mabi=o64 + +# Test the GPREL and LITERAL generation (microMIPS). +# FIXME: really this should check that the contents of .sdata, .lit4, +# and .lit8 are correct too. + +.*: +file format .*mips.* + +RELOCATION RECORDS FOR \[\.text\]: +OFFSET [ ]+ TYPE VALUE +0+0000000 R_MICROMIPS_LITERAL \.lit8 +0+0000004 R_MICROMIPS_LITERAL \.lit8 +0+0000008 R_MICROMIPS_LITERAL \.lit8 +0+000000c R_MICROMIPS_LITERAL \.lit4 +0+0000010 R_MICROMIPS_LITERAL \.lit4 +0+0000014 R_MICROMIPS_LITERAL \.lit4 +0+0000018 R_MICROMIPS_GPREL16 \.sdata +0+000001c R_MICROMIPS_GPREL16 \.sdata +0+0000020 R_MICROMIPS_GPREL16 \.sdata + + +Contents of section \.text: + 0000 5cbc0000 5cbc0800 5cbc1000 5c9c0000 .* + 0010 5c9c0400 5c9c0800 5cfc0000 5cfc0400 .* + 0020 5cfc0800 .* Index: gas/testsuite/gas/mips/micromips@mips4-branch-likely.d =================================================================== --- gas/testsuite/gas/mips/micromips@mips4-branch-likely.d 2011-07-24 15:05:46.000000000 +0100 +++ gas/testsuite/gas/mips/micromips@mips4-branch-likely.d 2011-07-24 15:07:51.000000000 +0100 @@ -1,6 +1,7 @@ #objdump: -dr --prefix-addresses --show-raw-insn #name: MIPS mips4 branch-likely instructions #source: mips4-branch-likely.s +#as: -32 # Test mips4 branch-likely instructions (microMIPS). Index: gas/testsuite/gas/mips/micromips@mips4-fp.d =================================================================== --- gas/testsuite/gas/mips/micromips@mips4-fp.d 2011-07-24 15:05:46.000000000 +0100 +++ gas/testsuite/gas/mips/micromips@mips4-fp.d 2011-07-24 15:07:51.000000000 +0100 @@ -1,6 +1,7 @@ #objdump: -dr --prefix-addresses --show-raw-insn #name: MIPS mips4 fp #source: mips4-fp.s +#as: -32 # Test mips4 fp instructions (microMIPS). Index: gas/testsuite/gas/mips/mips.exp =================================================================== --- gas/testsuite/gas/mips/mips.exp 2011-07-24 15:06:40.000000000 +0100 +++ gas/testsuite/gas/mips/mips.exp 2011-07-24 15:07:51.000000000 +0100 @@ -489,21 +489,31 @@ if { [istarget mips*-*-vxworks*] } { run_dump_test "eret-1" run_dump_test "eret-2" run_dump_test "eret-3" - run_dump_test_arches "24k-branch-delay-1" [mips_arch_list_matching mips1] + run_dump_test_arches "24k-branch-delay-1" \ + [mips_arch_list_matching mips1 !micromips] run_dump_test_arches "24k-triple-stores-1" \ - [mips_arch_list_matching mips32r2 !octeon] - run_dump_test_arches "24k-triple-stores-2" [mips_arch_list_matching mips2] - run_dump_test_arches "24k-triple-stores-3" [mips_arch_list_matching mips3] - run_dump_test_arches "24k-triple-stores-4" [mips_arch_list_matching mips2] - run_dump_test_arches "24k-triple-stores-5" [mips_arch_list_matching mips1] - run_dump_test_arches "24k-triple-stores-6" [mips_arch_list_matching mips2] - run_dump_test_arches "24k-triple-stores-7" [mips_arch_list_matching mips2] - run_dump_test_arches "24k-triple-stores-8" [mips_arch_list_matching mips1] - run_dump_test_arches "24k-triple-stores-9" [mips_arch_list_matching mips1] - run_dump_test_arches "24k-triple-stores-10" [mips_arch_list_matching mips1] + [mips_arch_list_matching mips32r2 !octeon !micromips] + run_dump_test_arches "24k-triple-stores-2" \ + [mips_arch_list_matching mips2 !micromips] + run_dump_test_arches "24k-triple-stores-3" \ + [mips_arch_list_matching mips3 !micromips] + run_dump_test_arches "24k-triple-stores-4" \ + [mips_arch_list_matching mips2 !micromips] + run_dump_test_arches "24k-triple-stores-5" \ + [mips_arch_list_matching mips1 !micromips] + run_dump_test_arches "24k-triple-stores-6" \ + [mips_arch_list_matching mips2 !micromips] + run_dump_test_arches "24k-triple-stores-7" \ + [mips_arch_list_matching mips2 !micromips] + run_dump_test_arches "24k-triple-stores-8" \ + [mips_arch_list_matching mips1 !micromips] + run_dump_test_arches "24k-triple-stores-9" \ + [mips_arch_list_matching mips1 !micromips] + run_dump_test_arches "24k-triple-stores-10" \ + [mips_arch_list_matching mips1 !micromips] if $elf { run_dump_test_arches "24k-triple-stores-11" \ - [mips_arch_list_matching mips1] + [mips_arch_list_matching mips1 !micromips] } if $elf { Index: gas/testsuite/gas/mips/mipsel16-e.d =================================================================== --- gas/testsuite/gas/mips/mipsel16-e.d 2011-07-24 15:01:44.000000000 +0100 +++ gas/testsuite/gas/mips/mipsel16-e.d 2011-07-24 15:07:52.000000000 +0100 @@ -1,4 +1,4 @@ -#objdump: -rst -mips16 +#objdump: -rst --special-syms -mips16 #name: MIPS16 reloc #as: -32 -mips16 #source: mips16-e.s Index: gas/testsuite/gas/mips/tmipsel16-e.d =================================================================== --- gas/testsuite/gas/mips/tmipsel16-e.d 2011-07-24 15:01:44.000000000 +0100 +++ gas/testsuite/gas/mips/tmipsel16-e.d 2011-07-24 15:07:52.000000000 +0100 @@ -1,4 +1,4 @@ -#objdump: -rst -mips16 +#objdump: -rst --special-syms -mips16 #name: MIPS16 reloc #as: -32 -mips16 #source: mips16-e.s Index: ld/testsuite/ld-mips-elf/mips-elf.exp =================================================================== --- ld/testsuite/ld-mips-elf/mips-elf.exp 2011-07-24 15:05:46.000000000 +0100 +++ ld/testsuite/ld-mips-elf/mips-elf.exp 2011-07-24 15:07:51.000000000 +0100 @@ -129,19 +129,19 @@ run_dump_test "jalx-1" if { $linux_gnu } { run_ld_link_tests [list \ [list "Dummy shared library for JALX test 2" \ - "-shared -nostdlib" \ + "-shared -nostdlib -melf32btsmip" \ "-G0 -EB -mmicromips -no-mdebug -mabi=32 -march=mips32r2 -KPIC" \ { jalx-2-printf.s } \ {} \ "libjalx-2.so"] \ [list "Dummy external function for JALX test 2" \ - "-r" \ + "-r -melf32btsmip" \ "-G0 -EB -no-mdebug -mabi=32 -march=mips32r2 -mno-shared -call_nonpic" \ { jalx-2-ex.s } \ {} \ "jalx-2-ex.o.r"] \ [list "MIPS JALX test 2" \ - "-nostdlib -T jalx-2.ld tmpdir/libjalx-2.so tmpdir/jalx-2-ex.o.r" \ + "-nostdlib -T jalx-2.ld tmpdir/libjalx-2.so tmpdir/jalx-2-ex.o.r -melf32btsmip" \ "-G0 -EB -mmicromips -no-mdebug -mabi=32 -march=mips32r2 -mno-shared -call_nonpic" \ { jalx-2-main.s } \ { { objdump -d jalx-2.dd } } \
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |