* 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.

	gas/
	* 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.

	include/opcode/
	* mips.h: Clarify the description of microMIPS instruction
	manipulation macros.
	(MICROMIPSOP_MASK_MAJOR, MICROMIPSOP_SH_MAJOR): Remove macros.
This commit is contained in:
Maciej W. Rozycki 2011-07-29 22:46:29 +00:00
parent a50242fb51
commit 2309ddf222
6 changed files with 121 additions and 143 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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.

View File

@ -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)
@ -2662,42 +2662,37 @@ 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;
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;
if ((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;

View File

@ -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>

View File

@ -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