/* tc-mips.c -- assemble code for a MIPS chip.
- Copyright (C) 1993, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1993, 94, 95, 96, 97, 98, 1999, 2000 Free Software Foundation, Inc.
Contributed by the OSF and Ralph Campbell.
Written by Keith Knowles and Ralph Campbell, working independently.
Modified for ECOFF and R4000 support by Ian Lance Taylor of Cygnus
return target_big_endian ? "a.out-mips-big" : "a.out-mips-little";
case bfd_target_ecoff_flavour:
return target_big_endian ? "ecoff-bigmips" : ECOFF_LITTLE_FORMAT;
+ case bfd_target_coff_flavour:
+ return "pe-mips";
case bfd_target_elf_flavour:
return (target_big_endian
? (mips_64 ? "elf64-bigmips" : "elf32-bigmips")
? ".data" \
: OUTPUT_FLAVOR == bfd_target_ecoff_flavour \
? ".rdata" \
+ : OUTPUT_FLAVOR == bfd_target_coff_flavour \
+ ? ".rdata" \
: OUTPUT_FLAVOR == bfd_target_elf_flavour \
? ".rodata" \
: (abort (), ""))
mips3 or greater, then mark the object file 32BITMODE. */
static int mips_32bitmode = 0;
+/* True if -mgp32 was passed. */
+static int mips_gp32 = 0;
+
+/* Some ISA's have delay slots for instructions which read or write
+ from a coprocessor (eg. mips1-mips3); some don't (eg mips4).
+ Return true if instructions marked INSN_LOAD_COPROC_DELAY,
+ INSN_COPROC_MOVE_DELAY, or INSN_WRITE_COND_CODE actually have a
+ delay slot in this ISA. The uses of this macro assume that any
+ ISA that has delay slots for one of these, has them for all. They
+ also assume that ISAs which don't have delays for these insns, don't
+ have delays for the INSN_LOAD_MEMORY_DELAY instructions either. */
+#define ISA_HAS_COPROC_DELAYS(ISA) ( \
+ (ISA) == 1 \
+ || (ISA) == 2 \
+ || (ISA) == 3 \
+ )
+
+/* Return true if ISA supports 64 bit gp register instructions. */
+#define ISA_HAS_64BIT_REGS(ISA) ( \
+ (ISA) == 3 \
+ || (ISA) == 4 \
+ )
+
/* Whether the processor uses hardware interlocks to protect
reads from the HI and LO registers, and thus does not
require nops to be inserted.
/* Whether the processor uses hardware interlocks to protect reads
from the GPRs, and thus does not require nops to be inserted. */
#define gpr_interlocks \
- (mips_opts.isa >= 2 \
+ (mips_opts.isa != 1 \
|| mips_cpu == 3900)
/* As with other "interlocks" this is used by hardware that has FP
#define cop_interlocks (mips_cpu == 4300 \
)
+/* Is this a mfhi or mflo instruction? */
+#define MF_HILO_INSN(PINFO) \
+ ((PINFO & INSN_READ_HI) || (PINFO & INSN_READ_LO))
+
/* MIPS PIC level. */
enum mips_pic_level
static int mips_any_noreorder;
+/* Non-zero if nops should be inserted when the register referenced in
+ an mfhi/mflo instruction is read in the next two instructions. */
+static int mips_7000_hilo_fix;
+
/* The size of the small data section. */
static int g_switch_value = 8;
/* Whether the -G option was used. */
better.
This function can only provide a guess, but it seems to work for
- gcc output. If it guesses wrong, the only loss should be in
- efficiency; it shouldn't introduce any bugs.
+ gcc output. It needs to guess right for gcc, otherwise gcc
+ will put what it thinks is a GP-relative instruction in a branch
+ delay slot.
I don't know if a fix is needed for the SVR4_PIC mode. I've only
fixed it for the non-PIC mode. KR 95/04/07 */
int broken = 0;
int mips_isa_from_cpu;
+ /* GP relative stuff not working for PE */
+ if (strncmp (TARGET_OS, "pe", 2) == 0
+ && g_switch_value != 0)
+ {
+ if (g_switch_seen)
+ as_bad (_("-G not supported in this configuration."));
+ g_switch_value = 0;
+ }
+
cpu = TARGET_CPU;
if (strcmp (cpu + (sizeof TARGET_CPU) - 3, "el") == 0)
{
if (strcmp (cpu, "mips") == 0)
{
- if (mips_opts.isa < 0)
- mips_cpu = 3000;
+ if (mips_opts.isa < 0)
+ mips_cpu = 3000;
- else if (mips_opts.isa == 2)
+ else if (mips_opts.isa == 2)
mips_cpu = 6000;
else if (mips_opts.isa == 3)
a = NULL;
}
- if (mips_opts.isa < 2 && mips_trap)
+ if (mips_opts.isa == 1 && mips_trap)
as_bad (_("trap exception not supported at ISA 1"));
/* Set the EABI kind based on the ISA before the user gets
to change the ISA with directives. This isn't really
the best, but then neither is basing the abi on the isa. */
- if (mips_opts.isa > 2
+ if (ISA_HAS_64BIT_REGS (mips_opts.isa)
&& mips_abi_string
&& 0 == strcmp (mips_abi_string,"eabi"))
mips_eabi64 = 1;
if (mips_cpu != 0 && mips_cpu != -1)
{
ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, mips_cpu);
-
+
/* If they asked for mips1 or mips2 and a cpu that is
mips3 or greater, then mark the object file 32BITMODE. */
if (mips_isa_from_cpu != -1
- && mips_opts.isa <= 2 && mips_isa_from_cpu > 2)
+ && ! ISA_HAS_64BIT_REGS (mips_opts.isa)
+ && ISA_HAS_64BIT_REGS (mips_isa_from_cpu))
mips_32bitmode = 1;
}
else
prev_pinfo = prev_insn.insn_mo->pinfo;
if (! mips_opts.noreorder
- && mips_opts.isa < 4
+ && ISA_HAS_COPROC_DELAYS (mips_opts.isa)
&& ((prev_pinfo & INSN_LOAD_COPROC_DELAY)
|| (! gpr_interlocks
&& (prev_pinfo & INSN_LOAD_MEMORY_DELAY))))
/* The previous insn might require a delay slot, depending upon
the contents of the current insn. */
if (! mips_opts.mips16
- && mips_opts.isa < 4
+ && ISA_HAS_COPROC_DELAYS (mips_opts.isa)
&& (((prev_pinfo & INSN_LOAD_COPROC_DELAY)
&& ! cop_interlocks)
|| (! gpr_interlocks
++nops;
}
else if (! mips_opts.mips16
- && mips_opts.isa < 4
+ && ISA_HAS_COPROC_DELAYS (mips_opts.isa)
&& (((prev_pinfo & INSN_COPROC_MOVE_DELAY)
&& ! cop_interlocks)
- || (mips_opts.isa < 2
+ || (mips_opts.isa == 1
&& (prev_pinfo & INSN_COPROC_MEMORY_DELAY))))
{
/* A generic coprocessor delay. The previous instruction
}
}
else if (! mips_opts.mips16
- && mips_opts.isa < 4
+ && ISA_HAS_COPROC_DELAYS (mips_opts.isa)
&& (prev_pinfo & INSN_WRITE_COND_CODE)
&& ! cop_interlocks)
{
|| (pinfo & INSN_READ_COND_CODE))
++nops;
}
+
+ /* If we're fixing up mfhi/mflo for the r7000 and the
+ previous insn was an mfhi/mflo and the current insn
+ reads the register that the mfhi/mflo wrote to, then
+ insert two nops. */
+
+ else if (mips_7000_hilo_fix
+ && MF_HILO_INSN (prev_pinfo)
+ && insn_uses_reg (ip, ((prev_insn.insn_opcode >> OP_SH_RD)
+ & OP_MASK_RD),
+ MIPS_GR_REG))
+
+ {
+ nops += 2;
+ }
+
+ /* If we're fixing up mfhi/mflo for the r7000 and the
+ 2nd previous insn was an mfhi/mflo and the current insn
+ reads the register that the mfhi/mflo wrote to, then
+ insert one nop. */
+
+ else if (mips_7000_hilo_fix
+ && MF_HILO_INSN (prev_prev_insn.insn_opcode)
+ && insn_uses_reg (ip, ((prev_prev_insn.insn_opcode >> OP_SH_RD)
+ & OP_MASK_RD),
+ MIPS_GR_REG))
+
+ {
+ nops += 1;
+ }
+
else if (prev_pinfo & INSN_READ_LO)
{
/* The previous instruction reads the LO register; if the
instruction, we must check for these cases compared to the
instruction previous to the previous instruction. */
if ((! mips_opts.mips16
- && mips_opts.isa < 4
+ && ISA_HAS_COPROC_DELAYS (mips_opts.isa)
&& (prev_prev_insn.insn_mo->pinfo & INSN_COPROC_MOVE_DELAY)
&& (prev_prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE)
&& (pinfo & INSN_READ_COND_CODE)
we can not swap, and I don't feel like handling that
case. */
|| (! mips_opts.mips16
- && mips_opts.isa < 4
+ && ISA_HAS_COPROC_DELAYS (mips_opts.isa)
&& (pinfo & INSN_READ_COND_CODE))
/* We can not swap with an instruction that requires a
delay slot, becase the target of the branch might
interfere with that instruction. */
|| (! mips_opts.mips16
- && mips_opts.isa < 4
+ && ISA_HAS_COPROC_DELAYS (mips_opts.isa)
&& (prev_pinfo
/* Itbl support may require additional care here. */
& (INSN_LOAD_COPROC_DELAY
&& ! gpr_interlocks
&& (prev_pinfo & INSN_LOAD_MEMORY_DELAY))
|| (! mips_opts.mips16
- && mips_opts.isa < 2
+ && mips_opts.isa == 1
/* Itbl support may require additional care here. */
&& (prev_pinfo & INSN_COPROC_MEMORY_DELAY))
/* We can not swap with a branch instruction. */
delay, and sets a register that the branch reads, we
can not swap. */
|| (! mips_opts.mips16
- && mips_opts.isa < 4
+ && ISA_HAS_COPROC_DELAYS (mips_opts.isa)
/* Itbl support may require additional care here. */
&& ((prev_prev_insn.insn_mo->pinfo & INSN_LOAD_COPROC_DELAY)
|| (! gpr_interlocks
nops = 0;
if ((! mips_opts.mips16
- && mips_opts.isa < 4
+ && ISA_HAS_COPROC_DELAYS (mips_opts.isa)
&& (! cop_interlocks
&& (prev_insn.insn_mo->pinfo
& (INSN_LOAD_COPROC_DELAY
&& (prev_insn.insn_mo->pinfo
& INSN_LOAD_MEMORY_DELAY))
|| (! mips_opts.mips16
- && mips_opts.isa < 2
+ && mips_opts.isa == 1
&& (prev_insn.insn_mo->pinfo
& INSN_COPROC_MEMORY_DELAY)))
{
/* Itbl support may require additional care here. */
++nops;
if ((! mips_opts.mips16
- && mips_opts.isa < 4
+ && ISA_HAS_COPROC_DELAYS (mips_opts.isa)
&& (! cop_interlocks
&& prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE))
|| (! hilo_interlocks
nops = 0;
}
else if ((! mips_opts.mips16
- && mips_opts.isa < 4
+ && ISA_HAS_COPROC_DELAYS (mips_opts.isa)
&& (! cop_interlocks
&& prev_prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE))
|| (! hilo_interlocks
struct mips_cl_insn insn;
bfd_reloc_code_real_type r;
va_list args;
- int insn_isa;
#ifdef USE_STDARG
va_start (args, fmt);
/* Search until we get a match for NAME. */
while (1)
{
- if ((insn.insn_mo->membership & INSN_ISA) == INSN_ISA1)
- insn_isa = 1;
- else if ((insn.insn_mo->membership & INSN_ISA) == INSN_ISA2)
- insn_isa = 2;
- else if ((insn.insn_mo->membership & INSN_ISA) == INSN_ISA3)
- insn_isa = 3;
- else if ((insn.insn_mo->membership & INSN_ISA) == INSN_ISA4)
- insn_isa = 4;
- else
- insn_isa = 15;
-
if (strcmp (fmt, insn.insn_mo->args) == 0
&& insn.insn_mo->pinfo != INSN_MACRO
- && (insn_isa <= mips_opts.isa
- || (mips_cpu == 4650
- && (insn.insn_mo->membership & INSN_4650) != 0)
- || (mips_cpu == 4010
- && (insn.insn_mo->membership & INSN_4010) != 0)
- || ((mips_cpu == 4100
- || mips_cpu == 4111
- )
- && (insn.insn_mo->membership & INSN_4100) != 0)
- || (mips_cpu == 3900
- && (insn.insn_mo->membership & INSN_3900) != 0))
+ && OPCODE_IS_MEMBER (insn.insn_mo, mips_opts.isa, mips_cpu,
+ mips_gp32)
&& (mips_cpu != 4650 || (insn.insn_mo->pinfo & FP_D) == 0))
break;
|| r == BFD_RELOC_MIPS_GOT_LO16
|| r == BFD_RELOC_MIPS_CALL_LO16
|| (ep->X_op == O_subtract
- && now_seg == text_section
&& r == BFD_RELOC_PCREL_LO16));
continue;
|| r == BFD_RELOC_MIPS_GOT_HI16
|| r == BFD_RELOC_MIPS_CALL_HI16))
|| (ep->X_op == O_subtract
- && now_seg == text_section
&& r == BFD_RELOC_PCREL_HI16_S)));
if (ep->X_op == O_constant)
{
|| ! ep->X_unsigned
|| sizeof (ep->X_add_number) > 4
|| (ep->X_add_number & 0x80000000) == 0))
- || ((mips_opts.isa < 3 || ! dbl)
+ || ((! ISA_HAS_64BIT_REGS (mips_opts.isa) || ! dbl)
&& (ep->X_add_number &~ (offsetT) 0xffffffff) == 0)
- || (mips_opts.isa < 3
+ || (! ISA_HAS_64BIT_REGS (mips_opts.isa)
&& ! dbl
&& ((ep->X_add_number &~ (offsetT) 0xffffffff)
== ~ (offsetT) 0xffffffff)))
/* The value is larger than 32 bits. */
- if (mips_opts.isa < 3)
+ if (! ISA_HAS_64BIT_REGS (mips_opts.isa))
{
as_bad (_("Number larger than 32 bits"));
macro_build ((char *) NULL, counter, ep, "addiu", "t,r,j", reg, 0,
frag_grow (20);
macro_build ((char *) NULL, counter, ep,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addiu" : "daddiu"),
"t,r,j", reg, GP, (int) BFD_RELOC_MIPS_GPREL);
p = frag_var (rs_machine_dependent, 8, 0,
p += 4;
macro_build (p, counter, ep,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addiu" : "daddiu"),
"t,r,j", reg, reg, (int) BFD_RELOC_LO16);
}
frag_grow (20);
macro_build ((char *) NULL, counter, ep,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "lw" : "ld"),
"t,o(b)", reg, (int) BFD_RELOC_MIPS_GOT16, GP);
macro_build ((char *) NULL, counter, (expressionS *) NULL, "nop", "");
ep->X_add_symbol, (offsetT) 0, (char *) NULL);
macro_build (p, counter, ep,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addiu" : "daddiu"),
"t,r,j", reg, reg, (int) BFD_RELOC_LO16);
if (ex.X_add_number != 0)
ex.X_op = O_constant;
macro_build ((char *) NULL, counter, &ex,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addiu" : "daddiu"),
"t,r,j", reg, reg, (int) BFD_RELOC_LO16);
}
(int) BFD_RELOC_MIPS_GOT_HI16);
macro_build ((char *) NULL, counter, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", reg, reg, GP);
macro_build ((char *) NULL, counter, ep,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "lw" : "ld"),
"t,o(b)", reg, (int) BFD_RELOC_MIPS_GOT_LO16, reg);
p = frag_var (rs_machine_dependent, 12 + off, 0,
}
macro_build (p, counter, ep,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "lw" : "ld"),
"t,o(b)", reg, (int) BFD_RELOC_MIPS_GOT16, GP);
p += 4;
p += 4;
macro_build (p, counter, ep,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addiu" : "daddiu"),
"t,r,j", reg, reg, (int) BFD_RELOC_LO16);
if (ex.X_add_number != 0)
ex.X_op = O_constant;
macro_build ((char *) NULL, counter, &ex,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addiu" : "daddiu"),
"t,r,j", reg, reg, (int) BFD_RELOC_LO16);
}
*/
macro_build ((char *) NULL, counter, ep,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addiu" : "daddiu"),
"t,r,j", reg, GP, (int) BFD_RELOC_MIPS_GPREL);
}
case M_BGT_I:
/* check for > max integer */
maxnum = 0x7fffffff;
- if (mips_opts.isa >= 3 && sizeof (maxnum) > 4)
+ if (ISA_HAS_64BIT_REGS (mips_opts.isa) && sizeof (maxnum) > 4)
{
maxnum <<= 16;
maxnum |= 0xffff;
}
if (imm_expr.X_op == O_constant
&& imm_expr.X_add_number >= maxnum
- && (mips_opts.isa < 3 || sizeof (maxnum) > 4))
+ && (! ISA_HAS_64BIT_REGS (mips_opts.isa) || sizeof (maxnum) > 4))
{
do_false:
/* result is always false */
return;
}
maxnum = 0x7fffffff;
- if (mips_opts.isa >= 3 && sizeof (maxnum) > 4)
+ if (ISA_HAS_64BIT_REGS (mips_opts.isa) && sizeof (maxnum) > 4)
{
maxnum <<= 16;
maxnum |= 0xffff;
maxnum = - maxnum - 1;
if (imm_expr.X_op == O_constant
&& imm_expr.X_add_number <= maxnum
- && (mips_opts.isa < 3 || sizeof (maxnum) > 4))
+ && (! ISA_HAS_64BIT_REGS (mips_opts.isa) || sizeof (maxnum) > 4))
{
do_true:
/* result is always true */
likely = 1;
case M_BGTU_I:
if (sreg == 0
- || (mips_opts.isa < 3
+ || (! ISA_HAS_64BIT_REGS (mips_opts.isa)
&& imm_expr.X_op == O_constant
&& imm_expr.X_add_number == 0xffffffff))
goto do_false;
likely = 1;
case M_BLE_I:
maxnum = 0x7fffffff;
- if (mips_opts.isa >= 3 && sizeof (maxnum) > 4)
+ if (ISA_HAS_64BIT_REGS (mips_opts.isa) && sizeof (maxnum) > 4)
{
maxnum <<= 16;
maxnum |= 0xffff;
}
if (imm_expr.X_op == O_constant
&& imm_expr.X_add_number >= maxnum
- && (mips_opts.isa < 3 || sizeof (maxnum) > 4))
+ && (! ISA_HAS_64BIT_REGS (mips_opts.isa) || sizeof (maxnum) > 4))
goto do_true;
if (imm_expr.X_op != O_constant)
as_bad (_("Unsupported large constant"));
likely = 1;
case M_BLEU_I:
if (sreg == 0
- || (mips_opts.isa < 3
+ || (! ISA_HAS_64BIT_REGS (mips_opts.isa)
&& imm_expr.X_op == O_constant
&& imm_expr.X_add_number == 0xffffffff))
goto do_true;
/* When generating embedded PIC code, we permit expressions of
the form
la $4,foo-bar
- where bar is an address in the .text section. These are used
+ where bar is an address in the current section. These are used
when getting the addresses of functions. We don't permit
X_add_number to be non-zero, because if the symbol is
external the relaxing code needs to know that any addend is
purely the offset to X_op_symbol. */
if (mips_pic == EMBEDDED_PIC
&& offset_expr.X_op == O_subtract
- && now_seg == text_section
&& (symbol_constant_p (offset_expr.X_op_symbol)
- ? S_GET_SEGMENT (offset_expr.X_op_symbol) == text_section
+ ? S_GET_SEGMENT (offset_expr.X_op_symbol) == now_seg
: (symbol_equated_p (offset_expr.X_op_symbol)
&& (S_GET_SEGMENT
(symbol_get_value_expression (offset_expr.X_op_symbol)
->X_add_symbol)
- == text_section)))
+ == now_seg)))
&& breg == 0
- && offset_expr.X_add_number == 0)
+ && (offset_expr.X_add_number == 0
+ || OUTPUT_FLAVOR == bfd_target_elf_flavour))
{
macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",
treg, (int) BFD_RELOC_PCREL_HI16_S);
macro_build ((char *) NULL, &icnt, &offset_expr,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addiu" : "daddiu"),
"t,r,j", treg, treg, (int) BFD_RELOC_PCREL_LO16);
return;
frag_grow (20);
macro_build ((char *) NULL, &icnt, &offset_expr,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addiu" : "daddiu"),
"t,r,j", tempreg, GP, (int) BFD_RELOC_MIPS_GPREL);
p = frag_var (rs_machine_dependent, 8, 0,
p += 4;
macro_build (p, &icnt, &offset_expr,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addiu" : "daddiu"),
"t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
}
}
macro_build (p, &icnt, &expr1,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addiu" : "daddiu"),
"t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
/* FIXME: If breg == 0, and the next instruction uses
"nop", "");
macro_build ((char *) NULL, &icnt, &expr1,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addiu" : "daddiu"),
"t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
(void) frag_var (rs_machine_dependent, 0, 0,
"nop", "");
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", treg, AT, breg);
breg = 0;
macro_build ((char *) NULL, &icnt, &expr1,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addiu" : "daddiu"),
"t,r,j", AT, AT, (int) BFD_RELOC_LO16);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", tempreg, tempreg, AT);
(void) frag_var (rs_machine_dependent, 0, 0,
tempreg, (int) BFD_RELOC_MIPS_GOT_HI16);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", tempreg, tempreg, GP);
macro_build ((char *) NULL, &icnt, &offset_expr,
"nop", "");
macro_build ((char *) NULL, &icnt, &expr1,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addiu" : "daddiu"),
"t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
"nop", "");
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", treg, AT, breg);
dreg = treg;
macro_build ((char *) NULL, &icnt, &expr1,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addiu" : "daddiu"),
"t,r,j", AT, AT, (int) BFD_RELOC_LO16);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", dreg, dreg, AT);
p += 4;
macro_build (p, &icnt, &expr1,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addiu" : "daddiu"),
"t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
/* FIXME: If add_number is 0, and there was no base
p += 4;
macro_build (p, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", treg, AT, breg);
p += 4;
p += 4;
macro_build (p, &icnt, &expr1,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addiu" : "daddiu"),
"t,r,j", AT, AT, (int) BFD_RELOC_LO16);
p += 4;
macro_build (p, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", tempreg, tempreg, AT);
p += 4;
*/
macro_build ((char *) NULL, &icnt, &offset_expr,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addiu" : "daddiu"),
"t,r,j", tempreg, GP, (int) BFD_RELOC_MIPS_GPREL);
}
if (breg != 0)
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", treg, tempreg, breg);
expr1.X_add_number = mips_cprestore_offset;
macro_build ((char *) NULL, &icnt, &expr1,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "lw" : "ld"),
"t,o(b)", GP, (int) BFD_RELOC_LO16, mips_frame_reg);
}
{
macro_build ((char *) NULL, &icnt, &offset_expr,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "lw" : "ld"),
"t,o(b)", PIC_CALL_REG,
(int) BFD_RELOC_MIPS_CALL16, GP);
PIC_CALL_REG, (int) BFD_RELOC_MIPS_CALL_HI16);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", PIC_CALL_REG, PIC_CALL_REG, GP);
macro_build ((char *) NULL, &icnt, &offset_expr,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "lw" : "ld"),
"t,o(b)", PIC_CALL_REG,
(int) BFD_RELOC_MIPS_CALL_LO16, PIC_CALL_REG);
}
macro_build (p, &icnt, &offset_expr,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "lw" : "ld"),
"t,o(b)", PIC_CALL_REG,
(int) BFD_RELOC_MIPS_GOT16, GP);
}
macro_build (p, &icnt, &offset_expr,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addiu" : "daddiu"),
"t,r,j", PIC_CALL_REG, PIC_CALL_REG,
(int) BFD_RELOC_LO16);
expr1.X_add_number = mips_cprestore_offset;
macro_build ((char *) NULL, &icnt, &expr1,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "lw" : "ld"),
"t,o(b)", GP, (int) BFD_RELOC_LO16,
mips_frame_reg);
frag_grow (28);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", tempreg, breg, GP);
macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,
p += 4;
macro_build (p, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", tempreg, tempreg, breg);
if (p != NULL)
frag_grow (20);
macro_build ((char *) NULL, &icnt, &offset_expr,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "lw" : "ld"),
"t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT16, GP);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "nop", "");
(char *) NULL);
macro_build (p, &icnt, &offset_expr,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addiu" : "daddiu"),
"t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
if (breg != 0)
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", tempreg, tempreg, breg);
macro_build ((char *) NULL, &icnt, &expr1, s, fmt, treg,
tempreg, (int) BFD_RELOC_MIPS_GOT_HI16);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", tempreg, tempreg, GP);
macro_build ((char *) NULL, &icnt, &offset_expr,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "lw" : "ld"),
"t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT_LO16,
tempreg);
}
macro_build (p, &icnt, &offset_expr,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "lw" : "ld"),
"t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT16, GP);
p += 4;
p += 4;
macro_build (p, &icnt, &offset_expr,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addiu" : "daddiu"),
"t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
if (breg != 0)
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", tempreg, tempreg, breg);
macro_build ((char *) NULL, &icnt, &expr1, s, fmt, treg,
{
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", tempreg, breg, GP);
macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,
or in offset_expr. */
if (imm_expr.X_op == O_constant || imm_expr.X_op == O_big)
{
- if (mips_opts.isa >= 3)
+ if (ISA_HAS_64BIT_REGS (mips_opts.isa))
load_register (&icnt, treg, &imm_expr, 1);
else
{
{
macro_build ((char *) NULL, &icnt, &offset_expr,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "lw" : "ld"),
"t,o(b)", AT, (int) BFD_RELOC_MIPS_GOT16, GP);
}
a single instruction. */
macro_build ((char *) NULL, &icnt, &offset_expr,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addiu" : "daddiu"),
"t,r,j", AT, GP, (int) BFD_RELOC_MIPS_GPREL);
offset_expr.X_op = O_constant;
abort ();
/* Now we load the register(s). */
- if (mips_opts.isa >= 3)
+ if (ISA_HAS_64BIT_REGS (mips_opts.isa))
macro_build ((char *) NULL, &icnt, &offset_expr, "ld", "t,o(b)",
treg, (int) BFD_RELOC_LO16, AT);
else
or in offset_expr. */
if (imm_expr.X_op == O_constant || imm_expr.X_op == O_big)
{
- load_register (&icnt, AT, &imm_expr, mips_opts.isa >= 3);
- if (mips_opts.isa >= 3)
+ load_register (&icnt, AT, &imm_expr, ISA_HAS_64BIT_REGS (mips_opts.isa));
+ if (ISA_HAS_64BIT_REGS (mips_opts.isa))
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
"dmtc1", "t,S", AT, treg);
else
s = segment_name (S_GET_SEGMENT (offset_expr.X_add_symbol));
if (strcmp (s, ".lit8") == 0)
{
- if (mips_opts.isa >= 2)
+ if (mips_opts.isa != 1)
{
macro_build ((char *) NULL, &icnt, &offset_expr, "ldc1",
"T,o(b)", treg, (int) BFD_RELOC_MIPS_LITERAL, GP);
if (mips_pic == SVR4_PIC)
macro_build ((char *) NULL, &icnt, &offset_expr,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "lw" : "ld"),
"t,o(b)", AT, (int) BFD_RELOC_MIPS_GOT16, GP);
else
macro_build_lui ((char *) NULL, &icnt, &offset_expr, AT);
}
- if (mips_opts.isa >= 2)
+ if (mips_opts.isa != 1)
{
macro_build ((char *) NULL, &icnt, &offset_expr, "ldc1",
"T,o(b)", treg, (int) BFD_RELOC_LO16, AT);
to adjust when loading from memory. */
r = BFD_RELOC_LO16;
dob:
- assert (mips_opts.isa < 2);
+ assert (mips_opts.isa == 1);
macro_build ((char *) NULL, &icnt, &offset_expr, "lwc1", "T,o(b)",
target_big_endian ? treg + 1 : treg,
(int) r, breg);
}
/* Itbl support may require additional care here. */
coproc = 1;
- if (mips_opts.isa >= 2)
+ if (mips_opts.isa != 1)
{
s = "ldc1";
goto ld;
return;
}
- if (mips_opts.isa >= 2)
+ if (mips_opts.isa != 1)
{
s = "sdc1";
goto st;
goto ldd_std;
case M_LD_AB:
- if (mips_opts.isa >= 3)
+ if (ISA_HAS_64BIT_REGS (mips_opts.isa))
{
s = "ld";
goto ld;
goto ldd_std;
case M_SD_AB:
- if (mips_opts.isa >= 3)
+ if (ISA_HAS_64BIT_REGS (mips_opts.isa))
{
s = "sd";
goto st;
frag_grow (36);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", AT, breg, GP);
tempreg = AT;
{
macro_build (p, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", AT, breg, AT);
if (p != NULL)
frag_grow (24 + off);
macro_build ((char *) NULL, &icnt, &offset_expr,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "lw" : "ld"),
"t,o(b)", AT, (int) BFD_RELOC_MIPS_GOT16, GP);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "nop", "");
if (breg != 0)
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", AT, breg, AT);
/* Itbl support may require additional care here. */
AT, (int) BFD_RELOC_MIPS_GOT_HI16);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", AT, AT, GP);
macro_build ((char *) NULL, &icnt, &offset_expr,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "lw" : "ld"),
"t,o(b)", AT, (int) BFD_RELOC_MIPS_GOT_LO16, AT);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "nop", "");
if (breg != 0)
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", AT, breg, AT);
/* Itbl support may require additional care here. */
}
macro_build (p, &icnt, &offset_expr,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "lw" : "ld"),
"t,o(b)", AT, (int) BFD_RELOC_MIPS_GOT16, GP);
p += 4;
{
macro_build (p, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", AT, breg, AT);
p += 4;
{
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", AT, breg, GP);
tempreg = AT;
case M_SD_OB:
s = "sw";
sd_ob:
- assert (bfd_arch_bits_per_address (stdoutput) == 32 || mips_opts.isa < 3);
+ assert (bfd_arch_bits_per_address (stdoutput) == 32
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa));
macro_build ((char *) NULL, &icnt, &offset_expr, s, "t,o(b)", treg,
(int) BFD_RELOC_LO16, breg);
offset_expr.X_add_number += 4;
as_bad (_("opcode not supported on this processor"));
return;
}
- assert (mips_opts.isa < 2);
+ assert (mips_opts.isa == 1);
/* Even on a big endian machine $fn comes before $fn+1. We have
to adjust when storing to memory. */
macro_build ((char *) NULL, &icnt, &offset_expr, "swc1", "T,o(b)",
imm_expr.X_add_number = -imm_expr.X_add_number;
macro_build ((char *) NULL, &icnt, &imm_expr,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addiu" : "daddiu"),
"t,r,j", dreg, sreg,
(int) BFD_RELOC_LO16);
ip->insn_mo->name);
macro_build ((char *) NULL, &icnt, &expr1,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addiu" : "daddiu"),
"t,r,j", dreg, 0, (int) BFD_RELOC_LO16);
return;
imm_expr.X_add_number = -imm_expr.X_add_number;
macro_build ((char *) NULL, &icnt, &imm_expr,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addiu" : "daddiu"),
"t,r,j", dreg, sreg, (int) BFD_RELOC_LO16);
used_at = 0;
case M_TRUNCWD:
case M_TRUNCWS:
- assert (mips_opts.isa < 2);
+ assert (mips_opts.isa == 1);
sreg = (ip->insn_opcode >> 11) & 0x1f; /* floating reg */
dreg = (ip->insn_opcode >> 06) & 0x1f; /* floating reg */
if (breg != 0)
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", AT, AT, breg);
if (! target_big_endian)
if (breg != 0)
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", AT, AT, breg);
if (target_big_endian)
if (breg != 0)
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", AT, AT, breg);
if (! target_big_endian)
if (breg != 0)
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", AT, AT, breg);
if (! target_big_endian)
argsStart = s;
for (;;)
{
- int insn_isa;
boolean ok;
assert (strcmp (insn->name, str) == 0);
- if ((insn->membership & INSN_ISA) == INSN_ISA1)
- insn_isa = 1;
- else if ((insn->membership & INSN_ISA) == INSN_ISA2)
- insn_isa = 2;
- else if ((insn->membership & INSN_ISA) == INSN_ISA3)
- insn_isa = 3;
- else if ((insn->membership & INSN_ISA) == INSN_ISA4)
- insn_isa = 4;
- else
- insn_isa = 15;
-
- if (insn_isa <= mips_opts.isa)
+ if (OPCODE_IS_MEMBER (insn, mips_opts.isa, mips_cpu, mips_gp32))
ok = true;
- else if (insn->pinfo == INSN_MACRO)
- ok = false;
- else if ((mips_cpu == 4650 && (insn->membership & INSN_4650) != 0)
- || (mips_cpu == 4010 && (insn->membership & INSN_4010) != 0)
- || ((mips_cpu == 4100
- || mips_cpu == 4111
- )
- && (insn->membership & INSN_4100) != 0)
- || (mips_cpu == 3900 && (insn->membership & INSN_3900) != 0))
- ok = true;
- else
+ else
ok = false;
-
+
if (insn->pinfo != INSN_MACRO)
{
if (mips_cpu == 4650 && (insn->pinfo & FP_D) != 0)
++insn;
continue;
}
- if (insn_isa == 15
- || insn_isa <= mips_opts.isa)
- insn_error = _("opcode not supported on this processor");
else
{
static char buf[100];
-
- sprintf (buf, _("opcode requires -mips%d or greater"), insn_isa);
+ sprintf (buf,
+ _("opcode not supported on this processor: %d (MIPS%d)"),
+ mips_cpu, mips_opts.isa);
+
insn_error = buf;
+ return;
}
- return;
}
ip->insn_mo = insn;
as_bad (_("Invalid float register number (%d)"), regno);
if ((regno & 1) != 0
- && mips_opts.isa < 3
+ && ! ISA_HAS_64BIT_REGS (mips_opts.isa)
&& ! (strcmp (str, "mtc1") == 0
|| strcmp (str, "mfc1") == 0
|| strcmp (str, "lwc1") == 0
offset_expr to the low order 32 bits.
Otherwise, set imm_expr to the entire 64 bit
constant. */
- if (mips_opts.isa < 3)
+ if (! ISA_HAS_64BIT_REGS (mips_opts.isa))
{
imm_expr.X_op = O_constant;
offset_expr.X_op = O_constant;
default: /* unused default case avoids warnings. */
case 'L':
newname = RDATA_SECTION_NAME;
- if (USE_GLOBAL_POINTER_OPT && g_switch_value >= 8)
+ if ((USE_GLOBAL_POINTER_OPT && g_switch_value >= 8)
+ || mips_pic == EMBEDDED_PIC)
newname = ".lit8";
break;
case 'F':
- newname = RDATA_SECTION_NAME;
+ if (mips_pic == EMBEDDED_PIC)
+ newname = ".lit8";
+ else
+ newname = RDATA_SECTION_NAME;
break;
case 'l':
assert (!USE_GLOBAL_POINTER_OPT
&& imm_expr.X_op == O_constant)
|| (more
&& imm_expr.X_add_number < 0
- && mips_opts.isa >= 3
+ && ISA_HAS_64BIT_REGS (mips_opts.isa)
&& imm_expr.X_unsigned
&& sizeof (imm_expr.X_add_number) <= 4))
{
|| offset_expr.X_add_number < -0x8000)
&& (mips_pic != EMBEDDED_PIC
|| offset_expr.X_op != O_subtract
- || now_seg != text_section
|| (S_GET_SEGMENT (offset_expr.X_op_symbol)
- != text_section)))
+ != now_seg)))
break;
if (c == 'h' || c == 'H')
#define OPTION_MABI (OPTION_MD_BASE + 38)
{"mabi", required_argument, NULL, OPTION_MABI},
+#define OPTION_M7000_HILO_FIX (OPTION_MD_BASE + 39)
+ {"mfix7000", no_argument, NULL, OPTION_M7000_HILO_FIX},
+#define OPTION_NO_M7000_HILO_FIX (OPTION_MD_BASE + 40)
+ {"no-fix-7000", no_argument, NULL, OPTION_NO_M7000_HILO_FIX},
+
#define OPTION_CALL_SHARED (OPTION_MD_BASE + 7)
#define OPTION_NON_SHARED (OPTION_MD_BASE + 8)
#define OPTION_XGOT (OPTION_MD_BASE + 19)
{"64", no_argument, NULL, OPTION_64},
#endif
+#define OPTION_GP32 (OPTION_MD_BASE + 41)
+#define OPTION_GP64 (OPTION_MD_BASE + 42)
+ {"mgp32", no_argument, NULL, OPTION_GP32},
+ {"mgp64", no_argument, NULL, OPTION_GP64},
+
{NULL, no_argument, NULL, 0}
};
size_t md_longopts_size = sizeof(md_longopts);
}
break;
+ case OPTION_GP32:
+ mips_gp32 = 1;
+ mips_64 = 0;
+
+ /* We deliberately don't allow "-gp32" to set the MIPS_32BITMODE
+ flag in object files because to do so would make it
+ impossible to link with libraries compiled without "-gp32".
+ This is unnecessarily restrictive.
+
+ We could solve this problem by adding "-gp32" multilibs to
+ gcc, but to set this flag before gcc is built with such
+ multilibs will break too many systems. */
+
+/* mips_32bitmode = 1; */
+ break;
+
+ case OPTION_GP64:
+ mips_gp32 = 0;
+ mips_64 = 1;
+/* mips_32bitmode = 0; */
+ break;
case OPTION_MABI:
if (strcmp (arg,"32") == 0
mips_abi_string = arg;
break;
+ case OPTION_M7000_HILO_FIX:
+ mips_7000_hilo_fix = true;
+ break;
+
+ case OPTION_NO_M7000_HILO_FIX:
+ mips_7000_hilo_fix = false;
+ break;
+
default:
return 0;
}
fixup requires the special reloc. */
#define SWITCH_TABLE(fixp) \
((fixp)->fx_r_type == BFD_RELOC_32 \
+ && OUTPUT_FLAVOR != bfd_target_elf_flavour \
&& (fixp)->fx_addsy != NULL \
&& (fixp)->fx_subsy != NULL \
&& S_GET_SEGMENT ((fixp)->fx_addsy) == text_section \
symbol, we need to adjust the value. */
#ifdef OBJ_ELF
if (fixP->fx_addsy != NULL && OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ {
if (S_GET_OTHER (fixP->fx_addsy) == STO_MIPS16
|| S_IS_WEAK (fixP->fx_addsy)
|| (symbol_used_in_reloc_p (fixP->fx_addsy)
&& (((bfd_get_section_flags (stdoutput,
- S_GET_SEGMENT (fixP->fx_addsy))
- & SEC_LINK_ONCE) != 0)
- || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
- ".gnu.linkonce",
- sizeof (".gnu.linkonce") - 1))))
+ S_GET_SEGMENT (fixP->fx_addsy))
+ & SEC_LINK_ONCE) != 0)
+ || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
+ ".gnu.linkonce",
+ sizeof (".gnu.linkonce") - 1))))
{
value -= S_GET_VALUE (fixP->fx_addsy);
{
/* In this case, the bfd_install_relocation routine will
incorrectly add the symbol value back in. We just want
- the addend to appear in the object file. */
+ the addend to appear in the object file.
+ FIXME: If this makes VALUE zero, we're toast. */
value -= S_GET_VALUE (fixP->fx_addsy);
}
}
-#endif
+ /* This code was generated using trial and error and so is
+ fragile and not trustworthy. If you change it, you should
+ rerun the elf-rel, elf-rel2, and empic testcases and ensure
+ they still pass. */
+ if (fixP->fx_pcrel || fixP->fx_subsy != NULL)
+ {
+ value += fixP->fx_frag->fr_address + fixP->fx_where;
+
+ /* BFD's REL handling, for MIPS, is _very_ weird.
+ This gives the right results, but it can't possibly
+ be the way things are supposed to work. */
+ if (fixP->fx_r_type != BFD_RELOC_16_PCREL_S2
+ || S_GET_SEGMENT (fixP->fx_addsy) != undefined_section)
+ value += fixP->fx_frag->fr_address + fixP->fx_where;
+ }
+ }
+#endif
fixP->fx_addnumber = value; /* Remember value for tc_gen_reloc */
case BFD_RELOC_PCREL_HI16_S:
/* The addend for this is tricky if it is internal, so we just
do everything here rather than in bfd_install_relocation. */
- if ((symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_SECTION_SYM) == 0)
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour
+ && !fixP->fx_done
+ && value != 0)
+ break;
+ if (fixP->fx_addsy
+ && (symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_SECTION_SYM) == 0)
{
/* For an external symbol adjust by the address to make it
pcrel_offset. We use the address of the RELLO reloc
case BFD_RELOC_PCREL_LO16:
/* The addend for this is tricky if it is internal, so we just
do everything here rather than in bfd_install_relocation. */
- if ((symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_SECTION_SYM) == 0)
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour
+ && !fixP->fx_done
+ && value != 0)
+ break;
+ if (fixP->fx_addsy
+ && (symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_SECTION_SYM) == 0)
value += fixP->fx_frag->fr_address + fixP->fx_where;
buf = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
if (target_big_endian)
}
break;
+ case BFD_RELOC_RVA:
case BFD_RELOC_32:
/* If we are deleting this reloc entry, we must fill in the
value now. This can happen if we have a .word which is not
if ((value & 0x3) != 0)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("Branch to odd address (%lx)"), value);
+
+ if (!fixP->fx_done && value != 0)
+ break;
+ /* If 'value' is zero, the remaining reloc code won't actually
+ do the store, so it must be done here. This is probably
+ a bug somewhere. */
+ if (!fixP->fx_done)
+ value -= fixP->fx_frag->fr_address + fixP->fx_where;
+
value >>= 2;
/* update old instruction data */
| SEC_RELOC
| SEC_DATA));
if (strcmp (TARGET_OS, "elf") != 0)
- bfd_set_section_alignment (stdoutput, seg, 4);
+ record_alignment (seg, 4);
}
demand_empty_rest_of_line ();
}
SEC_ALLOC | SEC_LOAD | SEC_RELOC
| SEC_DATA);
if (strcmp (TARGET_OS, "elf") != 0)
- bfd_set_section_alignment (stdoutput, seg, 4);
+ record_alignment (seg, 4);
}
demand_empty_rest_of_line ();
break;
macro_build ((char *) NULL, &icnt, &ex,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "sw" : "sd"),
"t,o(b)", GP, (int) BFD_RELOC_LO16, SP);
reg = tc_get_register (0);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
((bfd_arch_bits_per_address (stdoutput) == 32
- || mips_opts.isa < 3)
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
? "addu" : "daddu"),
"d,v,t", reg, reg, GP);
assert (strcmp (segname, ".lit8") != 0
&& strcmp (segname, ".lit4") != 0);
change = (strcmp (segname, ".sdata") != 0
- && strcmp (segname, ".sbss") != 0);
+ && strcmp (segname, ".sbss") != 0
+ && strncmp (segname, ".sdata.", 7) != 0
+ && strncmp (segname, ".gnu.linkonce.s.", 16) != 0);
}
return change;
}
/* This must duplicate the test in adjust_reloc_syms. */
change = (symsec != &bfd_und_section
&& symsec != &bfd_abs_section
- && ! bfd_is_com_section (symsec));
+ && ! bfd_is_com_section (symsec)
+#ifdef OBJ_ELF
+ /* A weak symbol is treated as external. */
+ && ! S_IS_WEAK (sym)
+#endif
+ );
}
else
abort ();
as_fatal (_("Double check fx_r_type in tc-mips.c:tc_gen_reloc"));
fixp->fx_r_type = BFD_RELOC_GPREL32;
}
+ else if (fixp->fx_pcrel == 0 || OUTPUT_FLAVOR == bfd_target_elf_flavour)
+ reloc->addend = fixp->fx_addnumber;
else if (fixp->fx_r_type == BFD_RELOC_PCREL_LO16)
{
/* We use a special addend for an internal RELLO reloc. */
+ fixp->fx_next->fx_frag->fr_address
+ fixp->fx_next->fx_where);
}
- else if (fixp->fx_pcrel == 0)
- reloc->addend = fixp->fx_addnumber;
else
{
if (OUTPUT_FLAVOR != bfd_target_aout_flavour)
/* To support a PC relative reloc when generating embedded PIC code
for ECOFF, we use a Cygnus extension. We check for that here to
make sure that we don't let such a reloc escape normally. */
- if (OUTPUT_FLAVOR == bfd_target_ecoff_flavour
+ if ((OUTPUT_FLAVOR == bfd_target_ecoff_flavour
+ || OUTPUT_FLAVOR == bfd_target_elf_flavour)
&& code == BFD_RELOC_16_PCREL_S2
&& mips_pic != EMBEDDED_PIC)
reloc->howto = NULL;
static procS *cur_proc_ptr;
static int numprocs;
+/* When we align code in the .text section of mips16, use the correct two
+ byte nop pattern of 0x6500 (move $0,$0) */
+
+int
+mips_do_align (n, fill, len, max)
+ int n;
+ const char *fill;
+ int len;
+ int max;
+{
+ if (fill == NULL
+ && subseg_text_p (now_seg)
+ && n > 1
+ && mips_opts.mips16)
+ {
+ static const unsigned char be_nop[] = { 0x65, 0x00 };
+ static const unsigned char le_nop[] = { 0x00, 0x65 };
+
+ frag_align (1, 0, 0);
+
+ if (target_big_endian)
+ frag_align_pattern (n, be_nop, 2, max);
+ else
+ frag_align_pattern (n, le_nop, 2, max);
+ return 1;
+ }
+
+ return 0;
+}
+
static void
md_obj_begin ()
{
symbolP->sy_segment = now_seg;
}
#endif
-
-
-