|| mips_opts.arch == CPU_R10000 \
|| mips_opts.arch == CPU_R12000 \
|| mips_opts.arch == CPU_RM7000 \
- || mips_opts.arch == CPU_SB1 \
|| mips_opts.arch == CPU_VR5500 \
)
level I. */
#define gpr_interlocks \
(mips_opts.isa != ISA_MIPS1 \
- || mips_opts.arch == CPU_VR5400 \
- || mips_opts.arch == CPU_VR5500 \
|| mips_opts.arch == CPU_R3900)
/* Whether the processor uses hardware interlocks to avoid delays
&& mips_opts.isa != ISA_MIPS2 \
&& mips_opts.isa != ISA_MIPS3) \
|| mips_opts.arch == CPU_R4300 \
- || mips_opts.arch == CPU_VR5400 \
- || mips_opts.arch == CPU_VR5500 \
- || mips_opts.arch == CPU_SB1 \
)
/* Whether the processor uses hardware interlocks to protect reads
16, 17, 2, 3, 4, 5, 6, 7
};
-static int mips_fix_4122_bugs;
+static int mips_fix_vr4120;
/* We don't relax branches by default, since this causes us to expand
`la .l2 - .l1' if there's a branch between .l1 and .l2, because we
if (prev_prev_nop && nops == 0)
++nops;
- if (mips_fix_4122_bugs && prev_insn.insn_mo->name)
+ if (mips_fix_vr4120 && prev_insn.insn_mo->name)
{
/* We're out of bits in pinfo, so we must resort to string
ops here. Shortcuts are selected based on opcodes being
- limited to the VR4122 instruction set. */
+ limited to the VR4120 instruction set. */
int min_nops = 0;
const char *pn = prev_insn.insn_mo->name;
const char *tn = ip->insn_mo->name;
++nops;
}
- if (mips_fix_4122_bugs && prev_insn.insn_mo->name)
+ if (mips_fix_vr4120 && prev_insn.insn_mo->name)
{
int min_nops = 0;
const char *pn = prev_insn.insn_mo->name;
macro_build (&lo32, "ori", "t,r,i", reg, freg, BFD_RELOC_LO16);
}
+static inline void
+load_delay_nop (void)
+{
+ if (!gpr_interlocks)
+ macro_build (NULL, "nop", "");
+}
+
/* Load an address into a register. */
static void
ep->X_add_number = 0;
macro_build (ep, ADDRESS_LOAD_INSN, "t,o(b)", reg,
BFD_RELOC_MIPS_GOT16, mips_gp_register);
- macro_build (NULL, "nop", "");
+ load_delay_nop ();
relax_start (ep->X_add_symbol);
relax_switch ();
macro_build (ep, ADDRESS_ADDI_INSN, "t,r,j", reg, reg,
}
macro_build (ep, ADDRESS_LOAD_INSN, "t,o(b)", reg,
BFD_RELOC_MIPS_GOT16, mips_gp_register);
- macro_build (NULL, "nop", "");
+ load_delay_nop ();
macro_build (ep, ADDRESS_ADDI_INSN, "t,r,j", reg, reg,
BFD_RELOC_LO16);
relax_end ();
/* We're going to put in an addu instruction using
tempreg, so we may as well insert the nop right
now. */
- macro_build (NULL, "nop", "");
+ load_delay_nop ();
}
relax_switch ();
macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)",
tempreg, BFD_RELOC_MIPS_GOT16, mips_gp_register);
- macro_build (NULL, "nop", "");
+ load_delay_nop ();
macro_build (&offset_expr, ADDRESS_ADDI_INSN, "t,r,j",
tempreg, tempreg, BFD_RELOC_LO16);
relax_end ();
&& offset_expr.X_add_number < 0x8000)
{
load_got_offset (tempreg, &offset_expr);
- macro_build (NULL, "nop", "");
+ load_delay_nop ();
add_got_offset (tempreg, &offset_expr);
}
else
not using a base register. */
if (breg == treg)
{
- macro_build (NULL, "nop", "");
+ load_delay_nop ();
macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
treg, AT, breg);
breg = 0;
/* We're going to put in an addu instruction using
tempreg, so we may as well insert the nop right
now. */
- macro_build (NULL, "nop", "");
+ load_delay_nop ();
}
}
else if (expr1.X_add_number >= -0x8000
&& expr1.X_add_number < 0x8000)
{
- macro_build (NULL, "nop", "");
+ load_delay_nop ();
macro_build (&expr1, ADDRESS_ADDI_INSN, "t,r,j",
tempreg, tempreg, BFD_RELOC_LO16);
}
else
{
assert (tempreg == AT);
- macro_build (NULL, "nop", "");
+ load_delay_nop ();
macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
treg, AT, breg);
dreg = treg;
if (expr1.X_add_number >= -0x8000
&& expr1.X_add_number < 0x8000)
{
- macro_build (NULL, "nop", "");
+ load_delay_nop ();
macro_build (&offset_expr, ADDRESS_ADDI_INSN, "t,r,j",
tempreg, tempreg, BFD_RELOC_LO16);
/* FIXME: If add_number is 0, and there was no base
/* We must add in the base register now, as in the
external symbol case. */
assert (tempreg == AT);
- macro_build (NULL, "nop", "");
+ load_delay_nop ();
macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
treg, AT, breg);
tempreg = treg;
macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)",
PIC_CALL_REG, BFD_RELOC_MIPS_CALL16,
mips_gp_register);
- macro_build (NULL, "nop", "");
+ load_delay_nop ();
relax_switch ();
}
else
macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)",
PIC_CALL_REG, BFD_RELOC_MIPS_CALL_LO16,
PIC_CALL_REG);
- macro_build (NULL, "nop", "");
+ load_delay_nop ();
relax_switch ();
if (gpdelay)
macro_build (NULL, "nop", "");
macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)",
PIC_CALL_REG, BFD_RELOC_MIPS_GOT16,
mips_gp_register);
- macro_build (NULL, "nop", "");
+ load_delay_nop ();
macro_build (&offset_expr, ADDRESS_ADDI_INSN, "t,r,j",
PIC_CALL_REG, PIC_CALL_REG, BFD_RELOC_LO16);
relax_end ();
as_bad (_("PIC code offset overflow (max 16 signed bits)"));
macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", tempreg,
lw_reloc_type, mips_gp_register);
- macro_build (NULL, "nop", "");
+ load_delay_nop ();
relax_start (offset_expr.X_add_symbol);
relax_switch ();
macro_build (&offset_expr, ADDRESS_ADDI_INSN, "t,r,j", tempreg,
macro_build (NULL, "nop", "");
macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", tempreg,
BFD_RELOC_MIPS_GOT16, mips_gp_register);
- macro_build (NULL, "nop", "");
+ load_delay_nop ();
macro_build (&offset_expr, ADDRESS_ADDI_INSN, "t,r,j", tempreg,
tempreg, BFD_RELOC_LO16);
relax_end ();
|| expr1.X_add_number >= 0x8000 - 4)
as_bad (_("PIC code offset overflow (max 16 signed bits)"));
load_got_offset (AT, &offset_expr);
- macro_build (NULL, "nop", "");
+ load_delay_nop ();
if (breg != 0)
macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", AT, breg, AT);
AT, AT, mips_gp_register);
macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)",
AT, BFD_RELOC_MIPS_GOT_LO16, AT);
- macro_build (NULL, "nop", "");
+ load_delay_nop ();
if (breg != 0)
macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", AT, breg, AT);
/* Itbl support may require additional care here. */
macro_build (NULL, "nop", "");
macro_build (&offset_expr, ADDRESS_LOAD_INSN, "t,o(b)", AT,
BFD_RELOC_MIPS_GOT16, mips_gp_register);
- macro_build (NULL, "nop", "");
+ load_delay_nop ();
if (breg != 0)
macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", AT, breg, AT);
/* Itbl support may require additional care here. */
if (treg == tempreg)
return;
/* Protect second load's delay slot. */
- if (!gpr_interlocks)
- macro_build (NULL, "nop", "");
+ load_delay_nop ();
move_register (treg, tempreg);
break;
#define OPTION_MNO_7000_HILO_FIX (OPTION_FIX_BASE + 1)
{"no-fix-7000", no_argument, NULL, OPTION_MNO_7000_HILO_FIX},
{"mno-fix7000", no_argument, NULL, OPTION_MNO_7000_HILO_FIX},
-#define OPTION_FIX_VR4122 (OPTION_FIX_BASE + 2)
-#define OPTION_NO_FIX_VR4122 (OPTION_FIX_BASE + 3)
- {"mfix-vr4122-bugs", no_argument, NULL, OPTION_FIX_VR4122},
- {"no-mfix-vr4122-bugs", no_argument, NULL, OPTION_NO_FIX_VR4122},
+#define OPTION_FIX_VR4120 (OPTION_FIX_BASE + 2)
+#define OPTION_NO_FIX_VR4120 (OPTION_FIX_BASE + 3)
+ {"mfix-vr4120", no_argument, NULL, OPTION_FIX_VR4120},
+ {"mno-fix-vr4120", no_argument, NULL, OPTION_NO_FIX_VR4120},
/* Miscellaneous options. */
#define OPTION_MISC_BASE (OPTION_FIX_BASE + 4)
g_switch_value = 0x7fffffff;
break;
- case OPTION_FIX_VR4122:
- mips_fix_4122_bugs = 1;
+ case OPTION_FIX_VR4120:
+ mips_fix_vr4120 = 1;
break;
- case OPTION_NO_FIX_VR4122:
- mips_fix_4122_bugs = 0;
+ case OPTION_NO_FIX_VR4120:
+ mips_fix_vr4120 = 0;
break;
case OPTION_RELAX_BRANCH:
-mips16 generate mips16 instructions\n\
-no-mips16 do not generate mips16 instructions\n"));
fprintf (stream, _("\
+-mfix-vr4120 work around certain VR4120 errata\n\
-mgp32 use 32-bit GPRs, regardless of the chosen ISA\n\
-mfp32 use 32-bit FPRs, regardless of the chosen ISA\n\
-O0 remove unneeded NOPs, do not swap branches\n\
{
if (mips_abi == N64_ABI)
return 8;
- /* GCC for 64-bit targets turns on mlong64 giving
- us 64-bit addresses. */
- else if (mips_abi == EABI_ABI && !file_mips_gp32)
- return 8;
else
return 4;
}