aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog7
-rw-r--r--bfd/elfxx-mips.c49
-rw-r--r--gas/ChangeLog17
-rw-r--r--gas/config/tc-mips.c178
-rw-r--r--include/opcode/ChangeLog6
-rw-r--r--include/opcode/mips.h9
6 files changed, 122 insertions, 144 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index c3fac58..54d926f 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,10 @@
+2011-07-29 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * elfxx-mips.c: Adjust comments throughout.
+ (mips_elf_relax_delete_bytes): Reshape code.
+ (_bfd_mips_elf_relax_section): Remove check for
+ R_MICROMIPS_GPREL16 relocations. Reshape code.
+
2011-07-28 Roland McGrath <mcgrathr@google.com>
* elf32-i386.c (NACL_PLT_ENTRY_SIZE, NACLMASK): New macros.
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index 53a9477..36b881e 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -11910,8 +11910,7 @@ 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++)
- if (isym->st_shndx == sec_shndx
- && isym->st_value > addr)
+ if (isym->st_shndx == sec_shndx && isym->st_value > addr)
isym->st_value -= count;
/* Now adjust the global symbols defined in this section. */
@@ -11928,9 +11927,8 @@ mips_elf_relax_delete_bytes (bfd *abfd,
|| sym_hash->root.type == bfd_link_hash_defweak)
&& sym_hash->root.u.def.section == sec)
{
- bfd_vma value;
+ bfd_vma value = sym_hash->root.u.def.value;
- value = sym_hash->root.u.def.value;
if (ELF_ST_IS_MICROMIPS (sym_hash->other))
value &= MINUS_TWO;
if (value > addr)
@@ -12336,6 +12334,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
unsigned long opcode;
bfd_vma symval;
bfd_vma pcrval;
+ bfd_byte *ptr;
int fndopc;
/* The number of bytes to delete for relaxation and from where
@@ -12347,8 +12346,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
this reloc. */
if (r_type != R_MICROMIPS_HI16
&& r_type != R_MICROMIPS_PC16_S1
- && r_type != R_MICROMIPS_26_S1
- && r_type != R_MICROMIPS_GPREL16)
+ && r_type != R_MICROMIPS_26_S1)
continue;
/* Get the section contents if we haven't done so already. */
@@ -12361,6 +12359,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
goto error_return;
}
+ ptr = contents + irel->r_offset;
/* Read this BFD's local symbols if we haven't done so already. */
if (isymbuf == NULL && symtab_hdr->sh_info != 0)
@@ -12432,8 +12431,8 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
if (irel->r_offset + 4 > sec->size)
continue;
- opcode = bfd_get_16 (abfd, contents + irel->r_offset ) << 16;
- opcode |= bfd_get_16 (abfd, contents + irel->r_offset + 2);
+ opcode = bfd_get_16 (abfd, ptr ) << 16;
+ opcode |= bfd_get_16 (abfd, ptr + 2);
/* This is the pc-relative distance from the instruction the
relocation is applied to, to the symbol referred. */
@@ -12477,7 +12476,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
/* 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
+ && check_br16_dslot (abfd, ptr - 2)
&& !(irel->r_offset >= 4
/* If the instruction is actually a 4-byte branch,
the value of check_br16_dslot doesn't matter.
@@ -12487,7 +12486,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
irel->r_offset - 4)))
continue;
if (irel->r_offset >= 4
- && check_br32_dslot (abfd, contents + irel->r_offset - 4) > 0)
+ && check_br32_dslot (abfd, ptr - 4))
continue;
reg = OP32_SREG (opcode);
@@ -12502,11 +12501,11 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
case 0:
break;
case 2:
- if (check_br16 (abfd, contents + irel->r_offset + 4, reg))
+ if (check_br16 (abfd, ptr + 4, reg))
break;
continue;
case 4:
- if (check_br32 (abfd, contents + irel->r_offset + 4, reg))
+ if (check_br32 (abfd, ptr + 4, reg))
break;
continue;
default:
@@ -12581,8 +12580,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
&& irel->r_offset + 5 < sec->size
&& ((fndopc = find_match (opcode, bz_rs_insns_32)) >= 0
|| (fndopc = find_match (opcode, bz_rt_insns_32)) >= 0)
- && MATCH (bfd_get_16 (abfd, contents + irel->r_offset + 4),
- nop_insn_16))
+ && MATCH (bfd_get_16 (abfd, ptr + 4), nop_insn_16))
{
unsigned long reg;
@@ -12593,10 +12591,8 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
| BZC32_REG_FIELD (reg)
| (opcode & 0xffff)); /* Addend value. */
- bfd_put_16 (abfd, (opcode >> 16) & 0xffff,
- contents + irel->r_offset);
- bfd_put_16 (abfd, opcode & 0xffff,
- contents + irel->r_offset + 2);
+ bfd_put_16 (abfd, (opcode >> 16) & 0xffff, ptr);
+ bfd_put_16 (abfd, opcode & 0xffff, ptr + 2);
/* Delete the 16-bit delay slot NOP: two bytes from
irel->offset + 4. */
@@ -12617,7 +12613,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
bfd_put_16 (abfd,
(b_insn_16.match
| (opcode & 0x3ff)), /* Addend value. */
- contents + irel->r_offset);
+ ptr);
/* Delete 2 bytes from irel->r_offset + 2. */
delcnt = 2;
@@ -12645,7 +12641,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
(bz_insns_16[fndopc].match
| BZ16_REG_FIELD (reg)
| (opcode & 0x7f)), /* Addend value. */
- contents + irel->r_offset);
+ ptr);
/* Delete 2 bytes from irel->r_offset + 2. */
delcnt = 2;
@@ -12661,14 +12657,13 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
unsigned long n32opc;
bfd_boolean relaxed = FALSE;
- n32opc = bfd_get_16 (abfd, contents + irel->r_offset + 4) << 16;
- n32opc |= bfd_get_16 (abfd, contents + irel->r_offset + 6);
+ n32opc = bfd_get_16 (abfd, ptr + 4) << 16;
+ n32opc |= bfd_get_16 (abfd, ptr + 6);
if (MATCH (n32opc, nop_insn_32))
{
/* Replace delay slot 32-bit NOP with a 16-bit NOP. */
- bfd_put_16 (abfd, nop_insn_16.match,
- contents + irel->r_offset + 4);
+ bfd_put_16 (abfd, nop_insn_16.match, ptr + 4);
relaxed = TRUE;
}
@@ -12679,7 +12674,7 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
(move_insn_16.match
| MOVE16_RD_FIELD (MOVE32_RD (n32opc))
| MOVE16_RS_FIELD (MOVE32_RS (n32opc))),
- contents + irel->r_offset + 4);
+ ptr + 4);
relaxed = TRUE;
}
@@ -12691,9 +12686,9 @@ _bfd_mips_elf_relax_section (bfd *abfd, asection *sec,
/* JAL with 32-bit delay slot that is changed to a JALS
with 16-bit delay slot. */
bfd_put_16 (abfd, (jal_insn_32_bd16.match >> 16) & 0xffff,
- contents + irel->r_offset);
+ ptr);
bfd_put_16 (abfd, jal_insn_32_bd16.match & 0xffff,
- contents + irel->r_offset + 2);
+ ptr + 2);
/* Delete 2 bytes from irel->r_offset + 6. */
delcnt = 2;
diff --git a/gas/ChangeLog b/gas/ChangeLog
index e91a35a..25e0b62 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,20 @@
+2011-07-29 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * config/tc-mips.c: Adjust comments throughout.
+ (reglist_lookup): Reshape code.
+ (jmp_reloc_p, jalr_reloc_p): Reformat.
+ (got16_reloc_p, hi16_reloc_p, lo16_reloc_p): Handle microMIPS
+ relocations.
+ (gpr_mod_mask): Remove unused variable.
+ (gpr_read_mask, gpr_write_mask): Reshape code.
+ (fpr_read_mask, fpr_write_mask): Likewise.
+ (nops_for_vr4130): Ensure non-microMIPS mode.
+ (can_swap_branch_p): Correct pinfo2 reference. Reshape code.
+ (append_insn): Skip Loongson 2F workaround in MIPS16 mode. Use
+ the outermost operator of a compound relocation to determines
+ the relocated field. Fix formatting.
+ (md_convert_frag): Reshape code.
+
2011-07-29 Tristan Gingold <gingold@adacore.com>
* frags.c (frag_var_init): New function.
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index af78329..8f57985 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -483,7 +483,7 @@ static int mips_32bitmode = 0;
(strncmp (TARGET_CPU, "mips16", sizeof ("mips16") - 1) == 0 \
|| strncmp (TARGET_CANONICAL, "mips-lsi-elf", sizeof ("mips-lsi-elf") - 1) == 0)
-/* Return true if the given CPU supports microMIPS. */
+/* Return true if the given CPU supports the microMIPS ASE. */
#define CPU_HAS_MICROMIPS(cpu) 0
/* True if CPU has a dror instruction. */
@@ -2141,7 +2141,7 @@ reg_lookup (char **s, unsigned int types, unsigned int *regnop)
As a special exception if one of s0-s7 registers is specified as
the range's lower delimiter and s8 (fp) is its upper one, then no
registers whose numbers place them between s7 and s8 (i.e. $24-$29)
- are selected; they have to be named separately if needed. */
+ are selected; they have to be listed separately if needed. */
static int
reglist_lookup (char **s, unsigned int types, unsigned int *reglistp)
@@ -2150,9 +2150,9 @@ reglist_lookup (char **s, unsigned int types, unsigned int *reglistp)
unsigned int lastregno;
bfd_boolean ok = TRUE;
unsigned int regmask;
- unsigned int regno;
+ char *s_endlist = *s;
char *s_reset = *s;
- char *s_end_of_list = *s;
+ unsigned int regno;
while (reg_lookup (s, types, &regno))
{
@@ -2177,14 +2177,14 @@ reglist_lookup (char **s, unsigned int types, unsigned int *reglistp)
regmask ^= (1 << regno) - 1;
reglist |= regmask;
- s_end_of_list = *s;
+ s_endlist = *s;
if (**s != ',')
break;
(*s)++;
}
if (ok)
- *s = s_end_of_list;
+ *s = s_endlist;
else
*s = s_reset;
if (reglistp)
@@ -2663,41 +2663,36 @@ micromips_reloc_p (bfd_reloc_code_real_type reloc)
}
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
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 reloc == BFD_RELOC_MIPS_JALR || reloc == BFD_RELOC_MICROMIPS_JALR;
}
/* Return true if the given relocation might need a matching %lo().
@@ -2893,17 +2888,15 @@ relax_end (void)
mips_relax.sequence = 0;
}
-/* Return the mask of core registers that instruction IP may
- read or write. */
+/* Return the mask of core registers that IP reads or writes. */
static unsigned int
gpr_mod_mask (const struct mips_cl_insn *ip)
{
- unsigned long pinfo, pinfo2;
+ unsigned long pinfo2;
unsigned int mask;
mask = 0;
- pinfo = ip->insn_mo->pinfo;
pinfo2 = ip->insn_mo->pinfo2;
if (mips_opts.micromips)
{
@@ -2969,27 +2962,20 @@ gpr_read_mask (const struct mips_cl_insn *ip)
if (pinfo & MIPS16_INSN_READ_GPR_X)
mask |= 1 << MIPS16_EXTRACT_OPERAND (REGR32, *ip);
}
- else if (mips_opts.micromips)
- {
- if (pinfo & INSN_READ_GPR_T)
- mask |= 1 << EXTRACT_OPERAND (1, RT, *ip);
- if (pinfo & INSN_READ_GPR_S)
- mask |= 1 << EXTRACT_OPERAND (1, RS, *ip);
- if (pinfo2 & INSN2_READ_GPR_31)
- mask |= 1 << RA;
- if (pinfo2 & INSN2_READ_GP)
- mask |= 1 << GP;
- }
else
{
if (pinfo2 & INSN2_READ_GPR_D)
- mask |= 1 << EXTRACT_OPERAND (0, RD, *ip);
+ mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RD, *ip);
if (pinfo & INSN_READ_GPR_T)
- mask |= 1 << EXTRACT_OPERAND (0, RT, *ip);
+ mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RT, *ip);
if (pinfo & INSN_READ_GPR_S)
- mask |= 1 << EXTRACT_OPERAND (0, RS, *ip);
+ mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RS, *ip);
+ if (pinfo2 & INSN2_READ_GP)
+ mask |= 1 << GP;
+ if (pinfo2 & INSN2_READ_GPR_31)
+ mask |= 1 << RA;
if (pinfo2 & INSN2_READ_GPR_Z)
- mask |= 1 << EXTRACT_OPERAND (0, RZ, *ip);
+ mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RZ, *ip);
}
/* Don't include register 0. */
return mask & ~1;
@@ -3023,23 +3009,14 @@ gpr_write_mask (const struct mips_cl_insn *ip)
if (pinfo & MIPS16_INSN_WRITE_GPR_Y)
mask |= 1 << MIPS16OP_EXTRACT_REG32R (ip->insn_opcode);
}
- else if (mips_opts.micromips)
- {
- if (pinfo & INSN_WRITE_GPR_D)
- mask |= 1 << EXTRACT_OPERAND (1, RD, *ip);
- if (pinfo & INSN_WRITE_GPR_T)
- mask |= 1 << EXTRACT_OPERAND (1, RT, *ip);
- if (pinfo2 & INSN2_WRITE_GPR_S)
- mask |= 1 << EXTRACT_OPERAND (1, RS, *ip);
- if (pinfo & INSN_WRITE_GPR_31)
- mask |= 1 << RA;
- }
else
{
if (pinfo & INSN_WRITE_GPR_D)
mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RD, *ip);
if (pinfo & INSN_WRITE_GPR_T)
mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RT, *ip);
+ if (pinfo2 & INSN2_WRITE_GPR_S)
+ mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RS, *ip);
if (pinfo & INSN_WRITE_GPR_31)
mask |= 1 << RA;
if (pinfo2 & INSN2_WRITE_GPR_Z)
@@ -3060,19 +3037,10 @@ fpr_read_mask (const struct mips_cl_insn *ip)
mask = 0;
pinfo = ip->insn_mo->pinfo;
pinfo2 = ip->insn_mo->pinfo2;
- if (mips_opts.micromips)
+ if (!mips_opts.mips16)
{
if (pinfo2 & INSN2_READ_FPR_D)
- mask |= 1 << EXTRACT_OPERAND (1, FD, *ip);
- if (pinfo & INSN_READ_FPR_S)
- mask |= 1 << EXTRACT_OPERAND (1, FS, *ip);
- if (pinfo & INSN_READ_FPR_T)
- mask |= 1 << EXTRACT_OPERAND (1, FT, *ip);
- if (pinfo & INSN_READ_FPR_R)
- mask |= 1 << EXTRACT_OPERAND (1, FR, *ip);
- }
- else if (!mips_opts.mips16)
- {
+ mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, FD, *ip);
if (pinfo & INSN_READ_FPR_S)
mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, FS, *ip);
if (pinfo & INSN_READ_FPR_T)
@@ -3100,16 +3068,7 @@ fpr_write_mask (const struct mips_cl_insn *ip)
mask = 0;
pinfo = ip->insn_mo->pinfo;
pinfo2 = ip->insn_mo->pinfo2;
- if (mips_opts.micromips)
- {
- if (pinfo2 & INSN_WRITE_FPR_D)
- mask |= 1 << EXTRACT_OPERAND (1, FD, *ip);
- if (pinfo & INSN_WRITE_FPR_S)
- mask |= 1 << EXTRACT_OPERAND (1, FS, *ip);
- if (pinfo & INSN_WRITE_FPR_T)
- mask |= 1 << EXTRACT_OPERAND (1, FT, *ip);
- }
- else if (!mips_opts.mips16)
+ if (!mips_opts.mips16)
{
if (pinfo & INSN_WRITE_FPR_D)
mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, FD, *ip);
@@ -3316,6 +3275,7 @@ nops_for_vr4130 (int ignore, const struct mips_cl_insn *hist,
if (MF_HILO_INSN (hist[i].insn_mo->pinfo))
{
/* Extract the destination register. */
+ gas_assert (!mips_opts.micromips);
mask = gpr_write_mask (&hist[i]);
/* No nops are needed if INSN reads that register. */
@@ -3720,8 +3680,9 @@ can_swap_branch_p (struct mips_cl_insn *ip)
return FALSE;
/* If the previous instruction is in a variant frag other than this
- branch's one, we cannot do the swap. This does not apply to the
- mips16, which uses variant frags for different purposes. */
+ branch's one, we cannot do the swap. This does not apply to
+ MIPS16/microMIPS code, which uses variant frags for different
+ purposes. */
if (!HAVE_CODE_COMPRESSION
&& history[0].frag
&& history[0].frag->fr_type == rs_machine_dependent)
@@ -3781,17 +3742,16 @@ can_swap_branch_p (struct mips_cl_insn *ip)
/* If the previous instruction has an incorrect size for a fixed
branch delay slot in microMIPS mode, we cannot swap. */
- if (mips_opts.micromips)
- {
- pinfo2 = ip->insn_mo->pinfo;
- if ((pinfo2 & INSN2_BRANCH_DELAY_16BIT)
- && insn_length (history) != 2)
- return FALSE;
-
- if ((pinfo2 & INSN2_BRANCH_DELAY_32BIT)
- && insn_length (history) != 4)
- return FALSE;
- }
+ pinfo2 = ip->insn_mo->pinfo2;
+ if (mips_opts.micromips
+ && (pinfo2 & INSN2_BRANCH_DELAY_16BIT)
+ && insn_length (history) != 2)
+ return FALSE;
+ if (mips_opts.micromips
+ && (pinfo2 & INSN2_BRANCH_DELAY_32BIT)
+ && insn_length (history) != 4)
+ return FALSE;
+
return TRUE;
}
@@ -3984,10 +3944,10 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
{
unsigned long prev_pinfo, prev_pinfo2, pinfo, pinfo2;
bfd_boolean relaxed_branch = FALSE;
- bfd_boolean relax32;
enum append_method method;
+ bfd_boolean relax32;
- if (mips_fix_loongson2f && !mips_opts.micromips)
+ if (mips_fix_loongson2f && !HAVE_CODE_COMPRESSION)
fix_loongson2f (ip);
mips_mark_labels ();
@@ -4192,9 +4152,9 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
If the instruction produced is a branch that we will swap with
the preceding instruction, then we add the displacement by which
the branch will be moved backwards. This is more appropriate
- and for MIPS16/microMIPS code also prevents a debugger from placing
- a breakpoint in the middle of the branch (and corrupting code if
- software breakpoints are used). */
+ and for MIPS16/microMIPS code also prevents a debugger from
+ placing a breakpoint in the middle of the branch (and corrupting
+ code if software breakpoints are used). */
dwarf2_emit_insn ((HAVE_CODE_COMPRESSION ? -1 : 0)
+ (method == APPEND_SWAP ? insn_length (history) : 0));
#endif
@@ -4330,6 +4290,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
if (!ip->complete_p && *reloc_type < BFD_RELOC_UNUSED)
{
bfd_reloc_code_real_type final_type[3];
+ reloc_howto_type *howto0;
reloc_howto_type *howto;
int i;
@@ -4340,7 +4301,8 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
/* In a compound relocation, it is the final (outermost)
operator that determines the relocated field. */
- howto = bfd_reloc_type_lookup (stdoutput, final_type[i - 1]);
+ howto = howto0 = bfd_reloc_type_lookup (stdoutput, final_type[i - 1]);
+
if (howto == NULL)
{
/* To reproduce this failure try assembling gas/testsuites/
@@ -4350,16 +4312,17 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
final_type[i - 1]);
howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_16);
}
-
- howto = bfd_reloc_type_lookup (stdoutput, final_type[0]);
+
+ if (i > 1)
+ howto0 = 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,
- howto->pc_relative, final_type[0]);
+ howto0 && howto0->pc_relative,
+ final_type[0]);
/* Tag symbols that have a R_MIPS16_26 relocation against them. */
- if (reloc_type[0] == BFD_RELOC_MIPS16_JMP
- && ip->fixp[0]->fx_addsy)
+ if (final_type[0] == BFD_RELOC_MIPS16_JMP && ip->fixp[0]->fx_addsy)
*symbol_get_tc (ip->fixp[0]->fx_addsy) = 1;
/* These relocations can have an addend that won't fit in
@@ -17800,8 +17763,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
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);
- unsigned long jal, jalr, jr;
-
+ bfd_boolean short_ds;
unsigned long insn;
expressionS exp;
fixS *fixp;
@@ -17841,7 +17803,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
return;
}
- /* Handle 32-bit branches that fit or forced to fit. */
+ /* Handle 32-bit branches that fit or are forced to fit. */
if (!RELAX_MICROMIPS_RELAX32 (fragp->fr_subtype)
|| !RELAX_MICROMIPS_TOOFAR32 (fragp->fr_subtype))
{
@@ -17914,18 +17876,8 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
as_warn_where (fragp->fr_file, fragp->fr_line,
_("Relaxed out-of-range branch into a jump"));
- /* Check the short-delay-slot bit. */
- if (al && (insn & 0x02000000) != 0)
- {
- jal = 0x74000000; /* jals */
- jalr = 0x45e0; /* jalrs */
- }
- else
- {
- jal = 0xf4000000; /* jal */
- jalr = 0x45c0; /* jalr */
- }
- jr = compact ? 0x45a0 : 0x4580; /* jr/c */
+ /* Set the short-delay-slot bit. */
+ short_ds = al && (insn & 0x02000000) != 0;
if (!RELAX_MICROMIPS_UNCOND (fragp->fr_subtype))
{
@@ -17995,6 +17947,8 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
if (mips_pic == NO_PIC)
{
+ unsigned long jal = short_ds ? 0x74000000 : 0xf4000000; /* jal/s */
+
/* j/jal/jals <sym> R_MICROMIPS_26_S1 */
insn = al ? jal : 0xd4000000;
@@ -18019,6 +17973,8 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
else
{
unsigned long at = RELAX_MICROMIPS_AT (fragp->fr_subtype);
+ unsigned long jalr = short_ds ? 0x45e0 : 0x45c0; /* jalr/s */
+ unsigned long jr = compact ? 0x45a0 : 0x4580; /* jr/c */
/* lw/ld $at, <sym>($gp) R_MICROMIPS_GOT16 */
insn = HAVE_64BIT_ADDRESSES ? 0xdc1c0000 : 0xfc1c0000;
diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog
index 3c69275..e7bfecd 100644
--- a/include/opcode/ChangeLog
+++ b/include/opcode/ChangeLog
@@ -1,3 +1,9 @@
+2011-07-29 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * mips.h: Clarify the description of microMIPS instruction
+ manipulation macros.
+ (MICROMIPSOP_MASK_MAJOR, MICROMIPSOP_SH_MAJOR): Remove macros.
+
2011-07-24 Chao-ying Fu <fu@mips.com>
Maciej W. Rozycki <macro@codesourcery.com>
diff --git a/include/opcode/mips.h b/include/opcode/mips.h
index ba68331..609a4af 100644
--- a/include/opcode/mips.h
+++ b/include/opcode/mips.h
@@ -1329,13 +1329,10 @@ extern int bfd_mips_num_opcodes;
extern const struct mips_opcode mips16_opcodes[];
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 MAJOR, no masks are
- provided for the fixed portions of an instruction, since they are
- not needed. */
+/* These are the bit masks and shift counts used for the different fields
+ in the microMIPS instruction formats. No masks are provided for the
+ fixed portions of an instruction, since they are not needed. */
-#define MICROMIPSOP_MASK_MAJOR 0x3f
-#define MICROMIPSOP_SH_MAJOR 26
#define MICROMIPSOP_MASK_IMMEDIATE 0xffff
#define MICROMIPSOP_SH_IMMEDIATE 0
#define MICROMIPSOP_MASK_DELTA 0xffff