/* MIPS ISA we are using for this output file. */
static int file_mips_isa = ISA_UNKNOWN;
-/* The CPU type we are using for this output file. */
+/* The argument of the -mcpu= flag. Historical for code generation. */
static int mips_cpu = CPU_UNKNOWN;
+/* The argument of the -march= flag. The architecture we are assembling. */
+static int mips_arch = CPU_UNKNOWN;
+
+/* The argument of the -mtune= flag. The architecture for which we
+ are optimizing. */
+static int mips_tune = CPU_UNKNOWN;
+
/* The argument of the -mabi= flag. */
-static char * mips_abi_string = 0;
+static char * mips_abi_string = NULL;
-/* Wether we should mark the file EABI64 or EABI32. */
+/* Whether we should mark the file EABI64 or EABI32. */
static int mips_eabi64 = 0;
/* If they asked for mips1 or mips2 and a cpu that is
/* True if -mgp32 was passed. */
static int mips_gp32 = 0;
+/* True if -mfp32 was passed. */
+static int mips_fp32 = 0;
+
+/* True if the selected ABI is defined for 32-bit registers only. */
+static int mips_32bit_abi = 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,
|| (ISA) == ISA_MIPS64 \
)
-/* Whether the processor uses hardware interlocks to protect
- reads from the HI and LO registers, and thus does not
- require nops to be inserted.
-
- FIXME: GCC makes a distinction between -mcpu=FOO and -mFOO:
- -mcpu=FOO schedules for FOO, but still produces code that meets the
- requirements of MIPS ISA I. For example, it won't generate any
- FOO-specific instructions, and it will still assume that any
- scheduling hazards described in MIPS ISA I are there, even if FOO
- has interlocks. -mFOO gives GCC permission to generate code that
- will only run on a FOO; it will generate FOO-specific instructions,
- and assume interlocks provided by a FOO.
+#define HAVE_32BIT_GPRS \
+ (mips_gp32 \
+ || mips_32bit_abi \
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- However, GAS currently doesn't make this distinction; before Jan 28
- 1999, GAS's -mcpu=FOO implied -mFOO, which violates GCC's
- assumptions. The GCC driver passes these flags through to GAS, so
- if GAS actually does anything that doesn't meet MIPS ISA I with
- -mFOO, then GCC's -mcpu=FOO flag isn't going to work.
+#define HAVE_32BIT_FPRS \
+ (mips_fp32 \
+ || mips_32bit_abi \
+ || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- And furthermore, it did not assume that -mFOO implied -mcpu=FOO,
- which seems senseless --- why generate code which will only run on
- a FOO, but schedule for something else?
+#define HAVE_64BIT_GPRS (! HAVE_32BIT_GPRS)
+#define HAVE_64BIT_FPRS (! HAVE_32BIT_FPRS)
- So now, at least, -mcpu=FOO and -mFOO are exactly equivalent.
+#define HAVE_32BIT_ADDRESSES \
+ (HAVE_32BIT_GPRS \
+ || bfd_arch_bits_per_address (stdoutput) == 32)
- -- Jim Blandy <jimb@cygnus.com> */
+/* Whether the processor uses hardware interlocks to protect
+ reads from the HI and LO registers, and thus does not
+ require nops to be inserted. */
-#define hilo_interlocks (mips_cpu == CPU_R4010 \
+#define hilo_interlocks (mips_arch == CPU_R4010 \
)
/* 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 != ISA_MIPS1 \
- || mips_cpu == CPU_R3900)
+ || mips_arch == CPU_R3900)
/* As with other "interlocks" this is used by hardware that has FP
(co-processor) interlocks. */
/* Itbl support may require additional care here. */
-#define cop_interlocks (mips_cpu == CPU_R4300 \
+#define cop_interlocks (mips_arch == CPU_R4300 \
)
/* Is this a mfhi or mflo instruction? */
static enum mips_pic_level mips_pic;
+/* Warn about all NOPS that the assembler generates. */
+static int warn_nops = 0;
+
/* 1 if we should generate 32 bit offsets from the GP register in
SVR4_PIC mode. Currently has no meaning in other modes. */
static int mips_big_got;
| ((warn) ? 1 : 0)))
#define RELAX_OLD(i) (((i) >> 23) & 0x7f)
#define RELAX_NEW(i) (((i) >> 16) & 0x7f)
-#define RELAX_RELOC1(i) ((bfd_vma) (((i) >> 9) & 0x7f) - 64)
-#define RELAX_RELOC2(i) ((bfd_vma) (((i) >> 2) & 0x7f) - 64)
+#define RELAX_RELOC1(i) ((valueT) (((i) >> 9) & 0x7f) - 64)
+#define RELAX_RELOC2(i) ((valueT) (((i) >> 2) & 0x7f) - 64)
#define RELAX_RELOC3(i) (((i) >> 1) & 1)
#define RELAX_WARN(i) ((i) & 1)
expressionS *));
static void load_register PARAMS ((int *, int, expressionS *, int));
static void load_address PARAMS ((int *counter, int reg, expressionS *ep));
+static void move_register PARAMS ((int *, int, int));
static void macro PARAMS ((struct mips_cl_insn * ip));
static void mips16_macro PARAMS ((struct mips_cl_insn * ip));
#ifdef LOSING_COMPILER
static const char *mips_isa_to_str PARAMS ((int));
static const char *mips_cpu_to_str PARAMS ((int));
static int validate_mips_insn PARAMS ((const struct mips_opcode *));
+static void show PARAMS ((FILE *, char *, int *, int *));
+
+/* Return values of my_getSmallExpression() */
+
+enum
+{
+ S_EX_NONE = 0,
+ S_EX_LO,
+ S_EX_HI,
+ S_EX_HIGHER,
+ S_EX_HIGHEST,
+ S_EX_GPREL,
+ S_EX_NEG
+};
/* Table and functions used to map between CPU/ISA names, and
ISA levels, and CPU numbers. */
if (mips_opts.mips16 < 0)
mips_opts.mips16 = target_cpu_had_mips16;
- /* At this point, mips_cpu will either be CPU_UNKNOWN if no CPU was
+ /* Backward compatibility for historic -mcpu= option. Check for
+ incompatible options, warn if -mcpu is used. */
+ if (mips_cpu != CPU_UNKNOWN
+ && mips_arch != CPU_UNKNOWN
+ && mips_cpu != mips_arch)
+ {
+ as_fatal (_("The -mcpu option can't be used together with -march. "
+ "Use -mtune instead of -mcpu."));
+ }
+
+ if (mips_cpu != CPU_UNKNOWN
+ && mips_tune != CPU_UNKNOWN
+ && mips_cpu != mips_tune)
+ {
+ as_fatal (_("The -mcpu option can't be used together with -mtune. "
+ "Use -march instead of -mcpu."));
+ }
+
+ if (mips_arch == CPU_UNKNOWN && mips_cpu != CPU_UNKNOWN)
+ {
+ ci = mips_cpu_info_from_cpu (mips_cpu);
+ assert (ci != NULL);
+ mips_arch = ci->cpu;
+ as_warn (_("The -mcpu option is deprecated. Please use -march and "
+ "-mtune instead."));
+ }
+
+ /* At this point, mips_arch will either be CPU_UNKNOWN if no ARCH was
specified on the command line, or some other value if one was.
Similarly, mips_opts.isa will be ISA_UNKNOWN if not specified on
the command line, or will be set otherwise if one was. */
- if (mips_cpu != CPU_UNKNOWN && mips_opts.isa != ISA_UNKNOWN)
+ if (mips_arch != CPU_UNKNOWN && mips_opts.isa != ISA_UNKNOWN)
{
- /* We have it all. There's nothing to do. */
+ /* We have to check if the isa is the default isa of arch. Otherwise
+ we'll get invalid object file headers. */
+ ci = mips_cpu_info_from_cpu (mips_arch);
+ assert (ci != NULL);
+ if (mips_opts.isa != ci->isa)
+ {
+ /* This really should be an error instead of a warning, but old
+ compilers only have -mcpu which sets both arch and tune. For
+ now, we discard arch and preserve tune. */
+ as_warn (_("The -march option is incompatible to -mipsN and "
+ "therefore ignored."));
+ if (mips_tune == CPU_UNKNOWN)
+ mips_tune = mips_arch;
+ ci = mips_cpu_info_from_isa (mips_opts.isa);
+ assert (ci != NULL);
+ mips_arch = ci->cpu;
+ }
}
- else if (mips_cpu != CPU_UNKNOWN && mips_opts.isa == ISA_UNKNOWN)
+ else if (mips_arch != CPU_UNKNOWN && mips_opts.isa == ISA_UNKNOWN)
{
- /* We have CPU, we need ISA. */
- ci = mips_cpu_info_from_cpu (mips_cpu);
+ /* We have ARCH, we need ISA. */
+ ci = mips_cpu_info_from_cpu (mips_arch);
assert (ci != NULL);
mips_opts.isa = ci->isa;
}
- else if (mips_cpu == CPU_UNKNOWN && mips_opts.isa != ISA_UNKNOWN)
+ else if (mips_arch == CPU_UNKNOWN && mips_opts.isa != ISA_UNKNOWN)
{
- /* We have ISA, we need default CPU. */
+ /* We have ISA, we need default ARCH. */
ci = mips_cpu_info_from_isa (mips_opts.isa);
assert (ci != NULL);
- mips_cpu = ci->cpu;
+ mips_arch = ci->cpu;
}
else
{
- /* We need to set both ISA and CPU from target cpu. */
+ /* We need to set both ISA and ARCH from target cpu. */
ci = mips_cpu_info_from_name (cpu);
if (ci == NULL)
ci = mips_cpu_info_from_cpu (CPU_R3000);
assert (ci != NULL);
mips_opts.isa = ci->isa;
- mips_cpu = ci->cpu;
+ mips_arch = ci->cpu;
}
- ci = mips_cpu_info_from_cpu (mips_cpu);
+ if (mips_tune == CPU_UNKNOWN)
+ mips_tune = mips_arch;
+
+ ci = mips_cpu_info_from_cpu (mips_arch);
assert (ci != NULL);
mips_isa_from_cpu = ci->isa;
&& ISA_HAS_64BIT_REGS (mips_isa_from_cpu))
mips_32bitmode = 1;
- if (! bfd_set_arch_mach (stdoutput, bfd_arch_mips, mips_cpu))
+ if (! bfd_set_arch_mach (stdoutput, bfd_arch_mips, mips_arch))
as_warn (_("Could not set architecture and machine"));
file_mips_isa = mips_opts.isa;
though the tx39's divide insns still do require the
delay. */
if (! (hilo_interlocks
- || (mips_cpu == CPU_R3900 && (pinfo & INSN_MULT)))
+ || (mips_tune == CPU_R3900 && (pinfo & INSN_MULT)))
&& (mips_optimize == 0
|| (pinfo & INSN_WRITE_LO)))
nops += 2;
insert a NOP. Some newer processors have interlocks.
Also the note tx39's multiply above. */
if (! (hilo_interlocks
- || (mips_cpu == CPU_R3900 && (pinfo & INSN_MULT)))
+ || (mips_tune == CPU_R3900 && (pinfo & INSN_MULT)))
&& (mips_optimize == 0
|| (pinfo & INSN_WRITE_HI)))
nops += 2;
|| ((prev_prev_insn.insn_mo->pinfo & INSN_READ_LO)
&& (pinfo & INSN_WRITE_LO)
&& ! (hilo_interlocks
- || (mips_cpu == CPU_R3900 && (pinfo & INSN_MULT))))
+ || (mips_tune == CPU_R3900 && (pinfo & INSN_MULT))))
|| ((prev_prev_insn.insn_mo->pinfo & INSN_READ_HI)
&& (pinfo & INSN_WRITE_HI)
&& ! (hilo_interlocks
- || (mips_cpu == CPU_R3900 && (pinfo & INSN_MULT)))))
+ || (mips_tune == CPU_R3900 && (pinfo & INSN_MULT)))))
prev_prev_nop = 1;
else
prev_prev_nop = 0;
| INSN_COPROC_MOVE_DELAY
| INSN_WRITE_COND_CODE)))
|| (! (hilo_interlocks
- || (mips_cpu == CPU_R3900 && (pinfo & INSN_MULT)))
+ || (mips_tune == CPU_R3900 && (pinfo & INSN_MULT)))
&& (prev_pinfo
& (INSN_READ_LO
| INSN_READ_HI)))
{
if (strcmp (fmt, insn.insn_mo->args) == 0
&& insn.insn_mo->pinfo != INSN_MACRO
- && OPCODE_IS_MEMBER (insn.insn_mo, mips_opts.isa, mips_cpu,
- mips_gp32)
- && (mips_cpu != CPU_R4650 || (insn.insn_mo->pinfo & FP_D) == 0))
+ && OPCODE_IS_MEMBER (insn.insn_mo, mips_opts.isa, mips_arch)
+ && (mips_arch != CPU_R4650 || (insn.insn_mo->pinfo & FP_D) == 0))
break;
++insn.insn_mo;
case 't':
case 'w':
case 'E':
- insn.insn_opcode |= va_arg (args, int) << 16;
+ insn.insn_opcode |= va_arg (args, int) << OP_SH_RT;
continue;
case 'c':
+ insn.insn_opcode |= va_arg (args, int) << OP_SH_CODE;
+ continue;
+
case 'T':
case 'W':
- insn.insn_opcode |= va_arg (args, int) << 16;
+ insn.insn_opcode |= va_arg (args, int) << OP_SH_FT;
continue;
case 'd':
case 'G':
- insn.insn_opcode |= va_arg (args, int) << 11;
+ insn.insn_opcode |= va_arg (args, int) << OP_SH_RD;
continue;
case 'U':
{
int tmp = va_arg (args, int);
- insn.insn_opcode |= tmp << 16;
- insn.insn_opcode |= tmp << 11;
+ insn.insn_opcode |= tmp << OP_SH_RT;
+ insn.insn_opcode |= tmp << OP_SH_RD;
continue;
}
case 'V':
case 'S':
- insn.insn_opcode |= va_arg (args, int) << 11;
+ insn.insn_opcode |= va_arg (args, int) << OP_SH_FS;
continue;
case 'z':
continue;
case '<':
- insn.insn_opcode |= va_arg (args, int) << 6;
+ insn.insn_opcode |= va_arg (args, int) << OP_SH_SHAMT;
continue;
case 'D':
- insn.insn_opcode |= va_arg (args, int) << 6;
+ insn.insn_opcode |= va_arg (args, int) << OP_SH_FD;
continue;
case 'B':
- insn.insn_opcode |= va_arg (args, int) << 6;
+ insn.insn_opcode |= va_arg (args, int) << OP_SH_CODE20;
continue;
case 'J':
- insn.insn_opcode |= va_arg (args, int) << 6;
+ insn.insn_opcode |= va_arg (args, int) << OP_SH_CODE19;
continue;
case 'q':
- insn.insn_opcode |= va_arg (args, int) << 6;
+ insn.insn_opcode |= va_arg (args, int) << OP_SH_CODE2;
continue;
case 'b':
case 's':
case 'r':
case 'v':
- insn.insn_opcode |= va_arg (args, int) << 21;
+ insn.insn_opcode |= va_arg (args, int) << OP_SH_RS;
continue;
case 'i':
if (high_expr.X_op == O_constant)
{
/* we can compute the instruction now without a relocation entry */
- if (high_expr.X_add_number & 0x8000)
- high_expr.X_add_number += 0x10000;
- high_expr.X_add_number =
- ((unsigned long) high_expr.X_add_number >> 16) & 0xffff;
+ high_expr.X_add_number = ((high_expr.X_add_number + 0x8000)
+ >> 16) & 0xffff;
r = BFD_RELOC_UNUSED;
}
else
|| ! ep->X_unsigned
|| sizeof (ep->X_add_number) > 4
|| (ep->X_add_number & 0x80000000) == 0))
- || ((! ISA_HAS_64BIT_REGS (mips_opts.isa) || ! dbl)
+ || ((HAVE_32BIT_GPRS || ! dbl)
&& (ep->X_add_number &~ (offsetT) 0xffffffff) == 0)
- || (! ISA_HAS_64BIT_REGS (mips_opts.isa)
+ || (HAVE_32BIT_GPRS
&& ! dbl
&& ((ep->X_add_number &~ (offsetT) 0xffffffff)
== ~ (offsetT) 0xffffffff)))
/* The value is larger than 32 bits. */
- if (! ISA_HAS_64BIT_REGS (mips_opts.isa))
+ if (HAVE_32BIT_GPRS)
{
as_bad (_("Number larger than 32 bits"));
macro_build ((char *) NULL, counter, ep, "addiu", "t,r,j", reg, 0,
lui $reg,<sym> (BFD_RELOC_HI16_S)
addiu $reg,$reg,<sym> (BFD_RELOC_LO16)
If we have an addend, we always use the latter form. */
- if ((valueT) ep->X_add_number >= MAX_GPREL_OFFSET
+ if ((valueT) ep->X_add_number > MAX_GPREL_OFFSET
|| nopic_need_relax (ep->X_add_symbol, 1))
p = NULL;
else
{
frag_grow (20);
macro_build ((char *) NULL, counter, ep,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addiu" : "daddiu"),
+ HAVE_32BIT_ADDRESSES ? "addiu" : "daddiu",
"t,r,j", reg, GP, (int) BFD_RELOC_MIPS_GPREL);
p = frag_var (rs_machine_dependent, 8, 0,
RELAX_ENCODE (4, 8, 0, 4, 0,
if (p != NULL)
p += 4;
macro_build (p, counter, ep,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addiu" : "daddiu"),
+ HAVE_32BIT_ADDRESSES ? "addiu" : "daddiu",
"t,r,j", reg, reg, (int) BFD_RELOC_LO16);
}
else if (mips_pic == SVR4_PIC && ! mips_big_got)
ep->X_add_number = 0;
frag_grow (20);
macro_build ((char *) NULL, counter, ep,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "lw" : "ld"),
+ HAVE_32BIT_ADDRESSES ? "lw" : "ld",
"t,o(b)", reg, (int) BFD_RELOC_MIPS_GOT16, GP);
macro_build ((char *) NULL, counter, (expressionS *) NULL, "nop", "");
p = frag_var (rs_machine_dependent, 4, 0,
RELAX_ENCODE (0, 4, -8, 0, 0, mips_opts.warn_about_macros),
ep->X_add_symbol, (offsetT) 0, (char *) NULL);
macro_build (p, counter, ep,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addiu" : "daddiu"),
+ HAVE_32BIT_ADDRESSES ? "addiu" : "daddiu",
"t,r,j", reg, reg, (int) BFD_RELOC_LO16);
if (ex.X_add_number != 0)
{
as_bad (_("PIC code offset overflow (max 16 signed bits)"));
ex.X_op = O_constant;
macro_build ((char *) NULL, counter, &ex,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addiu" : "daddiu"),
+ HAVE_32BIT_ADDRESSES ? "addiu" : "daddiu",
"t,r,j", reg, reg, (int) BFD_RELOC_LO16);
}
}
macro_build ((char *) NULL, counter, ep, "lui", "t,u", reg,
(int) BFD_RELOC_MIPS_GOT_HI16);
macro_build ((char *) NULL, counter, (expressionS *) NULL,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", reg, reg, GP);
macro_build ((char *) NULL, counter, ep,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "lw" : "ld"),
+ HAVE_32BIT_ADDRESSES ? "lw" : "ld",
"t,o(b)", reg, (int) BFD_RELOC_MIPS_GOT_LO16, reg);
p = frag_var (rs_machine_dependent, 12 + off, 0,
RELAX_ENCODE (12, 12 + off, off, 8 + off, 0,
macro_build (p, counter, (expressionS *) NULL, "nop", "");
p += 4;
}
- macro_build (p, counter, ep,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "lw" : "ld"),
+ macro_build (p, counter, ep, HAVE_32BIT_ADDRESSES ? "lw" : "ld",
"t,o(b)", reg, (int) BFD_RELOC_MIPS_GOT16, GP);
p += 4;
macro_build (p, counter, (expressionS *) NULL, "nop", "");
p += 4;
- macro_build (p, counter, ep,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addiu" : "daddiu"),
+ macro_build (p, counter, ep, HAVE_32BIT_ADDRESSES ? "addiu" : "daddiu",
"t,r,j", reg, reg, (int) BFD_RELOC_LO16);
if (ex.X_add_number != 0)
{
as_bad (_("PIC code offset overflow (max 16 signed bits)"));
ex.X_op = O_constant;
macro_build ((char *) NULL, counter, &ex,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addiu" : "daddiu"),
+ HAVE_32BIT_ADDRESSES ? "addiu" : "daddiu",
"t,r,j", reg, reg, (int) BFD_RELOC_LO16);
}
}
addiu $reg,$gp,<sym> (BFD_RELOC_MIPS_GPREL)
*/
macro_build ((char *) NULL, counter, ep,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addiu" : "daddiu"),
+ HAVE_32BIT_ADDRESSES ? "addiu" : "daddiu",
"t,r,j", reg, GP, (int) BFD_RELOC_MIPS_GPREL);
}
else
abort ();
}
+/* Move the contents of register SOURCE into register DEST. */
+
+static void
+move_register (counter, dest, source)
+ int *counter;
+ int dest;
+ int source;
+{
+ macro_build ((char *) NULL, counter, (expressionS *) NULL,
+ HAVE_32BIT_GPRS ? "addu" : "daddu",
+ "d,v,t", dest, source, 0);
+}
+
/*
* Build macros
* This routine implements the seemingly endless macro or synthesized
if (dreg == sreg)
macro_build ((char *) NULL, &icnt, NULL, "nop", "", 0);
else
- macro_build ((char *) NULL, &icnt, NULL, "move", "d,s", dreg, sreg, 0);
+ move_register (&icnt, dreg, sreg);
macro_build ((char *) NULL, &icnt, NULL,
- dbl ? "dsub" : "sub",
- "d,v,t", dreg, 0, sreg);
+ dbl ? "dsub" : "sub", "d,v,t", dreg, 0, sreg);
--mips_opts.noreorder;
return;
}
macro_build ((char *) NULL, &icnt, NULL, "slt", "d,v,t", AT, sreg, treg);
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "beql" : "beq",
- "s,t,p", AT, 0);
+ likely ? "beql" : "beq", "s,t,p", AT, 0);
break;
case M_BGTL_I:
case M_BGT_I:
/* check for > max integer */
maxnum = 0x7fffffff;
- if (ISA_HAS_64BIT_REGS (mips_opts.isa) && sizeof (maxnum) > 4)
+ if (HAVE_64BIT_GPRS && sizeof (maxnum) > 4)
{
maxnum <<= 16;
maxnum |= 0xffff;
}
if (imm_expr.X_op == O_constant
&& imm_expr.X_add_number >= maxnum
- && (! ISA_HAS_64BIT_REGS (mips_opts.isa) || sizeof (maxnum) > 4))
+ && (HAVE_32BIT_GPRS || sizeof (maxnum) > 4))
{
do_false:
/* result is always false */
if (! likely)
{
- as_warn (_("Branch %s is always false (nop)"), ip->insn_mo->name);
+ if (warn_nops)
+ as_warn (_("Branch %s is always false (nop)"),
+ ip->insn_mo->name);
macro_build ((char *) NULL, &icnt, NULL, "nop", "", 0);
}
else
{
- as_warn (_("Branch likely %s is always false"), ip->insn_mo->name);
+ if (warn_nops)
+ as_warn (_("Branch likely %s is always false"),
+ ip->insn_mo->name);
macro_build ((char *) NULL, &icnt, &offset_expr, "bnel",
"s,t,p", 0, 0);
}
if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
{
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "bgezl" : "bgez",
- "s,p", sreg);
+ likely ? "bgezl" : "bgez", "s,p", sreg);
return;
}
if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
{
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "bgtzl" : "bgtz",
- "s,p", sreg);
+ likely ? "bgtzl" : "bgtz", "s,p", sreg);
return;
}
maxnum = 0x7fffffff;
- if (ISA_HAS_64BIT_REGS (mips_opts.isa) && sizeof (maxnum) > 4)
+ if (HAVE_64BIT_GPRS && sizeof (maxnum) > 4)
{
maxnum <<= 16;
maxnum |= 0xffff;
maxnum = - maxnum - 1;
if (imm_expr.X_op == O_constant
&& imm_expr.X_add_number <= maxnum
- && (! ISA_HAS_64BIT_REGS (mips_opts.isa) || sizeof (maxnum) > 4))
+ && (HAVE_32BIT_GPRS || sizeof (maxnum) > 4))
{
do_true:
/* result is always true */
}
set_at (&icnt, sreg, 0);
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "beql" : "beq",
- "s,t,p", AT, 0);
+ likely ? "beql" : "beq", "s,t,p", AT, 0);
break;
case M_BGEUL:
if (sreg == 0)
{
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "beql" : "beq",
- "s,t,p", 0, treg);
+ likely ? "beql" : "beq", "s,t,p", 0, treg);
return;
}
macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", AT, sreg,
treg);
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "beql" : "beq",
- "s,t,p", AT, 0);
+ likely ? "beql" : "beq", "s,t,p", AT, 0);
break;
case M_BGTUL_I:
likely = 1;
case M_BGTU_I:
if (sreg == 0
- || (! ISA_HAS_64BIT_REGS (mips_opts.isa)
+ || (HAVE_32BIT_GPRS
&& imm_expr.X_op == O_constant
&& imm_expr.X_add_number == 0xffffffff))
goto do_false;
if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
{
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "bnel" : "bne",
- "s,t,p", sreg, 0);
+ likely ? "bnel" : "bne", "s,t,p", sreg, 0);
return;
}
set_at (&icnt, sreg, 1);
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "beql" : "beq",
- "s,t,p", AT, 0);
+ likely ? "beql" : "beq", "s,t,p", AT, 0);
break;
case M_BGTL:
if (treg == 0)
{
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "bgtzl" : "bgtz",
- "s,p", sreg);
+ likely ? "bgtzl" : "bgtz", "s,p", sreg);
return;
}
if (sreg == 0)
{
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "bltzl" : "bltz",
- "s,p", treg);
+ likely ? "bltzl" : "bltz", "s,p", treg);
return;
}
macro_build ((char *) NULL, &icnt, NULL, "slt", "d,v,t", AT, treg, sreg);
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "bnel" : "bne",
- "s,t,p", AT, 0);
+ likely ? "bnel" : "bne", "s,t,p", AT, 0);
break;
case M_BGTUL:
if (treg == 0)
{
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "bnel" : "bne",
- "s,t,p", sreg, 0);
+ likely ? "bnel" : "bne", "s,t,p", sreg, 0);
return;
}
if (sreg == 0)
macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", AT, treg,
sreg);
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "bnel" : "bne",
- "s,t,p", AT, 0);
+ likely ? "bnel" : "bne", "s,t,p", AT, 0);
break;
case M_BLEL:
if (treg == 0)
{
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "blezl" : "blez",
- "s,p", sreg);
+ likely ? "blezl" : "blez", "s,p", sreg);
return;
}
if (sreg == 0)
{
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "bgezl" : "bgez",
- "s,p", treg);
+ likely ? "bgezl" : "bgez", "s,p", treg);
return;
}
macro_build ((char *) NULL, &icnt, NULL, "slt", "d,v,t", AT, treg, sreg);
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "beql" : "beq",
- "s,t,p", AT, 0);
+ likely ? "beql" : "beq", "s,t,p", AT, 0);
break;
case M_BLEL_I:
likely = 1;
case M_BLE_I:
maxnum = 0x7fffffff;
- if (ISA_HAS_64BIT_REGS (mips_opts.isa) && sizeof (maxnum) > 4)
+ if (HAVE_64BIT_GPRS && sizeof (maxnum) > 4)
{
maxnum <<= 16;
maxnum |= 0xffff;
}
if (imm_expr.X_op == O_constant
&& imm_expr.X_add_number >= maxnum
- && (! ISA_HAS_64BIT_REGS (mips_opts.isa) || sizeof (maxnum) > 4))
+ && (HAVE_32BIT_GPRS || sizeof (maxnum) > 4))
goto do_true;
if (imm_expr.X_op != O_constant)
as_bad (_("Unsupported large constant"));
if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
{
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "bltzl" : "bltz",
- "s,p", sreg);
+ likely ? "bltzl" : "bltz", "s,p", sreg);
return;
}
if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
{
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "blezl" : "blez",
- "s,p", sreg);
+ likely ? "blezl" : "blez", "s,p", sreg);
return;
}
set_at (&icnt, sreg, 0);
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "bnel" : "bne",
- "s,t,p", AT, 0);
+ likely ? "bnel" : "bne", "s,t,p", AT, 0);
break;
case M_BLEUL:
if (treg == 0)
{
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "beql" : "beq",
- "s,t,p", sreg, 0);
+ likely ? "beql" : "beq", "s,t,p", sreg, 0);
return;
}
if (sreg == 0)
macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", AT, treg,
sreg);
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "beql" : "beq",
- "s,t,p", AT, 0);
+ likely ? "beql" : "beq", "s,t,p", AT, 0);
break;
case M_BLEUL_I:
likely = 1;
case M_BLEU_I:
if (sreg == 0
- || (! ISA_HAS_64BIT_REGS (mips_opts.isa)
+ || (HAVE_32BIT_GPRS
&& imm_expr.X_op == O_constant
&& imm_expr.X_add_number == 0xffffffff))
goto do_true;
}
set_at (&icnt, sreg, 1);
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "bnel" : "bne",
- "s,t,p", AT, 0);
+ likely ? "bnel" : "bne", "s,t,p", AT, 0);
break;
case M_BLTL:
if (treg == 0)
{
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "bltzl" : "bltz",
- "s,p", sreg);
+ likely ? "bltzl" : "bltz", "s,p", sreg);
return;
}
if (sreg == 0)
{
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "bgtzl" : "bgtz",
- "s,p", treg);
+ likely ? "bgtzl" : "bgtz", "s,p", treg);
return;
}
macro_build ((char *) NULL, &icnt, NULL, "slt", "d,v,t", AT, sreg, treg);
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "bnel" : "bne",
- "s,t,p", AT, 0);
+ likely ? "bnel" : "bne", "s,t,p", AT, 0);
break;
case M_BLTUL:
if (sreg == 0)
{
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "bnel" : "bne",
- "s,t,p", 0, treg);
+ likely ? "bnel" : "bne", "s,t,p", 0, treg);
return;
}
macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", AT, sreg,
treg);
macro_build ((char *) NULL, &icnt, &offset_expr,
- likely ? "bnel" : "bne",
- "s,t,p", AT, 0);
+ likely ? "bnel" : "bne", "s,t,p", AT, 0);
break;
case M_DDIV_3:
{
macro_build ((char *) NULL, &icnt, NULL, "teq", "s,t", treg, 0);
macro_build ((char *) NULL, &icnt, NULL,
- dbl ? "ddiv" : "div",
- "z,s,t", sreg, treg);
+ dbl ? "ddiv" : "div", "z,s,t", sreg, treg);
}
else
{
expr1.X_add_number = 8;
macro_build ((char *) NULL, &icnt, &expr1, "bne", "s,t,p", treg, 0);
macro_build ((char *) NULL, &icnt, NULL,
- dbl ? "ddiv" : "div",
- "z,s,t", sreg, treg);
+ dbl ? "ddiv" : "div", "z,s,t", sreg, treg);
macro_build ((char *) NULL, &icnt, NULL, "break", "c", 7);
}
expr1.X_add_number = -1;
if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
{
if (strcmp (s2, "mflo") == 0)
- macro_build ((char *) NULL, &icnt, NULL, "move", "d,s", dreg,
- sreg);
+ move_register (&icnt, dreg, sreg);
else
- macro_build ((char *) NULL, &icnt, NULL, "move", "d,s", dreg, 0);
+ move_register (&icnt, dreg, 0);
return;
}
if (imm_expr.X_op == O_constant
{
if (strcmp (s2, "mflo") == 0)
{
- if (dbl)
- macro_build ((char *) NULL, &icnt, NULL, "dneg", "d,w", dreg,
- sreg);
- else
- macro_build ((char *) NULL, &icnt, NULL, "neg", "d,w", dreg,
- sreg);
+ macro_build ((char *) NULL, &icnt, NULL, dbl ? "dneg" : "neg",
+ "d,w", dreg, sreg);
}
else
- macro_build ((char *) NULL, &icnt, NULL, "move", "d,s", dreg, 0);
+ move_register (&icnt, dreg, 0);
return;
}
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
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addiu" : "daddiu"),
+ HAVE_32BIT_ADDRESSES ? "addiu" : "daddiu",
"t,r,j", treg, treg, (int) BFD_RELOC_PCREL_LO16);
return;
}
addiu $tempreg,$tempreg,<sym> (BFD_RELOC_LO16)
If we have a constant, we need two instructions anyhow,
so we may as well always use the latter form. */
- if ((valueT) offset_expr.X_add_number >= MAX_GPREL_OFFSET
+ if ((valueT) offset_expr.X_add_number > MAX_GPREL_OFFSET
|| nopic_need_relax (offset_expr.X_add_symbol, 1))
p = NULL;
else
{
frag_grow (20);
macro_build ((char *) NULL, &icnt, &offset_expr,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addiu" : "daddiu"),
+ HAVE_32BIT_ADDRESSES ? "addiu" : "daddiu",
"t,r,j", tempreg, GP, (int) BFD_RELOC_MIPS_GPREL);
p = frag_var (rs_machine_dependent, 8, 0,
RELAX_ENCODE (4, 8, 0, 4, 0,
if (p != NULL)
p += 4;
macro_build (p, &icnt, &offset_expr,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addiu" : "daddiu"),
+ HAVE_32BIT_ADDRESSES ? "addiu" : "daddiu",
"t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
}
else if (mips_pic == SVR4_PIC && ! mips_big_got)
p += 4;
}
macro_build (p, &icnt, &expr1,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addiu" : "daddiu"),
+ HAVE_32BIT_ADDRESSES ? "addiu" : "daddiu",
"t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
/* FIXME: If breg == 0, and the next instruction uses
$tempreg, then if this variant case is used an extra
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
"nop", "");
macro_build ((char *) NULL, &icnt, &expr1,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addiu" : "daddiu"),
+ HAVE_32BIT_ADDRESSES ? "addiu" : "daddiu",
"t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
(void) frag_var (rs_machine_dependent, 0, 0,
RELAX_ENCODE (0, 0, -12, -4, 0, 0),
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
"nop", "");
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", treg, AT, breg);
breg = 0;
tempreg = treg;
mips_optimize = hold_mips_optimize;
macro_build ((char *) NULL, &icnt, &expr1,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addiu" : "daddiu"),
+ HAVE_32BIT_ADDRESSES ? "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
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", tempreg, tempreg, AT);
(void) frag_var (rs_machine_dependent, 0, 0,
RELAX_ENCODE (0, 0, -16 + off1, -8, 0, 0),
macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",
tempreg, lui_reloc_type);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", tempreg, tempreg, GP);
macro_build ((char *) NULL, &icnt, &offset_expr,
dbl ? "ld" : "lw",
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
"nop", "");
macro_build ((char *) NULL, &icnt, &expr1,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addiu" : "daddiu"),
+ HAVE_32BIT_ADDRESSES ? "addiu" : "daddiu",
"t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
p = frag_var (rs_machine_dependent, 12 + gpdel, 0,
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
"nop", "");
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", treg, AT, breg);
dreg = treg;
adj = 8;
mips_optimize = hold_mips_optimize;
macro_build ((char *) NULL, &icnt, &expr1,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addiu" : "daddiu"),
+ HAVE_32BIT_ADDRESSES ? "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
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", dreg, dreg, AT);
p = frag_var (rs_machine_dependent, 16 + gpdel + adj, 0,
macro_build (p, &icnt, (expressionS *) NULL, "nop", "");
p += 4;
macro_build (p, &icnt, &expr1,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addiu" : "daddiu"),
+ HAVE_32BIT_ADDRESSES ? "addiu" : "daddiu",
"t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
/* FIXME: If add_number is 0, and there was no base
register, the external symbol case ended with a load,
macro_build (p, &icnt, (expressionS *) NULL, "nop", "");
p += 4;
macro_build (p, &icnt, (expressionS *) NULL,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", treg, AT, breg);
p += 4;
tempreg = treg;
macro_build_lui (p, &icnt, &expr1, AT);
p += 4;
macro_build (p, &icnt, &expr1,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addiu" : "daddiu"),
+ HAVE_32BIT_ADDRESSES ? "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
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", tempreg, tempreg, AT);
p += 4;
}
addiu $tempreg,$gp,<sym> (BFD_RELOC_MIPS_GPREL)
*/
macro_build ((char *) NULL, &icnt, &offset_expr,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addiu" : "daddiu"),
+ HAVE_32BIT_ADDRESSES ? "addiu" : "daddiu",
"t,r,j", tempreg, GP, (int) BFD_RELOC_MIPS_GPREL);
}
else
if (breg != 0)
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", treg, tempreg, breg);
if (! used_at)
{
expr1.X_add_number = mips_cprestore_offset;
macro_build ((char *) NULL, &icnt, &expr1,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "lw" : "ld"),
+ HAVE_32BIT_ADDRESSES ? "lw" : "ld",
"t,o(b)", GP, (int) BFD_RELOC_LO16, mips_frame_reg);
}
}
if (! mips_big_got)
{
macro_build ((char *) NULL, &icnt, &offset_expr,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "lw" : "ld"),
+ HAVE_32BIT_ADDRESSES ? "lw" : "ld",
"t,o(b)", PIC_CALL_REG,
(int) BFD_RELOC_MIPS_CALL16, GP);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",
PIC_CALL_REG, (int) BFD_RELOC_MIPS_CALL_HI16);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "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
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "lw" : "ld"),
+ HAVE_32BIT_ADDRESSES ? "lw" : "ld",
"t,o(b)", PIC_CALL_REG,
(int) BFD_RELOC_MIPS_CALL_LO16, PIC_CALL_REG);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
p += 4;
}
macro_build (p, &icnt, &offset_expr,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "lw" : "ld"),
+ HAVE_32BIT_ADDRESSES ? "lw" : "ld",
"t,o(b)", PIC_CALL_REG,
(int) BFD_RELOC_MIPS_GOT16, GP);
p += 4;
p += 4;
}
macro_build (p, &icnt, &offset_expr,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addiu" : "daddiu"),
+ HAVE_32BIT_ADDRESSES ? "addiu" : "daddiu",
"t,r,j", PIC_CALL_REG, PIC_CALL_REG,
(int) BFD_RELOC_LO16);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
"nop", "");
expr1.X_add_number = mips_cprestore_offset;
macro_build ((char *) NULL, &icnt, &expr1,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "lw" : "ld"),
+ HAVE_32BIT_ADDRESSES ? "lw" : "ld",
"t,o(b)", GP, (int) BFD_RELOC_LO16,
mips_frame_reg);
}
lr = 1;
goto ld;
case M_LDC1_AB:
- if (mips_cpu == CPU_R4650)
+ if (mips_arch == CPU_R4650)
{
as_bad (_("opcode not supported on this processor"));
return;
s = "scd";
goto st;
case M_SDC1_AB:
- if (mips_cpu == CPU_R4650)
+ if (mips_arch == CPU_R4650)
{
as_bad (_("opcode not supported on this processor"));
return;
With a constant we always use the latter case. */
if (breg == 0)
{
- if ((valueT) offset_expr.X_add_number >= MAX_GPREL_OFFSET
+ if ((valueT) offset_expr.X_add_number > MAX_GPREL_OFFSET
|| nopic_need_relax (offset_expr.X_add_symbol, 1))
p = NULL;
else
}
else
{
- if ((valueT) offset_expr.X_add_number >= MAX_GPREL_OFFSET
+ if ((valueT) offset_expr.X_add_number > MAX_GPREL_OFFSET
|| nopic_need_relax (offset_expr.X_add_symbol, 1))
p = NULL;
else
{
frag_grow (28);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", tempreg, breg, GP);
macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,
treg, (int) BFD_RELOC_MIPS_GPREL, tempreg);
if (p != NULL)
p += 4;
macro_build (p, &icnt, (expressionS *) NULL,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", tempreg, tempreg, breg);
if (p != NULL)
p += 4;
as_bad (_("PIC code offset overflow (max 16 signed bits)"));
frag_grow (20);
macro_build ((char *) NULL, &icnt, &offset_expr,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "lw" : "ld"),
+ HAVE_32BIT_ADDRESSES ? "lw" : "ld",
"t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT16, GP);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "nop", "");
p = frag_var (rs_machine_dependent, 4, 0,
offset_expr.X_add_symbol, (offsetT) 0,
(char *) NULL);
macro_build (p, &icnt, &offset_expr,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addiu" : "daddiu"),
+ HAVE_32BIT_ADDRESSES ? "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
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", tempreg, tempreg, breg);
macro_build ((char *) NULL, &icnt, &expr1, s, fmt, treg,
(int) BFD_RELOC_LO16, tempreg);
macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",
tempreg, (int) BFD_RELOC_MIPS_GOT_HI16);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", tempreg, tempreg, GP);
macro_build ((char *) NULL, &icnt, &offset_expr,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "lw" : "ld"),
+ HAVE_32BIT_ADDRESSES ? "lw" : "ld",
"t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT_LO16,
tempreg);
p = frag_var (rs_machine_dependent, 12 + gpdel, 0,
p += 4;
}
macro_build (p, &icnt, &offset_expr,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "lw" : "ld"),
+ HAVE_32BIT_ADDRESSES ? "lw" : "ld",
"t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT16, GP);
p += 4;
macro_build (p, &icnt, (expressionS *) NULL, "nop", "");
p += 4;
macro_build (p, &icnt, &offset_expr,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addiu" : "daddiu"),
+ HAVE_32BIT_ADDRESSES ? "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
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", tempreg, tempreg, breg);
macro_build ((char *) NULL, &icnt, &expr1, s, fmt, treg,
(int) BFD_RELOC_LO16, tempreg);
else
{
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", tempreg, breg, GP);
macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,
treg, (int) BFD_RELOC_MIPS_GPREL, tempreg);
}
case M_LI_D:
- /* If we have a constant in IMM_EXPR, then in mips3 mode it is
- the entire value, and in mips1 mode it is the high order 32
- bits of the value and the low order 32 bits are either zero
- or in offset_expr. */
+ /* Check if we have a constant in IMM_EXPR. If the GPRs are 64 bits
+ wide, IMM_EXPR is the entire value. Otherwise IMM_EXPR is the high
+ order 32 bits of the value and the low order 32 bits are either
+ zero or in OFFSET_EXPR. */
if (imm_expr.X_op == O_constant || imm_expr.X_op == O_big)
{
- if (ISA_HAS_64BIT_REGS (mips_opts.isa))
+ if (HAVE_64BIT_GPRS)
load_register (&icnt, treg, &imm_expr, 1);
else
{
if (lreg <= 31)
{
if (offset_expr.X_op == O_absent)
- macro_build ((char *) NULL, &icnt, NULL, "move", "d,s",
- lreg, 0);
+ move_register (&icnt, lreg, 0);
else
{
assert (offset_expr.X_op == O_constant);
else if (mips_pic == SVR4_PIC)
{
macro_build ((char *) NULL, &icnt, &offset_expr,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "lw" : "ld"),
+ HAVE_32BIT_ADDRESSES ? "lw" : "ld",
"t,o(b)", AT, (int) BFD_RELOC_MIPS_GOT16, GP);
}
else if (mips_pic == EMBEDDED_PIC)
/* For embedded PIC we pick up the entire address off $gp in
a single instruction. */
macro_build ((char *) NULL, &icnt, &offset_expr,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addiu" : "daddiu"),
+ HAVE_32BIT_ADDRESSES ? "addiu" : "daddiu",
"t,r,j", AT, GP, (int) BFD_RELOC_MIPS_GPREL);
offset_expr.X_op = O_constant;
offset_expr.X_add_number = 0;
abort ();
/* Now we load the register(s). */
- if (ISA_HAS_64BIT_REGS (mips_opts.isa))
+ if (HAVE_64BIT_GPRS)
macro_build ((char *) NULL, &icnt, &offset_expr, "ld", "t,o(b)",
treg, (int) BFD_RELOC_LO16, AT);
else
break;
case M_LI_DD:
- /* If we have a constant in IMM_EXPR, then in mips3 mode it is
- the entire value, and in mips1 mode it is the high order 32
- bits of the value and the low order 32 bits are either zero
- or in offset_expr. */
+ /* Check if we have a constant in IMM_EXPR. If the FPRs are 64 bits
+ wide, IMM_EXPR is the entire value and the GPRs are known to be 64
+ bits wide as well. Otherwise IMM_EXPR is the high order 32 bits of
+ the value and the low order 32 bits are either zero or in
+ OFFSET_EXPR. */
if (imm_expr.X_op == O_constant || imm_expr.X_op == O_big)
{
- 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);
+ load_register (&icnt, AT, &imm_expr, HAVE_64BIT_FPRS);
+ if (HAVE_64BIT_FPRS)
+ {
+ assert (HAVE_64BIT_GPRS);
+ macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
+ "dmtc1", "t,S", AT, treg);
+ }
else
{
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
assert (strcmp (s, RDATA_SECTION_NAME) == 0);
if (mips_pic == SVR4_PIC)
macro_build ((char *) NULL, &icnt, &offset_expr,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "lw" : "ld"),
+ HAVE_32BIT_ADDRESSES ? "lw" : "ld",
"t,o(b)", AT, (int) BFD_RELOC_MIPS_GOT16, GP);
else
{
}
case M_L_DOB:
- if (mips_cpu == CPU_R4650)
+ if (mips_arch == CPU_R4650)
{
as_bad (_("opcode not supported on this processor"));
return;
* But, the resulting address is the same after relocation so why
* generate the extra instruction?
*/
- if (mips_cpu == CPU_R4650)
+ if (mips_arch == CPU_R4650)
{
as_bad (_("opcode not supported on this processor"));
return;
goto ldd_std;
case M_S_DAB:
- if (mips_cpu == CPU_R4650)
+ if (mips_arch == CPU_R4650)
{
as_bad (_("opcode not supported on this processor"));
return;
goto ldd_std;
case M_LD_AB:
- if (ISA_HAS_64BIT_REGS (mips_opts.isa))
+ if (HAVE_64BIT_GPRS)
{
s = "ld";
goto ld;
goto ldd_std;
case M_SD_AB:
- if (ISA_HAS_64BIT_REGS (mips_opts.isa))
+ if (HAVE_64BIT_GPRS)
{
s = "sd";
goto st;
If there is a base register, we add it to $at after the
lui instruction. If there is a constant, we always use
the last case. */
- if ((valueT) offset_expr.X_add_number >= MAX_GPREL_OFFSET
+ if ((valueT) offset_expr.X_add_number > MAX_GPREL_OFFSET
|| nopic_need_relax (offset_expr.X_add_symbol, 1))
{
p = NULL;
{
frag_grow (36);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", AT, breg, GP);
tempreg = AT;
off = 4;
if (breg != 0)
{
macro_build (p, &icnt, (expressionS *) NULL,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", AT, breg, AT);
if (p != NULL)
p += 4;
off = 4;
frag_grow (24 + off);
macro_build ((char *) NULL, &icnt, &offset_expr,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "lw" : "ld"),
+ HAVE_32BIT_ADDRESSES ? "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
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", AT, breg, AT);
/* Itbl support may require additional care here. */
macro_build ((char *) NULL, &icnt, &expr1, s, fmt,
macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",
AT, (int) BFD_RELOC_MIPS_GOT_HI16);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", AT, AT, GP);
macro_build ((char *) NULL, &icnt, &offset_expr,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "lw" : "ld"),
+ HAVE_32BIT_ADDRESSES ? "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
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", AT, breg, AT);
/* Itbl support may require additional care here. */
macro_build ((char *) NULL, &icnt, &expr1, s, fmt,
p += 4;
}
macro_build (p, &icnt, &offset_expr,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "lw" : "ld"),
+ HAVE_32BIT_ADDRESSES ? "lw" : "ld",
"t,o(b)", AT, (int) BFD_RELOC_MIPS_GOT16, GP);
p += 4;
macro_build (p, &icnt, (expressionS *) NULL, "nop", "");
if (breg != 0)
{
macro_build (p, &icnt, (expressionS *) NULL,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", AT, breg, AT);
p += 4;
}
else
{
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", AT, breg, GP);
tempreg = AT;
used_at = 1;
case M_SD_OB:
s = "sw";
sd_ob:
- assert (bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa));
+ assert (HAVE_32BIT_ADDRESSES);
macro_build ((char *) NULL, &icnt, &offset_expr, s, "t,o(b)", treg,
(int) BFD_RELOC_LO16, breg);
offset_expr.X_add_number += 4;
ip->insn_opcode);
return;
+ case M_MOVE:
+ move_register (&icnt, dreg, sreg);
+ return;
+
#ifdef LOSING_COMPILER
default:
/* Try and see if this is a new itbl instruction.
anyway. */
load_register (&icnt, AT, &imm_expr, dbl);
macro_build ((char *) NULL, &icnt, NULL,
- dbl ? "dmult" : "mult",
- "s,t", sreg, AT);
+ dbl ? "dmult" : "mult", "s,t", sreg, AT);
macro_build ((char *) NULL, &icnt, NULL, "mflo", "d", dreg);
break;
if (imm)
load_register (&icnt, AT, &imm_expr, dbl);
macro_build ((char *) NULL, &icnt, NULL,
- dbl ? "dmult" : "mult",
- "s,t", sreg, imm ? AT : treg);
+ dbl ? "dmult" : "mult", "s,t", sreg, imm ? AT : treg);
macro_build ((char *) NULL, &icnt, NULL, "mflo", "d", dreg);
macro_build ((char *) NULL, &icnt, NULL,
- dbl ? "dsra32" : "sra",
- "d,w,<", dreg, dreg, 31);
+ dbl ? "dsra32" : "sra", "d,w,<", dreg, dreg, 31);
macro_build ((char *) NULL, &icnt, NULL, "mfhi", "d", AT);
if (mips_trap)
macro_build ((char *) NULL, &icnt, NULL, "tne", "s,t", dreg, AT);
break;
case M_S_DOB:
- if (mips_cpu == CPU_R4650)
+ if (mips_arch == CPU_R4650)
{
as_bad (_("opcode not supported on this processor"));
return;
{
as_warn (_("Instruction %s: result is always false"),
ip->insn_mo->name);
- macro_build ((char *) NULL, &icnt, NULL, "move", "d,s", dreg, 0);
+ move_register (&icnt, dreg, 0);
return;
}
if (imm_expr.X_op == O_constant
{
imm_expr.X_add_number = -imm_expr.X_add_number;
macro_build ((char *) NULL, &icnt, &imm_expr,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addiu" : "daddiu"),
+ HAVE_32BIT_GPRS ? "addiu" : "daddiu",
"t,r,j", dreg, sreg,
(int) BFD_RELOC_LO16);
used_at = 0;
as_warn (_("Instruction %s: result is always true"),
ip->insn_mo->name);
macro_build ((char *) NULL, &icnt, &expr1,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addiu" : "daddiu"),
+ HAVE_32BIT_GPRS ? "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
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addiu" : "daddiu"),
+ HAVE_32BIT_GPRS ? "addiu" : "daddiu",
"t,r,j", dreg, sreg, (int) BFD_RELOC_LO16);
used_at = 0;
}
}
load_register (&icnt, AT, &imm_expr, dbl);
macro_build ((char *) NULL, &icnt, NULL,
- dbl ? "dsub" : "sub",
- "d,v,t", dreg, sreg, AT);
+ dbl ? "dsub" : "sub", "d,v,t", dreg, sreg, AT);
break;
case M_DSUBU_I:
}
load_register (&icnt, AT, &imm_expr, dbl);
macro_build ((char *) NULL, &icnt, NULL,
- dbl ? "dsubu" : "subu",
- "d,v,t", dreg, sreg, AT);
+ dbl ? "dsubu" : "subu", "d,v,t", dreg, sreg, AT);
break;
case M_TEQ_I:
load_address (&icnt, AT, &offset_expr);
if (breg != 0)
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", AT, AT, breg);
if (! target_big_endian)
expr1.X_add_number = off;
load_address (&icnt, AT, &offset_expr);
if (breg != 0)
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", AT, AT, breg);
if (target_big_endian)
expr1.X_add_number = 0;
load_address (&icnt, AT, &offset_expr);
if (breg != 0)
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", AT, AT, breg);
if (! target_big_endian)
expr1.X_add_number = off;
load_address (&icnt, AT, &offset_expr);
if (breg != 0)
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", AT, AT, breg);
if (! target_big_endian)
expr1.X_add_number = 0;
dbl = 1;
case M_MUL:
macro_build ((char *) NULL, &icnt, NULL,
- dbl ? "dmultu" : "multu",
- "x,y", xreg, yreg);
+ dbl ? "dmultu" : "multu", "x,y", xreg, yreg);
macro_build ((char *) NULL, &icnt, NULL, "mflo", "x", zreg);
return;
as_bad (_("Unsupported large constant"));
imm_expr.X_add_number = -imm_expr.X_add_number;
macro_build ((char *) NULL, &icnt, &imm_expr,
- dbl ? "daddiu" : "addiu",
- "y,x,4", yreg, xreg);
+ dbl ? "daddiu" : "addiu", "y,x,4", yreg, xreg);
break;
case M_SUBU_I_2:
expr1.X_add_number = 0;
macro_build ((char *) NULL, &icnt, &expr1, "slti", "x,8", yreg);
if (xreg != yreg)
- macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- "move", "y,X", xreg, yreg);
+ move_register (&icnt, xreg, yreg);
expr1.X_add_number = 2;
macro_build ((char *) NULL, &icnt, &expr1, "bteqz", "p");
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
assert (strcmp (insn->name, str) == 0);
- if (OPCODE_IS_MEMBER (insn, mips_opts.isa, mips_cpu, mips_gp32))
+ if (OPCODE_IS_MEMBER (insn, mips_opts.isa, mips_arch))
ok = true;
else
ok = false;
if (insn->pinfo != INSN_MACRO)
{
- if (mips_cpu == CPU_R4650 && (insn->pinfo & FP_D) != 0)
+ if (mips_arch == CPU_R4650 && (insn->pinfo & FP_D) != 0)
ok = false;
}
static char buf[100];
sprintf (buf,
_("opcode not supported on this processor: %s (%s)"),
- mips_cpu_to_str (mips_cpu),
+ mips_cpu_to_str (mips_arch),
mips_isa_to_str (mips_opts.isa));
insn_error = buf;
{
case 'r':
case 'v':
- ip->insn_opcode |= lastregno << 21;
+ ip->insn_opcode |= lastregno << OP_SH_RS;
continue;
case 'w':
+ ip->insn_opcode |= lastregno << OP_SH_RT;
+ continue;
+
case 'W':
- ip->insn_opcode |= lastregno << 16;
+ ip->insn_opcode |= lastregno << OP_SH_FT;
continue;
case 'V':
- ip->insn_opcode |= lastregno << 11;
+ ip->insn_opcode |= lastregno << OP_SH_FS;
continue;
}
break;
{
as_warn (_("Improper shift amount (%ld)"),
(long) imm_expr.X_add_number);
- imm_expr.X_add_number = imm_expr.X_add_number & 0x1f;
+ imm_expr.X_add_number &= OP_MASK_SHAMT;
}
- ip->insn_opcode |= imm_expr.X_add_number << 6;
+ ip->insn_opcode |= imm_expr.X_add_number << OP_SH_SHAMT;
imm_expr.X_op = O_absent;
s = expr_end;
continue;
if ((unsigned long) imm_expr.X_add_number < 32
|| (unsigned long) imm_expr.X_add_number > 63)
break;
- ip->insn_opcode |= (imm_expr.X_add_number - 32) << 6;
+ ip->insn_opcode |= (imm_expr.X_add_number - 32) << OP_SH_SHAMT;
imm_expr.X_op = O_absent;
s = expr_end;
continue;
{
as_warn (_("Illegal break code (%ld)"),
(long) imm_expr.X_add_number);
- imm_expr.X_add_number &= 0x3ff;
+ imm_expr.X_add_number &= OP_MASK_CODE;
}
- ip->insn_opcode |= imm_expr.X_add_number << 16;
+ ip->insn_opcode |= imm_expr.X_add_number << OP_SH_CODE;
imm_expr.X_op = O_absent;
s = expr_end;
continue;
{
as_warn (_("Illegal lower break code (%ld)"),
(long) imm_expr.X_add_number);
- imm_expr.X_add_number &= 0x3ff;
+ imm_expr.X_add_number &= OP_MASK_CODE2;
}
- ip->insn_opcode |= imm_expr.X_add_number << 6;
+ ip->insn_opcode |= imm_expr.X_add_number << OP_SH_CODE2;
imm_expr.X_op = O_absent;
s = expr_end;
continue;
case 'B': /* 20-bit syscall/break code. */
my_getExpression (&imm_expr, s);
check_absolute_expr (ip, &imm_expr);
- if ((unsigned) imm_expr.X_add_number > 0xfffff)
+ if ((unsigned) imm_expr.X_add_number > OP_MASK_CODE20)
as_warn (_("Illegal 20-bit code (%ld)"),
(long) imm_expr.X_add_number);
- ip->insn_opcode |= imm_expr.X_add_number << 6;
+ ip->insn_opcode |= imm_expr.X_add_number << OP_SH_CODE20;
imm_expr.X_op = O_absent;
s = expr_end;
continue;
case 'J': /* 19-bit wait code. */
my_getExpression (&imm_expr, s);
check_absolute_expr (ip, &imm_expr);
- if ((unsigned) imm_expr.X_add_number > 0x7ffff)
+ if ((unsigned) imm_expr.X_add_number > OP_MASK_CODE19)
as_warn (_("Illegal 19-bit code (%ld)"),
(long) imm_expr.X_add_number);
- ip->insn_opcode |= imm_expr.X_add_number << 6;
+ ip->insn_opcode |= imm_expr.X_add_number << OP_SH_CODE19;
imm_expr.X_op = O_absent;
s = expr_end;
continue;
check_absolute_expr (ip, &imm_expr);
if (imm_expr.X_add_number != 0 && imm_expr.X_add_number != 1)
{
- as_warn (_("Invalidate performance regster (%ld)"),
+ as_warn (_("Invalid performance register (%ld)"),
(long) imm_expr.X_add_number);
- imm_expr.X_add_number &= 1;
+ imm_expr.X_add_number &= OP_MASK_PERFREG;
}
- ip->insn_opcode |= (imm_expr.X_add_number << 1);
+ ip->insn_opcode |= (imm_expr.X_add_number << OP_SH_PERFREG);
imm_expr.X_op = O_absent;
s = expr_end;
continue;
case 's':
case 'v':
case 'b':
- ip->insn_opcode |= regno << 21;
+ ip->insn_opcode |= regno << OP_SH_RS;
break;
case 'd':
case 'G':
- ip->insn_opcode |= regno << 11;
+ ip->insn_opcode |= regno << OP_SH_RD;
break;
case 'U':
- ip->insn_opcode |= regno << 11;
- ip->insn_opcode |= regno << 16;
+ ip->insn_opcode |= regno << OP_SH_RD;
+ ip->insn_opcode |= regno << OP_SH_RT;
break;
case 'w':
case 't':
case 'E':
- ip->insn_opcode |= regno << 16;
+ ip->insn_opcode |= regno << OP_SH_RT;
break;
case 'x':
/* This case exists because on the r3000 trunc
{
case 'r':
case 'v':
- ip->insn_opcode |= lastregno << 21;
+ ip->insn_opcode |= lastregno << OP_SH_RS;
continue;
case 'w':
- ip->insn_opcode |= lastregno << 16;
+ ip->insn_opcode |= lastregno << OP_SH_RT;
continue;
}
break;
as_bad (_("Invalid float register number (%d)"), regno);
if ((regno & 1) != 0
- && ! ISA_HAS_64BIT_REGS (mips_opts.isa)
+ && HAVE_32BIT_FPRS
&& ! (strcmp (str, "mtc1") == 0
|| strcmp (str, "mfc1") == 0
|| strcmp (str, "lwc1") == 0
switch (c)
{
case 'D':
- ip->insn_opcode |= regno << 6;
+ ip->insn_opcode |= regno << OP_SH_FD;
break;
case 'V':
case 'S':
- ip->insn_opcode |= regno << 11;
+ ip->insn_opcode |= regno << OP_SH_FS;
break;
case 'W':
case 'T':
- ip->insn_opcode |= regno << 16;
+ ip->insn_opcode |= regno << OP_SH_FT;
break;
case 'R':
- ip->insn_opcode |= regno << 21;
+ ip->insn_opcode |= regno << OP_SH_FR;
break;
}
lastregno = regno;
switch (*args++)
{
case 'V':
- ip->insn_opcode |= lastregno << 11;
+ ip->insn_opcode |= lastregno << OP_SH_FS;
continue;
case 'W':
- ip->insn_opcode |= lastregno << 16;
+ ip->insn_opcode |= lastregno << OP_SH_FT;
continue;
}
break;
case 'l':
{
int f64;
+ int using_gprs;
char *save_in;
char *err;
unsigned char temp[8];
.lit4 inline easily; we need to put .lit8
somewhere in the data segment, and using .lit8
permits the linker to eventually combine identical
- .lit8 entries). */
+ .lit8 entries).
+
+ The code below needs to know whether the target register
+ is 32 or 64 bits wide. It relies on the fact 'f' and
+ 'F' are used with GPR-based instructions and 'l' and
+ 'L' are used with FPR-based instructions. */
f64 = *args == 'F' || *args == 'L';
+ using_gprs = *args == 'F' || *args == 'f';
save_in = input_line_pointer;
input_line_pointer = s;
}
else if (length > 4
&& ! mips_disable_float_construction
+ /* Constants can only be constructed in GPRs and
+ copied to FPRs if the GPRs are at least as wide
+ as the FPRs. Force the constant into memory if
+ we are using 64-bit FPRs but the GPRs are only
+ 32 bits wide. */
+ && (using_gprs
+ || ! (HAVE_64BIT_FPRS && HAVE_32BIT_GPRS))
&& ((temp[0] == 0 && temp[1] == 0)
|| (temp[2] == 0 && temp[3] == 0))
&& ((temp[4] == 0 && temp[5] == 0)
|| (temp[6] == 0 && temp[7] == 0)))
{
- /* The value is simple enough to load with a
- couple of instructions. In mips1 mode, set
- imm_expr to the high order 32 bits and
- offset_expr to the low order 32 bits.
- Otherwise, set imm_expr to the entire 64 bit
- constant. */
- if (! ISA_HAS_64BIT_REGS (mips_opts.isa))
+ /* The value is simple enough to load with a couple of
+ instructions. If using 32-bit registers, set
+ imm_expr to the high order 32 bits and offset_expr to
+ the low order 32 bits. Otherwise, set imm_expr to
+ the entire 64 bit constant. */
+ if (using_gprs ? HAVE_32BIT_GPRS : HAVE_32BIT_FPRS)
{
imm_expr.X_op = O_constant;
offset_expr.X_op = O_constant;
case 'j': /* 16 bit signed immediate */
imm_reloc = BFD_RELOC_LO16;
c = my_getSmallExpression (&imm_expr, s);
- if (c != '\0')
+ if (c != S_EX_NONE)
{
- if (c != 'l')
+ if (c != S_EX_LO)
{
if (imm_expr.X_op == O_constant)
imm_expr.X_add_number =
(imm_expr.X_add_number >> 16) & 0xffff;
- else if (c == 'h')
+ else if (c == S_EX_HIGHEST)
+ imm_reloc = BFD_RELOC_MIPS_HIGHEST;
+ else if (c == S_EX_HIGHER)
+ imm_reloc = BFD_RELOC_MIPS_HIGHER;
+ else if (c == S_EX_HI)
{
imm_reloc = BFD_RELOC_HI16_S;
imm_unmatched_hi = true;
}
if (*args == 'i')
{
- if ((c == '\0' && imm_expr.X_op != O_constant)
+ if ((c == S_EX_NONE && imm_expr.X_op != O_constant)
|| ((imm_expr.X_add_number < 0
|| imm_expr.X_add_number >= 0x10000)
&& imm_expr.X_op == O_constant))
max = 0x8000;
else
max = 0x10000;
- if ((c == '\0' && imm_expr.X_op != O_constant)
+ if ((c == S_EX_NONE && imm_expr.X_op != O_constant)
|| ((imm_expr.X_add_number < -0x8000
|| imm_expr.X_add_number >= max)
&& imm_expr.X_op == O_constant)
|| (more
&& imm_expr.X_add_number < 0
- && ISA_HAS_64BIT_REGS (mips_opts.isa)
+ && HAVE_64BIT_GPRS
&& imm_expr.X_unsigned
&& sizeof (imm_expr.X_add_number) <= 4))
{
fashion is that the macro function doesn't expect to
see anything which can be handled in a single
constant instruction. */
- if (c == 0
+ if (c == S_EX_NONE
&& (offset_expr.X_op != O_constant
|| offset_expr.X_add_number >= 0x8000
|| offset_expr.X_add_number < -0x8000)
!= S_GET_SEGMENT (offset_expr.X_op_symbol))))
break;
- if (c == 'h' || c == 'H')
+ if (c == S_EX_HI)
{
if (offset_expr.X_op != O_constant)
break;
case 'u': /* upper 16 bits */
c = my_getSmallExpression (&imm_expr, s);
imm_reloc = BFD_RELOC_LO16;
- if (c)
+ if (c != S_EX_NONE)
{
- if (c != 'l')
+ if (c != S_EX_LO)
{
if (imm_expr.X_op == O_constant)
imm_expr.X_add_number =
(imm_expr.X_add_number >> 16) & 0xffff;
- else if (c == 'h')
+ else if (c == S_EX_HIGHEST)
+ imm_reloc = BFD_RELOC_MIPS_HIGHEST;
+ else if (c == S_EX_HI)
{
imm_reloc = BFD_RELOC_HI16_S;
imm_unmatched_hi = true;
}
}
\f
-#define LP '('
-#define RP ')'
static int
my_getSmallExpression (ep, str)
char *str;
{
char *sp;
- int c = 0;
+ char *oldstr = str;
+ int c = S_EX_NONE;
if (*str == ' ')
str++;
- if (*str == LP
- || (*str == '%' &&
- ((str[1] == 'h' && str[2] == 'i')
- || (str[1] == 'H' && str[2] == 'I')
- || (str[1] == 'l' && str[2] == 'o'))
- && str[3] == LP))
- {
- if (*str == LP)
- c = 0;
- else
- {
- c = str[1];
- str += 3;
- }
+ if (*str == '(')
+ c = S_EX_NONE;
+ else if (str[0] == '%'
+ && tolower(str[1]) == 'l'
+ && tolower(str[2]) == 'o'
+ && str[3] == '(')
+ {
+ c = S_EX_LO;
+ str += sizeof ("%lo(") - 2;
+ }
+ else if (str[0] == '%'
+ && tolower(str[1]) == 'h'
+ && tolower(str[2]) == 'i'
+ && str[3] == '(')
+ {
+ c = S_EX_HI;
+ str += sizeof ("%hi(") - 2;
+ }
+ else if (str[0] == '%'
+ && tolower(str[1]) == 'h'
+ && tolower(str[2]) == 'i'
+ && tolower(str[3]) == 'g'
+ && tolower(str[4]) == 'h'
+ && tolower(str[5]) == 'e'
+ && tolower(str[6]) == 'r'
+ && str[7] == '(')
+ {
+ c = S_EX_HIGHER;
+ str += sizeof ("%higher(") - 2;
+ }
+ else if (str[0] == '%'
+ && tolower(str[1]) == 'h'
+ && tolower(str[2]) == 'i'
+ && tolower(str[3]) == 'g'
+ && tolower(str[4]) == 'h'
+ && tolower(str[5]) == 'e'
+ && tolower(str[6]) == 's'
+ && tolower(str[7]) == 't'
+ && str[8] == '(')
+ {
+ c = S_EX_HIGHEST;
+ str += sizeof ("%highest(") - 2;
+ }
+/* currently unsupported */
+#if 0
+ else if (str[0] == '%'
+ && tolower(str[1]) == 'g'
+ && tolower(str[2]) == 'p'
+ && tolower(str[3]) == '_'
+ && tolower(str[4]) == 'r'
+ && tolower(str[5]) == 'e'
+ && tolower(str[6]) == 'l'
+ && str[7] == '(')
+ {
+ c = S_EX_GPREL;
+ str += sizeof ("%gp_rel(") - 2;
+ }
+ else if (str[0] == '%'
+ && tolower(str[1]) == 'n'
+ && tolower(str[2]) == 'e'
+ && tolower(str[3]) == 'g'
+ && str[4] == '(')
+ {
+ c = S_EX_NEG;
+ str += sizeof ("%neg(") - 2;
+ }
+#endif
+ else
+ {
+ my_getExpression (ep, str);
+ return c;
+ }
- /*
- * A small expression may be followed by a base register.
- * Scan to the end of this operand, and then back over a possible
- * base register. Then scan the small expression up to that
- * point. (Based on code in sparc.c...)
- */
- for (sp = str; *sp && *sp != ','; sp++)
- ;
- if (sp - 4 >= str && sp[-1] == RP)
+ /*
+ * A small expression may be followed by a base register.
+ * Scan to the end of this operand, and then back over a possible
+ * base register. Then scan the small expression up to that
+ * point. (Based on code in sparc.c...)
+ */
+ for (sp = str; *sp && *sp != ','; sp++)
+ ;
+ if (sp - 4 >= str && sp[-1] == ')')
+ {
+ if (isdigit ((unsigned char) sp[-2]))
{
- if (isdigit ((unsigned char) sp[-2]))
+ for (sp -= 3; sp >= str && isdigit ((unsigned char) *sp); sp--)
+ ;
+ if (*sp == '$' && sp > str && sp[-1] == '(')
{
- for (sp -= 3; sp >= str && isdigit ((unsigned char) *sp); sp--)
- ;
- if (*sp == '$' && sp > str && sp[-1] == LP)
- {
- sp--;
- goto do_it;
- }
+ sp--;
+ goto do_it;
}
- else if (sp - 5 >= str
- && sp[-5] == LP
- && sp[-4] == '$'
- && ((sp[-3] == 'f' && sp[-2] == 'p')
- || (sp[-3] == 's' && sp[-2] == 'p')
- || (sp[-3] == 'g' && sp[-2] == 'p')
- || (sp[-3] == 'a' && sp[-2] == 't')))
+ }
+ else if (sp - 5 >= str
+ && sp[-5] == '('
+ && sp[-4] == '$'
+ && ((sp[-3] == 'f' && sp[-2] == 'p')
+ || (sp[-3] == 's' && sp[-2] == 'p')
+ || (sp[-3] == 'g' && sp[-2] == 'p')
+ || (sp[-3] == 'a' && sp[-2] == 't')))
+ {
+ sp -= 5;
+ do_it:
+ if (sp == str)
{
- sp -= 5;
- do_it:
- if (sp == str)
+ /* no expression means zero offset */
+ if (c != S_EX_NONE)
{
- /* no expression means zero offset */
- if (c)
- {
- /* %xx(reg) is an error */
- ep->X_op = O_absent;
- expr_end = str - 3;
- }
- else
- {
- ep->X_op = O_constant;
- expr_end = sp;
- }
- ep->X_add_symbol = NULL;
- ep->X_op_symbol = NULL;
- ep->X_add_number = 0;
+ /* %xx(reg) is an error */
+ ep->X_op = O_absent;
+ expr_end = oldstr;
}
else
{
- *sp = '\0';
- my_getExpression (ep, str);
- *sp = LP;
+ ep->X_op = O_constant;
+ expr_end = sp;
}
- return c;
+ ep->X_add_symbol = NULL;
+ ep->X_op_symbol = NULL;
+ ep->X_add_number = 0;
}
+ else
+ {
+ *sp = '\0';
+ my_getExpression (ep, str);
+ *sp = '(';
+ }
+ return c;
}
}
my_getExpression (ep, str);
- return c; /* => %hi or %lo encountered */
+
+ /* => %highest, %higher, %hi, %lo, %gprel, %neg encountered */
+ return c;
}
static void
number_to_chars_littleendian (buf, val, n);
}
\f
-CONST char *md_shortopts = "O::g::G:";
+CONST char *md_shortopts = "nO::g::G:";
struct option md_longopts[] =
{
{"mips5", no_argument, NULL, OPTION_MIPS5},
#define OPTION_MIPS64 (OPTION_MD_BASE + 30)
{"mips64", no_argument, NULL, OPTION_MIPS64},
+#define OPTION_MARCH (OPTION_MD_BASE + 31)
+ {"march", required_argument, NULL, OPTION_MARCH},
+#define OPTION_MTUNE (OPTION_MD_BASE + 32)
+ {"mtune", required_argument, NULL, OPTION_MTUNE},
+#define OPTION_FP32 (OPTION_MD_BASE + 33)
+ {"mfp32", no_argument, NULL, OPTION_FP32},
#ifdef OBJ_ELF
#define OPTION_ELF_BASE (OPTION_MD_BASE + 35)
#define OPTION_CALL_SHARED (OPTION_ELF_BASE + 0)
target_big_endian = 0;
break;
+ case 'n':
+ warn_nops = 1;
+ break;
+
case 'O':
if (arg && arg[1] == '0')
mips_optimize = 1;
mips_opts.isa = ISA_MIPS64;
break;
+ case OPTION_MTUNE:
+ case OPTION_MARCH:
case OPTION_MCPU:
{
+ int cpu = CPU_UNKNOWN;
+
/* Identify the processor type. */
- if (strcasecmp (arg, "default") == 0)
- mips_cpu = CPU_UNKNOWN;
- else
+ if (strcasecmp (arg, "default") != 0)
{
const struct mips_cpu_info *ci;
ci = mips_cpu_info_from_name (arg);
if (ci == NULL || ci->is_isa)
- as_bad (_("invalid architecture -mcpu=%s"), arg);
+ {
+ switch (c)
+ {
+ case OPTION_MTUNE:
+ as_fatal (_("invalid architecture -mtune=%s"), arg);
+ break;
+ case OPTION_MARCH:
+ as_fatal (_("invalid architecture -march=%s"), arg);
+ break;
+ case OPTION_MCPU:
+ as_fatal (_("invalid architecture -mcpu=%s"), arg);
+ break;
+ }
+ }
else
- mips_cpu = ci->cpu;
+ cpu = ci->cpu;
+ }
+
+ switch (c)
+ {
+ case OPTION_MTUNE:
+ if (mips_tune != CPU_UNKNOWN && mips_tune != cpu)
+ as_warn(_("A different -mtune= was already specified, is now "
+ "-mtune=%s"), arg);
+ mips_tune = cpu;
+ break;
+ case OPTION_MARCH:
+ if (mips_arch != CPU_UNKNOWN && mips_arch != cpu)
+ as_warn(_("A different -march= was already specified, is now "
+ "-march=%s"), arg);
+ mips_arch = cpu;
+ break;
+ case OPTION_MCPU:
+ if (mips_cpu != CPU_UNKNOWN && mips_cpu != cpu)
+ as_warn(_("A different -mcpu= was already specified, is now "
+ "-mcpu=%s"), arg);
+ mips_cpu = cpu;
}
}
break;
case OPTION_M4650:
- mips_cpu = CPU_R4650;
+ if ((mips_arch != CPU_UNKNOWN && mips_arch != CPU_R4650)
+ || (mips_tune != CPU_UNKNOWN && mips_tune != CPU_R4650))
+ as_warn(_("A different -march= or -mtune= was already specified, "
+ "is now -m4650"));
+ mips_arch = CPU_R4650;
+ mips_tune = CPU_R4650;
break;
case OPTION_NO_M4650:
break;
case OPTION_M4010:
- mips_cpu = CPU_R4010;
+ if ((mips_arch != CPU_UNKNOWN && mips_arch != CPU_R4010)
+ || (mips_tune != CPU_UNKNOWN && mips_tune != CPU_R4010))
+ as_warn(_("A different -march= or -mtune= was already specified, "
+ "is now -m4010"));
+ mips_arch = CPU_R4010;
+ mips_tune = CPU_R4010;
break;
case OPTION_NO_M4010:
break;
case OPTION_M4100:
- mips_cpu = CPU_VR4100;
+ if ((mips_arch != CPU_UNKNOWN && mips_arch != CPU_VR4100)
+ || (mips_tune != CPU_UNKNOWN && mips_tune != CPU_VR4100))
+ as_warn(_("A different -march= or -mtune= was already specified, "
+ "is now -m4100"));
+ mips_arch = CPU_VR4100;
+ mips_tune = CPU_VR4100;
break;
case OPTION_NO_M4100:
break;
case OPTION_M3900:
- mips_cpu = CPU_R3900;
+ if ((mips_arch != CPU_UNKNOWN && mips_arch != CPU_R3900)
+ || (mips_tune != CPU_UNKNOWN && mips_tune != CPU_R3900))
+ as_warn(_("A different -march= or -mtune= was already specified, "
+ "is now -m3900"));
+ mips_arch = CPU_R3900;
+ mips_tune = CPU_R3900;
break;
case OPTION_NO_M3900:
list = bfd_target_list ();
for (l = list; *l != NULL; l++)
- if (strcmp (*l, "elf64-bigmips") == 0
- || strcmp (*l, "elf64-littlemips") == 0
- || strcmp (*l, "elf64-tradbigmips") == 0
+#ifdef TE_TMIPS
+ /* This is traditional mips */
+ if (strcmp (*l, "elf64-tradbigmips") == 0
|| strcmp (*l, "elf64-tradlittlemips") == 0)
+#else
+ if (strcmp (*l, "elf64-bigmips") == 0
+ || strcmp (*l, "elf64-littlemips") == 0)
+#endif
break;
if (*l == NULL)
as_fatal (_("No compiled in support for 64 bit object file format"));
#endif
break;
+ case OPTION_FP32:
+ mips_fp32 = 1;
+ break;
+
case OPTION_MABI:
if (strcmp (arg, "32") == 0
|| strcmp (arg, "n32") == 0
|| strcmp (arg, "64") == 0
|| strcmp (arg, "o64") == 0
|| strcmp (arg, "eabi") == 0)
- mips_abi_string = arg;
+ {
+ mips_abi_string = arg;
+ mips_32bit_abi = (strcmp (arg, "32") == 0);
+ }
break;
case OPTION_M7000_HILO_FIX:
-membedded-pic generate embedded position independent code\n\
-EB generate big endian output\n\
-EL generate little endian output\n\
--g, -g2 do not remove uneeded NOPs or swap branches\n\
+-g, -g2 do not remove unneeded NOPs or swap branches\n\
-G NUM allow referencing objects up to NUM bytes\n\
implicitly with the gp register [default 8]\n"));
fprintf (stream, _("\
-mips5 generate MIPS ISA V instructions\n\
-mips32 generate MIPS32 ISA instructions\n\
-mips64 generate MIPS64 ISA instructions\n\
--mcpu=CPU generate code for CPU, where CPU is one of:\n"));
+-march=CPU/-mtune=CPU generate code/schedule for CPU, where CPU is one of:\n"));
first = 1;
show (stream, "4600", &column, &first);
show (stream, "4650", &column, &first);
show (stream, "5000", &column, &first);
+ show (stream, "5200", &column, &first);
+ show (stream, "5230", &column, &first);
+ show (stream, "5231", &column, &first);
+ show (stream, "5261", &column, &first);
+ show (stream, "5721", &column, &first);
show (stream, "6000", &column, &first);
show (stream, "8000", &column, &first);
show (stream, "10000", &column, &first);
fputc ('\n', stream);
fprintf (stream, _("\
--mCPU equivalent to -mcpu=CPU.\n\
+-mCPU equivalent to -march=CPU -mtune=CPU. Deprecated.\n\
-no-mCPU don't generate code specific to CPU.\n\
For -mCPU and -no-mCPU, CPU must be one of:\n"));
-mips16 generate mips16 instructions\n\
-no-mips16 do not generate mips16 instructions\n"));
fprintf (stream, _("\
+-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\
-O remove unneeded NOPs and swap branches\n\
+-n warn about NOPs generated from macros\n\
--[no-]construct-floats [dis]allow floating point values to be constructed\n\
--trap, --no-break trap exception on div by 0 and mult overflow\n\
--break, --no-trap break exception on div by 0 and mult overflow\n"));
return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
}
-/* This is called by emit_expr via TC_CONS_FIX_NEW when creating a
- reloc for a cons. We could use the definition there, except that
- we want to handle 64 bit relocs specially. */
-
-void
-cons_fix_new_mips (frag, where, nbytes, exp)
- fragS *frag ATTRIBUTE_UNUSED;
- int where;
- unsigned int nbytes;
- expressionS *exp;
-{
-#ifndef OBJ_ELF
- /* If we are assembling in 32 bit mode, turn an 8 byte reloc into a
- 4 byte reloc. */
- if (nbytes == 8 && ! mips_64)
- {
- if (target_big_endian)
- where += 4;
- nbytes = 4;
- }
-#endif
-
- if (nbytes != 2 && nbytes != 4 && nbytes != 8)
- as_bad (_("Unsupported reloc size %d"), nbytes);
-
- fix_new_exp (frag_now, where, (int) nbytes, exp, 0,
- (nbytes == 2
- ? BFD_RELOC_16
- : (nbytes == 4 ? BFD_RELOC_32 : BFD_RELOC_64)));
-}
-
/* This is called before the symbol table is processed. In order to
work with gcc when using mips-tfile, we must keep all local labels.
However, in other cases, we want to discard them. If we were
{
valueT symval = S_GET_VALUE (fixP->fx_addsy);
value -= symval;
- if (value != 0 && ! fixP->fx_pcrel)
+ if (value != 0
+ && ! fixP->fx_pcrel
+ && fixP->fx_r_type != BFD_RELOC_MIPS_GPREL)
{
/* 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.
- FIXME: If this makes VALUE zero, we're toast. */
+ the addend to appear in the object file. */
value -= symval;
+
+ /* Make sure the addend is still non-zero. If it became zero
+ after the last operation, set it to a spurious value and
+ subtract the same value from the object file's contents. */
+ if (value == 0)
+ {
+ value = 8;
+
+ /* The in-place addends for LO16 relocations are signed;
+ leave the matching HI16 in-place addends as zero. */
+ if (fixP->fx_r_type != BFD_RELOC_HI16_S)
+ {
+ reloc_howto_type *howto;
+ bfd_vma contents, mask, field;
+
+ howto = bfd_reloc_type_lookup (stdoutput,
+ fixP->fx_r_type);
+
+ contents = bfd_get_bits (fixP->fx_frag->fr_literal
+ + fixP->fx_where,
+ fixP->fx_size * 8,
+ target_big_endian);
+
+ /* MASK has bits set where the relocation should go.
+ FIELD is -value, shifted into the appropriate place
+ for this relocation. */
+ mask = 1 << (howto->bitsize - 1);
+ mask = (((mask - 1) << 1) | 1) << howto->bitpos;
+ field = (-value >> howto->rightshift) << howto->bitpos;
+
+ bfd_put_bits ((field & mask) | (contents & ~mask),
+ fixP->fx_frag->fr_literal + fixP->fx_where,
+ fixP->fx_size * 8,
+ target_big_endian);
+ }
+ }
}
}
value += (fixP->fx_next->fx_frag->fr_address
+ fixP->fx_next->fx_where);
}
- if (value & 0x8000)
- value += 0x10000;
- value >>= 16;
+ value = ((value + 0x8000) >> 16) & 0xffff;
buf = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
if (target_big_endian)
buf += 2;
case 1: mips_opts.isa = ISA_MIPS1; break;
case 2: mips_opts.isa = ISA_MIPS2; break;
case 3: mips_opts.isa = ISA_MIPS3; break;
- case 5: mips_opts.isa = ISA_MIPS5; break;
case 4: mips_opts.isa = ISA_MIPS4; break;
+ case 5: mips_opts.isa = ISA_MIPS5; break;
case 32: mips_opts.isa = ISA_MIPS32; break;
case 64: mips_opts.isa = ISA_MIPS64; break;
default: as_bad (_("unknown ISA level")); break;
ex.X_add_number = mips_cprestore_offset;
macro_build ((char *) NULL, &icnt, &ex,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "sw" : "sd"),
+ HAVE_32BIT_ADDRESSES ? "sw" : "sd",
"t,o(b)", GP, (int) BFD_RELOC_LO16, SP);
demand_empty_rest_of_line ();
/* Add $gp to the register named as an argument. */
reg = tc_get_register (0);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- ((bfd_arch_bits_per_address (stdoutput) == 32
- || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
- ? "addu" : "daddu"),
+ HAVE_32BIT_ADDRESSES ? "addu" : "daddu",
"d,v,t", reg, reg, GP);
demand_empty_rest_of_line ();
}
sym_frag = symbol_get_frag (fragp->fr_symbol);
- val = S_GET_VALUE (fragp->fr_symbol) + sym_frag->fr_address;
+ val = S_GET_VALUE (fragp->fr_symbol);
symsec = S_GET_SEGMENT (fragp->fr_symbol);
if (op->pcrel)
&& !linkonce
#ifdef OBJ_ELF
/* A global or weak symbol is treated as external. */
- && ! (S_IS_EXTERN (sym) || S_IS_WEAK (sym))
+ && (OUTPUT_FLAVOR == bfd_target_elf_flavour
+ && ! (S_IS_EXTERN (sym) || S_IS_WEAK (sym)))
#endif
);
}
+ RELAX_RELOC1 (fragp->fr_subtype));
/* FIXME: This really needs as_warn_where. */
if (RELAX_WARN (fragp->fr_subtype))
- as_warn (_("AT used after \".set noat\" or macro used after \".set nomacro\""));
+ as_warn (_("AT used after \".set noat\" or macro used after "
+ "\".set nomacro\""));
+
+ return RELAX_NEW (fragp->fr_subtype) - RELAX_OLD (fragp->fr_subtype);
}
- if (! change)
- return 0;
- else
- return RELAX_NEW (fragp->fr_subtype) - RELAX_OLD (fragp->fr_subtype);
+ return 0;
}
/* This is called to see whether a reloc against a defined symbol
{
#ifdef OBJ_ELF
/* Prevent all adjustments to global symbols. */
- if (S_IS_EXTERN (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy))
+ if (OUTPUT_FLAVOR == bfd_target_elf_flavour
+ && (S_IS_EXTERN (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)))
return 0;
#endif
if (fixp->fx_r_type == BFD_RELOC_MIPS16_JMP)
elf_elfheader (stdoutput)->e_flags |= EF_MIPS_PIC;
/* Set the MIPS ELF ABI flags. */
- if (mips_abi_string == 0)
+ if (mips_abi_string == NULL)
;
else if (strcmp (mips_abi_string, "32") == 0)
elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_O32;
else
elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_EABI32;
}
+ else if (strcmp (mips_abi_string, "n32") == 0)
+ elf_elfheader (stdoutput)->e_flags |= EF_MIPS_ABI2;
+
+ /* Nothing to do for "64". */
if (mips_32bitmode)
elf_elfheader (stdoutput)->e_flags |= EF_MIPS_32BITMODE;
{
/* check for premature end, nesting errors, etc */
if (cur_proc_ptr)
- as_warn (_("missing `.end' at end of assembly"));
+ as_warn (_("missing .end at end of assembly"));
}
static long
{
segT saved_seg = now_seg;
subsegT saved_subseg = now_subseg;
- fragS *saved_frag = frag_now;
valueT dot;
- segT seg;
expressionS exp;
char *fragp;
as_warn (_(".ent or .aent not in text section."));
if (!aent && cur_proc_ptr)
- as_warn (_("missing `.end'"));
+ as_warn (_("missing .end"));
if (!aent)
{
static void
s_mips_frame (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
#ifdef MIPS_STABS_ELF
{ "mips64vr5000", 0, ISA_MIPS4, CPU_R5000, },
{ "r5000", 0, ISA_MIPS4, CPU_R5000, },
{ "r5200", 0, ISA_MIPS4, CPU_R5000, },
+ { "rm5200", 0, ISA_MIPS4, CPU_R5000, },
{ "r5230", 0, ISA_MIPS4, CPU_R5000, },
+ { "rm5230", 0, ISA_MIPS4, CPU_R5000, },
{ "r5231", 0, ISA_MIPS4, CPU_R5000, },
+ { "rm5231", 0, ISA_MIPS4, CPU_R5000, },
{ "r5261", 0, ISA_MIPS4, CPU_R5000, },
+ { "rm5261", 0, ISA_MIPS4, CPU_R5000, },
{ "r5721", 0, ISA_MIPS4, CPU_R5000, },
+ { "rm5721", 0, ISA_MIPS4, CPU_R5000, },
{ "r5k", 0, ISA_MIPS4, CPU_R5000, },
{ "r7000", 0, ISA_MIPS4, CPU_R5000, },