/* tc-mips.c -- assemble code for a MIPS chip.
- Copyright (C) 1993, 94, 95, 96, 97, 1998 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
#undef S_GET_SIZE
#undef S_SET_ALIGN
#undef S_SET_SIZE
-#undef TARGET_SYMBOL_FIELDS
#undef obj_frob_file
#undef obj_frob_file_after_relocs
#undef obj_frob_symbol
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:
+#ifdef TE_TMIPS
+ /* This is traditional mips */
+ return (target_big_endian
+ ? "elf32-tradbigmips" : "elf32-tradlittlemips");
+#else
return (target_big_endian
? (mips_64 ? "elf64-bigmips" : "elf32-bigmips")
: (mips_64 ? "elf64-littlemips" : "elf32-littlemips"));
+#endif
default:
abort ();
return NULL;
? ".data" \
: OUTPUT_FLAVOR == bfd_target_ecoff_flavour \
? ".rdata" \
+ : OUTPUT_FLAVOR == bfd_target_coff_flavour \
+ ? ".rdata" \
: OUTPUT_FLAVOR == bfd_target_elf_flavour \
? ".rodata" \
: (abort (), ""))
/* This is the set of options which may be modified by the .set
pseudo-op. We use a struct so that .set push and .set pop are more
- reliable.
-
- FIXME: The CPU specific variables (mips_4010, et. al.) should
- probably be in here as well, and there should probably be some way
- to set them. */
+ reliable. */
struct mips_set_options
{
that we must set the isa and mips16 fields to -1 to indicate that
they have not been initialized. */
-static struct mips_set_options mips_opts = { -1, -1 };
+static struct mips_set_options mips_opts = { -1, -1, 0, 0, 0, 0, 0, 0 };
/* These variables are filled in with the masks of registers used.
The object format code reads them and puts them in the appropriate
/* The CPU type as a number: 2000, 3000, 4000, 4400, etc. */
static int mips_cpu = -1;
-/* Whether the 4650 instructions (mad/madu) are permitted. */
-static int mips_4650 = -1;
-
-/* Whether the 4010 instructions are permitted. */
-static int mips_4010 = -1;
-
-/* Whether the 4100 MADD16 and DMADD16 are permitted. */
-static int mips_4100 = -1;
-
-/* start-sanitize-vr4320 */
-/* Whether NEC vr4320 instructions are permitted. */
-static int mips_4320 = -1;
+/* The argument of the -mabi= flag. */
+static char* mips_abi_string = 0;
+
+/* Wether 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
+ 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 \
+ )
-/* end-sanitize-vr4320 */
-/* start-sanitize-vr5400 */
-/* Whether NEC vr5400 instructions are permitted. */
-static int mips_5400 = -1;
+/* Whether the processor uses hardware interlocks to protect
+ reads from the HI and LO registers, and thus does not
+ require nops to be inserted.
-/* end-sanitize-vr5400 */
-/* start-sanitize-r5900 */
-/* Whether Toshiba r5900 instructions are permitted. */
-static int mips_5900 = -1;
+ 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.
-/* end-sanitize-r5900 */
-/* Whether Toshiba r3900 instructions are permitted. */
-static int mips_3900 = -1;
+ 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.
-/* start-sanitize-tx49 */
-/* Whether Toshiba r4900 instructions are permitted. */
-static int mips_4900 = -1;
+ 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?
-/* end-sanitize-tx49 */
-/* start-sanitize-tx19 */
-/* The tx19 (r1900) is a mips16 decoder with a tx39(r3900) behind it.
- The tx19 related options and configuration bits are handled by
- the tx39 flags. */
-/* end-sanitize-tx19 */
+ So now, at least, -mcpu=FOO and -mFOO are exactly equivalent.
-/* Whether the processor uses hardware interlocks to protect
- reads from the HI and LO registers, and thus does not
- require nops to be inserted.
+ -- Jim Blandy <jimb@cygnus.com> */
- FIXME: We really should not be checking mips_cpu here. The -mcpu=
- option is documented to not do anything special. In gcc, the
- -mcpu= option only affects scheduling, and does not affect code
- generation. Each test of -mcpu= here should actually be testing a
- specific variable, such as mips_4010, and each such variable should
- have a command line option to set it. The -mcpu= option may be
- used to set the default value of these options, as is the case for
- mips_4010. */
-
-#define hilo_interlocks (mips_4010 || mips_3900 \
- /* start-sanitize-tx49 */ \
- || mips_cpu == 4900 || mips_4900 \
- /* end-sanitize-tx49 */ \
- /* start-sanitize-vr4320 */ \
- || mips_cpu == 4320 \
- /* end-sanitize-vr4320 */ \
- /* start-sanitize-r5900 */ \
- || mips_5900 \
- /* end-sanitize-r5900 */ \
+#define hilo_interlocks (mips_cpu == 4010 \
)
/* 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_3900)
-/* start-sanitize-vr5400 */
-#undef gpr_interlocks
-#define gpr_interlocks (mips_opts.isa >= 2 || mips_3900 || mips_5400)
-/* end-sanitize-vr5400 */
-
+#define gpr_interlocks \
+ (mips_opts.isa != 1 \
+ || mips_cpu == 3900)
/* 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 == 4300 \
- /* start-sanitize-vr4320 */ \
- || mips_cpu == 4320 \
- /* end-sanitize-vr4320 */ \
- /* start-sanitize-vr5400 */ \
- || mips_cpu == 5400 \
- /* end-sanitize-vr5400 */ \
)
+/* 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
instructions. */
static int mips_trap;
+/* 1 if double width floating point constants should not be constructed
+ by a assembling two single width halves into two single width floating
+ point registers which just happen to alias the double width destination
+ register. On some architectures this aliasing can be disabled by a bit
+ in the status register, and the settin gof this bit cannot be determined
+ automatically at assemble time. */
+static int mips_disable_float_construction;
+
/* Non-zero if any .set noreorder directives were used. */
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 */
const char line_comment_chars[] = "#";
/* This array holds machine specific line separator characters. */
-const char line_separator_chars[] = "";
+const char line_separator_chars[] = ";";
/* Chars that can be used to separate mant from exp in floating point nums */
const char EXP_CHARS[] = "eE";
/* If we don't want information for prev_insn or prev_prev_insn, we
point the insn_mo field at this dummy integer. */
-static const struct mips_opcode dummy_opcode = { 0 };
+static const struct mips_opcode dummy_opcode = { NULL, NULL, 0, 0, 0, 0 };
/* Non-zero if prev_insn is valid. */
static int prev_insn_valid;
static void md_obj_begin PARAMS ((void));
static void md_obj_end PARAMS ((void));
static long get_number PARAMS ((void));
-static void s_ent PARAMS ((int));
-static void s_mipsend PARAMS ((int));
-static void s_file PARAMS ((int));
+static void s_mips_ent PARAMS ((int));
+static void s_mips_end PARAMS ((int));
+static void s_mips_frame PARAMS ((int));
+static void s_mips_mask PARAMS ((int));
static void s_mips_stab PARAMS ((int));
static void s_mips_weakext PARAMS ((int));
+static void s_file PARAMS ((int));
static int mips16_extended_frag PARAMS ((fragS *, asection *, long));
{"stabn", s_mips_stab, 'n'},
{"text", s_change_sec, 't'},
{"word", s_cons, 2},
- { 0 },
+ { NULL, NULL, 0 },
};
static const pseudo_typeS mips_nonecoff_pseudo_table[] = {
/* These pseudo-ops should be defined by the object file format.
However, a.out doesn't support them, so we have versions here. */
- {"aent", s_ent, 1},
+ {"aent", s_mips_ent, 1},
{"bgnb", s_ignore, 0},
- {"end", s_mipsend, 0},
+ {"end", s_mips_end, 0},
{"endb", s_ignore, 0},
- {"ent", s_ent, 0},
+ {"ent", s_mips_ent, 0},
{"file", s_file, 0},
- {"fmask", s_ignore, 'F'},
- {"frame", s_ignore, 0},
+ {"fmask", s_mips_mask, 'F'},
+ {"frame", s_mips_frame, 0},
{"loc", s_ignore, 0},
- {"mask", s_ignore, 'R'},
+ {"mask", s_mips_mask, 'R'},
{"verstamp", s_ignore, 0},
- { 0 },
+ { NULL, NULL, 0 },
};
extern void pop_insert PARAMS ((const pseudo_typeS *));
static boolean mips16_small, mips16_ext;
+#ifdef MIPS_STABS_ELF
+/* The pdr segment for per procedure frame/regmask info */
+
+static segT pdr_seg;
+#endif
+
/*
* This function is called once, at assembler startup time. It should
* set up all the tables, etc. that the MD part of the assembler will need.
const char *cpu;
char *a = NULL;
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)
else if (strcmp (cpu, "r3900") == 0
|| strcmp (cpu, "mipstx39") == 0
- /* start-sanitize-tx19 */
- || strcmp (cpu, "r1900") == 0
- || strcmp (cpu, "mipstx19") == 0
- /* end-sanitize-tx19 */
)
mips_cpu = 3900;
else if (strcmp (cpu, "mips64vr4300") == 0)
mips_cpu = 4300;
- /* start-sanitize-vr4320 */
- else if (strcmp (cpu, "r4320") == 0
- || strcmp (cpu, "mips64vr4320") == 0)
- mips_cpu = 4320;
+ else if (strcmp (cpu, "mips64vr4111") == 0)
+ mips_cpu = 4111;
- /* end-sanitize-vr4320 */
else if (strcmp (cpu, "mips64vr4100") == 0)
mips_cpu = 4100;
else if (strcmp (cpu, "r4010") == 0)
mips_cpu = 4010;
- /* start-sanitize-tx49 */
- else if (strcmp (cpu, "mips64tx49") == 0)
- mips_cpu = 4900;
- /* end-sanitize-tx49 */
else if (strcmp (cpu, "r5000") == 0
|| strcmp (cpu, "mips64vr5000") == 0)
mips_cpu = 5000;
- /* start-sanitize-vr5400 */
- else if (strcmp (cpu, "r5400") == 0
- || strcmp (cpu, "mips64vr5400") == 0)
- mips_cpu = 5400;
- /* end-sanitize-vr5400 */
- /* start-sanitize-r5900 */
- else if (strcmp (cpu, "r5900") == 0
- || strcmp (cpu, "mips64r5900") == 0)
- mips_cpu = 5900;
- /* end-sanitize-r5900 */
else if (strcmp (cpu, "r8000") == 0
|| strcmp (cpu, "mips4") == 0)
mips_cpu = 3000;
}
+ if (mips_cpu == 3000
+ || mips_cpu == 3900)
+ mips_isa_from_cpu = 1;
+
+ else if (mips_cpu == 6000
+ || mips_cpu == 4010)
+ mips_isa_from_cpu = 2;
+
+ else if (mips_cpu == 4000
+ || mips_cpu == 4100
+ || mips_cpu == 4111
+ || mips_cpu == 4400
+ || mips_cpu == 4300
+ || mips_cpu == 4600
+ || mips_cpu == 4650)
+ mips_isa_from_cpu = 3;
+
+ else if (mips_cpu == 5000
+ || mips_cpu == 8000
+ || mips_cpu == 10000)
+ mips_isa_from_cpu = 4;
+
+ else
+ mips_isa_from_cpu = -1;
+
if (mips_opts.isa == -1)
{
- if (mips_cpu == 3000
- || mips_cpu == 3900)
- mips_opts.isa = 1;
-
- else if (mips_cpu == 6000
- || mips_cpu == 4010)
- mips_opts.isa = 2;
-
- else if (mips_cpu == 4000
- || mips_cpu == 4100
- || mips_cpu == 4400
- || mips_cpu == 4300
- /* start-sanitize-vr4320 */
- || mips_cpu == 4320
- /* end-sanitize-vr4320 */
- || mips_cpu == 4600
- /* start-sanitize-tx49 */
- || mips_cpu == 4900
- /* end-sanitize-tx49 */
- /* start-sanitize-r5900 */
- || mips_cpu == 5900
- /* end-sanitize-r5900 */
- || mips_cpu == 4650)
- mips_opts.isa = 3;
-
- else if (mips_cpu == 5000
- /* start-sanitize-vr5400 */
- || mips_cpu == 5400
- /* end-sanitize-vr5400 */
- || mips_cpu == 8000
- || mips_cpu == 10000)
- mips_opts.isa = 4;
-
+ if (mips_isa_from_cpu != -1)
+ mips_opts.isa = mips_isa_from_cpu;
else
- mips_opts.isa = 1;
+ mips_opts.isa = 1;
}
if (mips_opts.mips16 < 0)
mips_opts.mips16 = 0;
}
- if (mips_4650 < 0)
- mips_4650 = (mips_cpu == 4650);
-
- if (mips_4010 < 0)
- mips_4010 = (mips_cpu == 4010);
-
- if (mips_4100 < 0)
- mips_4100 = (mips_cpu == 4100);
-
- /* start-sanitize-vr4320 */
- if (mips_4320 < 0)
- mips_4320 = (mips_cpu == 4320);
-
- /* end-sanitize-vr4320 */
- /* start-sanitize-vr5400 */
- if (mips_5400 < 0)
- mips_5400 = (mips_cpu == 5400);
- /* end-sanitize-vr5400 */
-
- /* start-sanitize-r5900 */
- if (mips_5900 < 0)
- mips_5900 = (mips_cpu == 5900);
- /* end-sanitize-r5900 */
-
- if (mips_3900 < 0)
- mips_3900 = (mips_cpu == 3900);
-
- /* start-sanitize-tx49 */
- if (mips_4900 < 0)
- mips_4900 = (mips_cpu == 4900);
-
- /* end-sanitize-tx49 */
-
/* End of TARGET_CPU processing, get rid of malloced memory
if necessary. */
cpu = NULL;
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 (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
+ && ! ISA_HAS_64BIT_REGS (mips_opts.isa)
+ && ISA_HAS_64BIT_REGS (mips_isa_from_cpu))
+ mips_32bitmode = 1;
}
else
{
(void) bfd_set_section_alignment (stdoutput, sec, 2);
}
+#ifdef MIPS_STABS_ELF
+ pdr_seg = subseg_new (".pdr", (subsegT) 0);
+ (void) bfd_set_section_flags (stdoutput, pdr_seg,
+ SEC_READONLY | SEC_RELOC | SEC_DEBUGGING);
+ (void) bfd_set_section_alignment (stdoutput, pdr_seg, 2);
+#endif
+
subseg_set (seg, subseg);
}
}
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))))
if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
S_SET_OTHER (l->label, STO_MIPS16);
#endif
- if ((l->label->sy_value.X_add_number & 1) == 0)
- ++l->label->sy_value.X_add_number;
+ if ((S_GET_VALUE (l->label) & 1) == 0)
+ S_SET_VALUE (l->label, S_GET_VALUE (l->label) + 1);
}
}
}
/* 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
current instruction writes to the LO register, we must
- insert two NOPS. Some newer processors have interlocks. */
- if (! hilo_interlocks
+ insert two NOPS. Some newer processors have interlocks.
+ Also the tx39's multiply instructions can be exectuted
+ immediatly after a read from HI/LO (without the delay),
+ though the tx39's divide insns still do require the
+ delay. */
+ if (! (hilo_interlocks
+ || (mips_cpu == 3900 && (pinfo & INSN_MULT)))
&& (mips_optimize == 0
|| (pinfo & INSN_WRITE_LO)))
nops += 2;
+ /* Most mips16 branch insns don't have a delay slot.
+ If a read from LO is immediately followed by a branch
+ to a write to LO we have a read followed by a write
+ less than 2 insns away. We assume the target of
+ a branch might be a write to LO, and insert a nop
+ between a read and an immediately following branch. */
+ else if (mips_opts.mips16
+ && (mips_optimize == 0
+ || (pinfo & MIPS16_INSN_BRANCH)))
+ nops += 1;
}
else if (prev_insn.insn_mo->pinfo & INSN_READ_HI)
{
/* The previous instruction reads the HI register; if the
current instruction writes to the HI register, we must
- insert a NOP. Some newer processors have interlocks. */
- if (! hilo_interlocks
+ insert a NOP. Some newer processors have interlocks.
+ Also the note tx39's multiply above. */
+ if (! (hilo_interlocks
+ || (mips_cpu == 3900 && (pinfo & INSN_MULT)))
&& (mips_optimize == 0
|| (pinfo & INSN_WRITE_HI)))
nops += 2;
+ /* Most mips16 branch insns don't have a delay slot.
+ If a read from HI is immediately followed by a branch
+ to a write to HI we have a read followed by a write
+ less than 2 insns away. We assume the target of
+ a branch might be a write to HI, and insert a nop
+ between a read and an immediately following branch. */
+ else if (mips_opts.mips16
+ && (mips_optimize == 0
+ || (pinfo & MIPS16_INSN_BRANCH)))
+ nops += 1;
}
/* If the previous instruction was in a noreorder section, then
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)
&& ! cop_interlocks)
|| ((prev_prev_insn.insn_mo->pinfo & INSN_READ_LO)
&& (pinfo & INSN_WRITE_LO)
- && ! hilo_interlocks)
+ && ! (hilo_interlocks
+ || (mips_cpu == 3900 && (pinfo & INSN_MULT))))
|| ((prev_prev_insn.insn_mo->pinfo & INSN_READ_HI)
&& (pinfo & INSN_WRITE_HI)
- && ! hilo_interlocks))
+ && ! (hilo_interlocks
+ || (mips_cpu == 3900 && (pinfo & INSN_MULT)))))
prev_prev_nop = 1;
else
prev_prev_nop = 0;
for (l = insn_labels; l != NULL; l = l->next)
{
assert (S_GET_SEGMENT (l->label) == now_seg);
- l->label->sy_frag = frag_now;
+ symbol_set_frag (l->label, frag_now);
S_SET_VALUE (l->label, (valueT) frag_now_fix ());
/* mips16 text labels are stored as odd. */
if (mips_opts.mips16)
- ++l->label->sy_value.X_add_number;
+ S_SET_VALUE (l->label, S_GET_VALUE (l->label) + 1);
}
#ifndef NO_ECOFF_DEBUGGING
| ((address_expr->X_add_number & 0x3fffc) >> 2));
break;
- /* start-sanitize-r5900 */
- case BFD_RELOC_MIPS15_S3:
- ip->insn_opcode |= ((imm_expr.X_add_number & 0x7fff) >> 3) << 6;
- break;
- /* end-sanitize-r5900 */
case BFD_RELOC_16_PCREL_S2:
goto need_reloc;
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
| INSN_COPROC_MOVE_DELAY
| INSN_WRITE_COND_CODE)))
- || (! hilo_interlocks
+ || (! (hilo_interlocks
+ || (mips_cpu == 3900 && (pinfo & INSN_MULT)))
&& (prev_pinfo
& (INSN_READ_LO
| INSN_READ_HI)))
&& ! 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
/* If the previous instruction had a fixup in mips16
mode, we can not swap. This normally means that the
previous instruction was a 4 byte branch anyhow. */
- || (mips_opts.mips16 && prev_insn_fixp))
+ || (mips_opts.mips16 && prev_insn_fixp)
+ /* If the previous instruction is a sync, sync.l, or
+ sync.p, we can not swap. */
+ || (prev_pinfo & INSN_SYNC))
{
/* We could do even better for unconditional branches to
portions of this object file; we could pick up the
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
for (l = insn_labels; l != NULL; l = l->next)
{
assert (S_GET_SEGMENT (l->label) == now_seg);
- l->label->sy_frag = frag_now;
+ symbol_set_frag (l->label, frag_now);
S_SET_VALUE (l->label, (valueT) frag_now_fix ());
/* mips16 text labels are stored as odd. */
if (mips_opts.mips16)
- ++l->label->sy_value.X_add_number;
+ S_SET_VALUE (l->label, S_GET_VALUE (l->label) + 1);
}
}
}
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_4650
- && (insn.insn_mo->membership & INSN_4650) != 0)
- || (mips_4010
- && (insn.insn_mo->membership & INSN_4010) != 0)
- || (mips_4100
- && (insn.insn_mo->membership & INSN_4100) != 0)
- /* start-sanitize-vr4320 */
- || (mips_4320
- && (insn.insn_mo->membership & INSN_4320) != 0)
- /* end-sanitize-vr4320 */
- /* start-sanitize-tx49 */
- || (mips_4900
- && (insn.insn_mo->membership & INSN_4900) != 0)
- /* end-sanitize-tx49 */
- /* start-sanitize-r5900 */
- || (mips_5900
- && (insn.insn_mo->membership & INSN_5900) != 0)
- /* end-sanitize-r5900 */
- /* start-sanitize-vr5400 */
- || (mips_5400
- && (insn.insn_mo->membership & INSN_5400) != 0)
- /* end-sanitize-vr5400 */
- || (mips_3900
- && (insn.insn_mo->membership & INSN_3900) != 0))
- /* start-sanitize-r5900 */
- && (! mips_5900 || (insn.insn_mo->pinfo & FP_D) == 0)
- /* end-sanitize-r5900 */
- && (! mips_4650 || (insn.insn_mo->pinfo & FP_D) == 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;
++insn.insn_mo;
|| 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)
{
static void
mips16_macro_build (place, counter, ep, name, fmt, args)
char *place;
- int *counter;
+ int *counter ATTRIBUTE_UNUSED;
expressionS *ep;
const char *name;
const char *fmt;
|| ! 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);
}
int tempreg;
int mask;
int icnt = 0;
- int used_at;
+ int used_at = 0;
expressionS expr1;
const char *s;
const char *s2;
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;
if (mips_trap)
macro_build ((char *) NULL, &icnt, NULL, "teq", "s,t", 0, 0);
else
- /* start-sanitize-r5900 */
- if (mips_5900)
- macro_build ((char *) NULL, &icnt, NULL, "break", "B", 7);
- else
- /* end-sanitize-r5900 */
macro_build ((char *) NULL, &icnt, NULL, "break", "c", 7);
return;
}
macro_build ((char *) NULL, &icnt, NULL,
dbl ? "ddiv" : "div",
"z,s,t", sreg, treg);
- /* start-sanitize-r5900 */
- if (mips_5900)
- macro_build ((char *) NULL, &icnt, NULL, "break", "B", 7);
- else
- /* end-sanitize-r5900 */
macro_build ((char *) NULL, &icnt, NULL, "break", "c", 7);
}
expr1.X_add_number = -1;
that later insns are available for delay slot filling. */
--mips_opts.noreorder;
- /* start-sanitize-r5900 */
- if (mips_5900)
- macro_build ((char *) NULL, &icnt, NULL, "break", "B", 6);
- else
- /* end-sanitize-r5900 */
macro_build ((char *) NULL, &icnt, NULL, "break", "c", 6);
}
macro_build ((char *) NULL, &icnt, NULL, s, "d", dreg);
if (mips_trap)
macro_build ((char *) NULL, &icnt, NULL, "teq", "s,t", 0, 0);
else
- /* start-sanitize-r5900 */
- if (mips_5900)
- macro_build ((char *) NULL, &icnt, NULL, "break", "B", 7);
- else
- /* end-sanitize-r5900 */
macro_build ((char *) NULL, &icnt, NULL, "break", "c", 7);
return;
}
/* We want to close the noreorder block as soon as possible, so
that later insns are available for delay slot filling. */
--mips_opts.noreorder;
- /* start-sanitize-r5900 */
- if (mips_5900)
- macro_build ((char *) NULL, &icnt, NULL, "break", "B", 7);
- else
- /* end-sanitize-r5900 */
macro_build ((char *) NULL, &icnt, NULL, "break", "c", 7);
}
macro_build ((char *) NULL, &icnt, NULL, s2, "d", dreg);
/* 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
- && (offset_expr.X_op_symbol->sy_value.X_op == O_constant
- ? S_GET_SEGMENT (offset_expr.X_op_symbol) == text_section
- : (offset_expr.X_op_symbol->sy_value.X_op == O_symbol
- && (S_GET_SEGMENT (offset_expr.X_op_symbol
- ->sy_value.X_add_symbol)
- == text_section)))
+ && (symbol_constant_p (offset_expr.X_op_symbol)
+ ? 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)
+ == 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);
lr = 1;
goto ld;
case M_LDC1_AB:
- if (mips_4650)
+ if (mips_cpu == 4650)
{
as_bad (_("opcode not supported on this processor"));
return;
s = "scd";
goto st;
case M_SDC1_AB:
- if (mips_4650)
+ if (mips_cpu == 4650)
{
as_bad (_("opcode not supported on this processor"));
return;
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);
}
case M_L_DOB:
- if (mips_4650)
+ if (mips_cpu == 4650)
{
as_bad (_("opcode not supported on this processor"));
return;
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);
* But, the resulting address is the same after relocation so why
* generate the extra instruction?
*/
- if (mips_4650)
+ if (mips_cpu == 4650)
{
as_bad (_("opcode not supported on this processor"));
return;
}
/* Itbl support may require additional care here. */
coproc = 1;
- if (mips_opts.isa >= 2)
+ if (mips_opts.isa != 1)
{
s = "ldc1";
goto ld;
goto ldd_std;
case M_S_DAB:
- if (mips_4650)
+ if (mips_cpu == 4650)
{
as_bad (_("opcode not supported on this processor"));
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;
expr1.X_add_number = 8;
macro_build ((char *) NULL, &icnt, &expr1, "beq", "s,t,p", dreg, AT);
macro_build ((char *) NULL, &icnt, NULL, "nop", "", 0);
- /* start-sanitize-r5900 */
- if (mips_5900)
- macro_build ((char *) NULL, &icnt, NULL, "break", "B", 6);
- else
- /* end-sanitize-r5900 */
macro_build ((char *) NULL, &icnt, NULL, "break", "c", 6);
}
--mips_opts.noreorder;
expr1.X_add_number = 8;
macro_build ((char *) NULL, &icnt, &expr1, "beq", "s,t,p", AT, 0);
macro_build ((char *) NULL, &icnt, NULL, "nop", "", 0);
- /* start-sanitize-r5900 */
- if (mips_5900)
- macro_build ((char *) NULL, &icnt, NULL, "break", "B", 6);
- else
- /* end-sanitize-r5900 */
macro_build ((char *) NULL, &icnt, NULL, "break", "c", 6);
}
--mips_opts.noreorder;
break;
case M_S_DOB:
- if (mips_4650)
+ if (mips_cpu == 4650)
{
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);
&& imm_expr.X_add_number >= -0x8000
&& imm_expr.X_add_number < 0x8000)
{
- macro_build ((char *) NULL, &icnt, &expr1,
+ macro_build ((char *) NULL, &icnt, &imm_expr,
mask == M_SGE_I ? "slti" : "sltiu",
"t,r,j", dreg, sreg, (int) BFD_RELOC_LO16);
used_at = 0;
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;
macro_build ((char *) NULL, &icnt, NULL, s, "s,t", sreg, AT);
break;
- case M_TRUNCWD:
case M_TRUNCWS:
- assert (mips_opts.isa < 2);
+ case M_TRUNCWD:
+ 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)
"0,x,y", xreg, yreg);
expr1.X_add_number = 2;
macro_build ((char *) NULL, &icnt, &expr1, "bnez", "x,p", yreg);
- /* start-sanitize-r5900 */
- if (mips_5900)
- macro_build ((char *) NULL, &icnt, NULL, "break", "B", 7);
- else
- /* end-sanitize-r5900 */
macro_build ((char *) NULL, &icnt, NULL, "break", "6", 7);
/* FIXME: The normal code checks for of -1 / -0x80000000 here,
macro_build ((char *) NULL, &icnt, NULL, s, "0,x,y", xreg, yreg);
expr1.X_add_number = 2;
macro_build ((char *) NULL, &icnt, &expr1, "bnez", "x,p", yreg);
- /* start-sanitize-r5900 */
- if (mips_5900)
- macro_build ((char *) NULL, &icnt, NULL, "break", "B", 7);
- else
- /* end-sanitize-r5900 */
macro_build ((char *) NULL, &icnt, NULL, "break", "6", 7);
--mips_opts.noreorder;
macro_build ((char *) NULL, &icnt, NULL, s2, "x", zreg);
case 'x': break;
case 'z': break;
case 'P': USE_BITS (OP_MASK_PERFREG, OP_SH_PERFREG); break;
- /* start-sanitize-r5900 */
- case '0': USE_BITS (OP_MASK_VADDI, OP_SH_VADDI); break;
- case '1': USE_BITS (OP_MASK_VUTREG, OP_SH_VUTREG); break;
- case '2': USE_BITS (OP_MASK_VUSREG, OP_SH_VUSREG); break;
- case '3': USE_BITS (OP_MASK_VUDREG, OP_SH_VUDREG); break;
- case '4': USE_BITS (OP_MASK_VUTREG, OP_SH_VUTREG); break;
- case '5': USE_BITS (OP_MASK_VUSREG, OP_SH_VUSREG); break;
- case '6': USE_BITS (OP_MASK_VUDREG, OP_SH_VUDREG); break;
- case '7':
- USE_BITS (OP_MASK_VUTREG, OP_SH_VUTREG);
- USE_BITS (OP_MASK_VUFTF, OP_SH_VUFTF);
- break;
- case '8':
- USE_BITS (OP_MASK_VUSREG, OP_SH_VUSREG);
- USE_BITS (OP_MASK_VUFSF, OP_SH_VUFSF);
- break;
- case '9': break;
- case 'K': break;
- case 'X': break;
- case 'U': break;
- case 'Q': break;
- case 'J': break;
- case 'O': USE_BITS (OP_MASK_VUCALLMS, OP_SH_VUCALLMS);break;
- case '&': USE_BITS (OP_MASK_VUDEST, OP_SH_VUDEST); break;
- case ';': break;
- case '#':
- p++;
- break;
- case '-': break;
- case '+': break;
- /* end-sanitize-r5900 */
- /* start-sanitize-vr5400 */
- case 'e': USE_BITS (OP_MASK_VECBYTE, OP_SH_VECBYTE); break;
- case '%': USE_BITS (OP_MASK_VECALIGN, OP_SH_VECALIGN); break;
- case '[': break;
- case ']': break;
- /* end-sanitize-vr5400 */
default:
as_bad (_("internal: bad mips opcode (unknown operand type `%c'): %s %s"),
c, opc->name, opc->args);
{
char *s;
const char *args;
- char c;
+ char c = 0;
struct mips_opcode *insn;
char *argsStart;
unsigned int regno;
/* If the instruction contains a '.', we first try to match an instruction
including the '.'. Then we try again without the '.'. */
insn = NULL;
- for (s = str; *s != '\0' && !isspace(*s); ++s)
+ for (s = str; *s != '\0' && !isspace ((unsigned char) *s); ++s)
continue;
/* If we stopped on whitespace, then replace the whitespace with null for
the call to hash_find. Save the character we replaced just in case we
have to re-parse the instruction. */
- if (isspace (*s))
+ if (isspace ((unsigned char) *s))
{
save_c = *s;
*s++ = '\0';
*(--s) = save_c;
/* Scan up to the first '.' or whitespace. */
- for (s = str; *s != '\0' && *s != '.' && !isspace (*s); ++s)
+ for (s = str; *s != '\0' && *s != '.' && !isspace ((unsigned char) *s); ++s)
continue;
/* If we did not find a '.', then we can quit now. */
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)
+ else
ok = false;
- else if ((mips_4650 && (insn->membership & INSN_4650) != 0)
- || (mips_4010 && (insn->membership & INSN_4010) != 0)
- || (mips_4100 && (insn->membership & INSN_4100) != 0)
- /* start-sanitize-vr4320 */
- || (mips_4320 && (insn->membership & INSN_4320) != 0)
- /* end-sanitize-vr4320 */
- /* start-sanitize-tx49 */
- || (mips_4900 && (insn->membership & INSN_4900) != 0)
- /* end-sanitize-tx49 */
- /* start-sanitize-r5900 */
- || (mips_5900 && (insn->membership & INSN_5900) != 0)
- /* end-sanitize-r5900 */
- /* start-sanitize-vr5400 */
- || (mips_5400 && (insn->membership & INSN_5400) != 0)
- /* end-sanitize-vr5400 */
- || (mips_3900 && (insn->membership & INSN_3900) != 0))
- ok = true;
- else
- ok = false;
-
+
if (insn->pinfo != INSN_MACRO)
{
- if (mips_4650 && (insn->pinfo & FP_D) != 0)
- ok = false;
- /* start-sanitize-r5900 */
- if (mips_5900 && (insn->pinfo & FP_D) != 0)
+ if (mips_cpu == 4650 && (insn->pinfo & FP_D) != 0)
ok = false;
- /* end-sanitize-r5900 */
}
if (! ok)
++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;
return;
case ')': /* these must match exactly */
- /* start-sanitize-vr5400 */
- case '[':
- case ']':
- /* end-sanitize-vr5400 */
- /* start-sanitize-r5900 */
- case '-':
- case '+':
- /* end-sanitize-r5900 */
if (*s++ == *args)
continue;
break;
s = expr_end;
continue;
- /* start-sanitize-r5900 */
- case '0': /* 5 bit signed immediate at 6 */
- my_getExpression (&imm_expr, s);
- check_absolute_expr (ip, &imm_expr);
- if ((c == '\0' && imm_expr.X_op != O_constant)
- || ((imm_expr.X_add_number < -16
- || imm_expr.X_add_number >= 16)
- && imm_expr.X_op == O_constant))
- {
- if (imm_expr.X_op != O_constant
- && imm_expr.X_op != O_big)
- insn_error = "absolute expression required";
- else
- as_bad (_("5 bit expression not in range -16..15"));
- }
- ip->insn_opcode |= (imm_expr.X_add_number) << 6;
- imm_expr.X_op = O_absent;
- s = expr_end;
- continue;
-
- case '9': /* vi27 for vcallmsr */
- if (strncmp (s, "vi27", 4) == 0)
- s += 4;
- else
- as_bad (_("expected vi27"));
- continue;
-
- case '#': /* escape character */
- /* '#' specifies that we've got an optional suffix to this
- operand that must match exactly (if it exists). */
- if (*s != '\0' && *s != ','
- && *s != ' ' && *s != '\t' && *s != '\n')
- {
- if (*s == *(args + 1))
- {
- s++;
- args++;
- continue;
- }
- break;
- }
- args++;
- continue;
-
- case 'K': /* DEST operand completer (optional), must
- match previous dest if specified. */
- case '&': /* DEST instruction completer */
- case ';': /* DEST instruction completer, must be xyz */
- {
- int w,x,y,z;
- static int last_h;
-
- w = x = y = z = 0;
-
- /* Parse the completer. */
- s_reset = s;
- while ((!full_opcode_match || *args == 'K')
- && *s != '\0' && *s != ' ' && *s != ',')
- {
- if (*s == 'w')
- w++;
- else if (*s == 'x')
- x++;
- else if (*s == 'y')
- y++;
- else if (*s == 'z')
- z++;
- else
- {
- insn_error = "Invalid dest specification";
- break;
- }
- s++;
- }
-
- if (insn_error)
- continue;
-
- /* Each completer can only appear once. */
- if (w > 1 || x > 1 || y > 1 || z > 1)
- {
- insn_error = "Invalid dest specification";
- continue;
- }
-
- /* If this is the opcode completer, then we must insert
- the appropriate value into the insn. */
- if (*args == '&')
- {
- /* Not strictly in the specs, but requested by users. */
- if (w == 0 && x == 0 && y == 0 && z == 0)
- w = x = y = z = 1;
-
- ip->insn_opcode |= ((w << 21) | (x << 24)
- | (y << 23) | (z << 22));
- last_h = (w << 3) | (x << 0) | (y << 1) | (z << 2);
- }
- else if (*args == ';')
- {
- /* This implicitly has the .xyz completer. */
- if (w == 0 && x == 0 && y == 0 && z == 0)
- x = y = z = 1;
-
- if (w != 0 || x != 1 || y != 1 || z != 1)
- {
- insn_error = "Invalid dest specification";
- continue;
- }
-
- last_h = (w << 3) | (x << 0) | (y << 1) | (z << 2);
- }
- else
- {
- int temp;
-
- /* This is the operand completer, make sure it matches
- the previous opcode completer. */
- temp = (w << 3) | (x << 0) | (y << 1) | (z << 2);
- if (temp && temp != last_h)
- {
- insn_error = "DEST field in operand does not match DEST field in instruction";
- continue;
- }
-
- }
-
- continue;
- }
-
- case 'J': /* vu0 I register */
- if (s[0] == 'I')
- s += 1;
- else
- insn_error = "operand `I' expected";
- continue;
-
- case 'Q': /* vu0 Q register */
- if (s[0] == 'Q')
- s += 1;
- else
- insn_error = "operand `Q' expected";
- continue;
-
- case 'X': /* vu0 R register */
- if (s[0] == 'R')
- s += 1;
- else
- insn_error = "operand `R' expected";
- continue;
-
- case 'U': /* vu0 ACC register */
- if (s[0] == 'A' && s[1] == 'C' && s[2] == 'C')
- s += 3;
- else
- insn_error = "operand `ACC' expected";
- continue;
-
- case 'O':
- my_getSmallExpression (&imm_expr, s);
- imm_reloc = BFD_RELOC_MIPS15_S3;
- s = expr_end;
- continue;
- /* end-sanitize-r5900 */
case 'k': /* cache code */
case 'h': /* prefx code */
s_reset = s;
if (s[0] == '$')
{
- if (isdigit (s[1]))
+
+ if (isdigit ((unsigned char) s[1]))
{
++s;
regno = 0;
regno += *s - '0';
++s;
}
- while (isdigit (*s));
+ while (isdigit ((unsigned char) *s));
if (regno > 31)
as_bad (_("Invalid register number (%d)"), regno);
}
else if (itbl_have_entries)
{
char *p, *n;
- int r;
+ unsigned long r;
- p = s+1; /* advance past '$' */
+ p = s + 1; /* advance past '$' */
n = itbl_get_field (&p); /* n is name */
- /* See if this is a register defined in an
- itbl entry */
- r = itbl_get_reg_val (n);
- if (r)
+ /* See if this is a register defined in an
+ itbl entry. */
+ if (itbl_get_reg_val (n, &r))
{
/* Get_field advances to the start of
the next field, so we need to back
- rack to the end of the last field. */
+ rack to the end of the last field. */
if (p)
s = p - 1;
else
- s = strchr (s,'\0');
+ s = strchr (s, '\0');
regno = r;
}
else
case 'R': /* floating point source register */
case 'V':
case 'W':
- /* start-sanitize-r5900 */
- case '1': /* vu0 fp reg position 1 */
- case '2': /* vu0 fp reg position 2 */
- case '3': /* vu0 fp reg position 3 */
- case '4': /* vu0 int reg position 1 */
- case '5': /* vu0 int reg position 2 */
- case '6': /* vu0 int reg position 3 */
- case '7': /* vu0 fp reg with ftf modifier */
- case '8': /* vu0 fp reg with fsf modifier */
- /* end-sanitize-r5900 */
s_reset = s;
- if (s[0] == '$' && s[1] == 'f' && isdigit (s[2]))
+ if (s[0] == '$' && s[1] == 'f' && isdigit ((unsigned char) s[2]))
{
s += 2;
regno = 0;
regno += *s - '0';
++s;
}
- while (isdigit (*s));
+ while (isdigit ((unsigned char) *s));
if (regno > 31)
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
continue;
}
- /* start-sanitize-r5900 */
- /* Handle vf and vi regsiters for vu0. */
- if (s[0] == 'v'
- && (s[1] == 'f' || s[1] == 'i')
- && isdigit (s[2]))
- {
- s += 2;
- regno = 0;
- do
- {
- regno *= 10;
- regno += *s - '0';
- ++s;
- }
- while (isdigit (*s));
-
- if (regno > 31)
- as_bad (_("Invalid vu0 register number (%d)"), regno);
-
- c = *args;
-
- if (c == '7' || c == '8')
- {
- int value;
-
- switch (*s)
- {
- case 'w':
- value = 3;
- s++;
- ip->insn_opcode |= value << (c == '7' ? 23 : 21);
- break;
- case 'x':
- value = 0;
- s++;
- ip->insn_opcode |= value << (c == '7' ? 23 : 21);
- break;
- case 'y':
- value = 1;
- s++;
- ip->insn_opcode |= value << (c == '7' ? 23 : 21);
- break;
- case 'z':
- value = 2;
- s++;
- ip->insn_opcode |= value << (c == '7' ? 23 : 21);
- break;
- default:
- as_bad (_("Invalid FSF/FTF specification"));
- }
- }
-
- if (*s == ' ')
- s++;
- if (args[1] != *s)
- {
- if (c == 'V' || c == 'W')
- {
- regno = lastregno;
- s = s_reset;
- args++;
- }
- }
- switch (c)
- {
- case '1':
- case '4':
- case '7':
- ip->insn_opcode |= regno << 16;
- break;
- case '2':
- case '5':
- case '8':
- ip->insn_opcode |= regno << 11;
- break;
- case '3':
- case '6':
- ip->insn_opcode |= regno << 6;
- break;
- }
- lastregno = regno;
- continue;
- }
- /* end-sanitize-r5900 */
switch (*args++)
{
imm_expr.X_add_number = bfd_getb32 (temp);
}
else if (length > 4
+ && ! mips_disable_float_construction
&& ((temp[0] == 0 && temp[1] == 0)
|| (temp[2] == 0 && temp[3] == 0))
&& ((temp[4] == 0 && temp[5] == 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
else
imm_reloc = BFD_RELOC_HI16;
}
+ else if (imm_expr.X_op == O_constant)
+ imm_expr.X_add_number &= 0xffff;
}
if (*args == 'i')
{
if (insn + 1 < &mips_opcodes[NUMOPCODES] &&
!strcmp (insn->name, insn[1].name))
break;
- if (imm_expr.X_op != O_constant
- && imm_expr.X_op != O_big)
- insn_error = _("absolute expression required");
- else
+ if (imm_expr.X_op == O_constant
+ || imm_expr.X_op == O_big)
as_bad (_("16 bit expression not in range 0..65535"));
}
}
&& 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))
{
if (more)
break;
- if (imm_expr.X_op != O_constant
- && imm_expr.X_op != O_big)
- insn_error = _("absolute expression required");
- else
+ if (imm_expr.X_op == O_constant
+ || imm_expr.X_op == O_big)
as_bad (_("16 bit expression not in range -32768..32767"));
}
}
|| 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;
- offset_reloc = BFD_RELOC_LO16;
if (c == 'h' || c == 'H')
{
- assert (offset_expr.X_op == O_constant);
+ if (offset_expr.X_op != O_constant)
+ break;
offset_expr.X_add_number =
(offset_expr.X_add_number >> 16) & 0xffff;
}
+ offset_reloc = BFD_RELOC_LO16;
s = expr_end;
continue;
case 'u': /* upper 16 bits */
c = my_getSmallExpression (&imm_expr, s);
- if (imm_expr.X_op == O_constant
- && (imm_expr.X_add_number < 0
- || imm_expr.X_add_number >= 0x10000))
- as_bad (_("lui expression not in range 0..65535"));
imm_reloc = BFD_RELOC_LO16;
if (c)
{
else
imm_reloc = BFD_RELOC_HI16;
}
+ else if (imm_expr.X_op == O_constant)
+ imm_expr.X_add_number &= 0xffff;
}
+ if (imm_expr.X_op == O_constant
+ && (imm_expr.X_add_number < 0
+ || imm_expr.X_add_number >= 0x10000))
+ as_bad (_("lui expression not in range 0..65535"));
s = expr_end;
continue;
regno += *s - '0';
++s;
}
- while (isdigit (*s));
+ while (isdigit ((unsigned char) *s));
if (regno > 7)
as_bad (_("invalid condition code register $fcc%d"), regno);
if (*args == 'N')
ip->insn_opcode |= regno << OP_SH_CCC;
continue;
- /* start-sanitize-vr5400 */
- case 'e': /* must be at least one digit */
- my_getExpression (&imm_expr, s);
- check_absolute_expr (ip, &imm_expr);
- if ((unsigned long) imm_expr.X_add_number > (unsigned long) OP_MASK_VECBYTE)
- {
- as_bad (_("bad byte vector index (%ld)"),
- (long) imm_expr.X_add_number);
- imm_expr.X_add_number = imm_expr.X_add_number;
- }
- ip->insn_opcode |= imm_expr.X_add_number << OP_SH_VECBYTE;
- imm_expr.X_op = O_absent;
- s = expr_end;
- continue;
-
- case '%':
- my_getExpression (&imm_expr, s);
- check_absolute_expr (ip, &imm_expr);
- if ((unsigned long) imm_expr.X_add_number > (unsigned long) OP_MASK_VECALIGN)
- {
- as_bad (_("bad byte vector index (%ld)"),
- (long) imm_expr.X_add_number);
- imm_expr.X_add_number = imm_expr.X_add_number;
- }
- ip->insn_opcode |= imm_expr.X_add_number << OP_SH_VECALIGN;
- imm_expr.X_op = O_absent;
- s = expr_end;
- continue;
-
- /* end-sanitize-vr5400 */
default:
as_bad (_("bad char = '%c'\n"), *args);
internalError ();
mips16_small = false;
mips16_ext = false;
- for (s = str; islower (*s); ++s)
+ for (s = str; islower ((unsigned char) *s); ++s)
;
switch (*s)
{
if (s[0] != '$')
break;
s_reset = s;
- if (isdigit (s[1]))
+ if (isdigit ((unsigned char) s[1]))
{
++s;
regno = 0;
regno += *s - '0';
++s;
}
- while (isdigit (*s));
+ while (isdigit ((unsigned char) *s));
if (regno > 31)
{
as_bad (_("invalid register number (%d)"), regno);
++s;
}
reg1 = 0;
- while (isdigit (*s))
+ while (isdigit ((unsigned char) *s))
{
reg1 *= 10;
reg1 += *s - '0';
}
}
reg2 = 0;
- while (isdigit (*s))
+ while (isdigit ((unsigned char) *s))
{
reg2 *= 10;
reg2 += *s - '0';
;
if (sp - 4 >= str && sp[-1] == RP)
{
- if (isdigit (sp[-2]))
+ if (isdigit ((unsigned char) sp[-2]))
{
- for (sp -= 3; sp >= str && isdigit (*sp); sp--)
+ for (sp -= 3; sp >= str && isdigit ((unsigned char) *sp); sp--)
;
if (*sp == '$' && sp > str && sp[-1] == LP)
{
&& ep->X_op == O_symbol
&& strcmp (S_GET_NAME (ep->X_add_symbol), FAKE_LABEL_NAME) == 0
&& S_GET_SEGMENT (ep->X_add_symbol) == now_seg
- && ep->X_add_symbol->sy_frag == frag_now
- && ep->X_add_symbol->sy_value.X_op == O_constant
- && ep->X_add_symbol->sy_value.X_add_number == frag_now_fix ())
- ++ep->X_add_symbol->sy_value.X_add_number;
+ && symbol_get_frag (ep->X_add_symbol) == frag_now
+ && symbol_constant_p (ep->X_add_symbol)
+ && S_GET_VALUE (ep->X_add_symbol) == frag_now_fix ())
+ S_SET_VALUE (ep->X_add_symbol, S_GET_VALUE (ep->X_add_symbol) + 1);
}
/* Turn a string in input_line_pointer into a floating point constant
- of type type, and store the appropriate bytes in *litP. The number
- of LITTLENUMS emitted is stored in *sizeP . An error message is
+ of type TYPE, and store the appropriate bytes in *LITP. The number
+ of LITTLENUMS emitted is stored in *SIZEP. An error message is
returned, or NULL on OK. */
char *
{"mcpu", required_argument, NULL, OPTION_MCPU},
#define OPTION_MEMBEDDED_PIC (OPTION_MD_BASE + 6)
{"membedded-pic", no_argument, NULL, OPTION_MEMBEDDED_PIC},
+
+#define OPTION_CALL_SHARED (OPTION_MD_BASE + 7)
+#define OPTION_NON_SHARED (OPTION_MD_BASE + 8)
+
#define OPTION_TRAP (OPTION_MD_BASE + 9)
{"trap", no_argument, NULL, OPTION_TRAP},
{"no-break", no_argument, NULL, OPTION_TRAP},
{"m4100", no_argument, NULL, OPTION_M4100},
#define OPTION_NO_M4100 (OPTION_MD_BASE + 18)
{"no-m4100", no_argument, NULL, OPTION_NO_M4100},
+
+#define OPTION_XGOT (OPTION_MD_BASE + 19)
+#define OPTION_32 (OPTION_MD_BASE + 20)
+#define OPTION_64 (OPTION_MD_BASE + 21)
+
#define OPTION_MIPS16 (OPTION_MD_BASE + 22)
{"mips16", no_argument, NULL, OPTION_MIPS16},
#define OPTION_NO_MIPS16 (OPTION_MD_BASE + 23)
{"no-mips16", no_argument, NULL, OPTION_NO_MIPS16},
- /* start-sanitize-r5900 */
-#define OPTION_M5900 (OPTION_MD_BASE + 24)
- {"m5900", no_argument, NULL, OPTION_M5900},
-#define OPTION_NO_M5900 (OPTION_MD_BASE + 25)
- {"no-m5900", no_argument, NULL, OPTION_NO_M5900},
- /* end-sanitize-r5900 */
+
#define OPTION_M3900 (OPTION_MD_BASE + 26)
{"m3900", no_argument, NULL, OPTION_M3900},
#define OPTION_NO_M3900 (OPTION_MD_BASE + 27)
{"no-m3900", no_argument, NULL, OPTION_NO_M3900},
- /* start-sanitize-tx19 */
- {"m1900", no_argument, NULL, OPTION_M3900},
- {"no-m1900", no_argument, NULL, OPTION_NO_M3900},
- /* end-sanitize-tx19 */
-
- /* start-sanitize-vr5400 */
-#define OPTION_M5400 (OPTION_MD_BASE + 28)
- {"m5400", no_argument, NULL, OPTION_M5400},
-#define OPTION_NO_M5400 (OPTION_MD_BASE + 29)
- {"no-m5400", no_argument, NULL, OPTION_NO_M5400},
-
- /* end-sanitize-vr5400 */
- /* start-sanitize-tx49 */
-#define OPTION_M4900 (OPTION_MD_BASE + 30)
- {"m4900", no_argument, NULL, OPTION_M4900},
-#define OPTION_NO_M4900 (OPTION_MD_BASE + 31)
- {"no-m4900", no_argument, NULL, OPTION_NO_M4900},
-
- /* end-sanitize-tx49 */
- /* start-sanitize-vr4320 */
-#define OPTION_M4320 (OPTION_MD_BASE + 32)
- {"m4320", no_argument, NULL, OPTION_M4320},
-#define OPTION_NO_M4320 (OPTION_MD_BASE + 33)
- {"no-m4320", no_argument, NULL, OPTION_NO_M4320},
-
- /* end-sanitize-vr4320 */
-#define OPTION_CALL_SHARED (OPTION_MD_BASE + 7)
-#define OPTION_NON_SHARED (OPTION_MD_BASE + 8)
-#define OPTION_XGOT (OPTION_MD_BASE + 19)
-#define OPTION_32 (OPTION_MD_BASE + 20)
-#define OPTION_64 (OPTION_MD_BASE + 21)
+#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},
+
#ifdef OBJ_ELF
{"KPIC", no_argument, NULL, OPTION_CALL_SHARED},
{"xgot", no_argument, NULL, OPTION_XGOT},
{"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},
+
+#define OPTION_CONSTRUCT_FLOATS (OPTION_MD_BASE + 43)
+ {"construct-floats", no_argument, NULL, OPTION_CONSTRUCT_FLOATS},
+
+#define OPTION_NO_CONSTRUCT_FLOATS (OPTION_MD_BASE + 44)
+ {"no-construct-floats", no_argument, NULL, OPTION_NO_CONSTRUCT_FLOATS},
+
{NULL, no_argument, NULL, 0}
};
size_t md_longopts_size = sizeof(md_longopts);
{
switch (c)
{
+ case OPTION_CONSTRUCT_FLOATS:
+ mips_disable_float_construction = 0;
+ break;
+
+ case OPTION_NO_CONSTRUCT_FLOATS:
+ mips_disable_float_construction = 1;
+ break;
+
case OPTION_TRAP:
mips_trap = 1;
break;
|| strcmp (p, "10k") == 0
|| strcmp (p, "10K") == 0)
mips_cpu = 10000;
- /* start-sanitize-tx19 */
- else if (strcmp (p, "1900") == 0)
- mips_cpu = 3900;
- /* end-sanitize-tx19 */
break;
case '2':
mips_cpu = 4000;
else if (strcmp (p, "4100") == 0)
mips_cpu = 4100;
+ else if (strcmp (p, "4111") == 0)
+ mips_cpu = 4111;
else if (strcmp (p, "4300") == 0)
mips_cpu = 4300;
- /* start-sanitize-vr4320 */
- else if (strcmp (p, "4320") == 0)
- mips_cpu = 4320;
- /* end-sanitize-vr4320 */
else if (strcmp (p, "4400") == 0)
mips_cpu = 4400;
else if (strcmp (p, "4600") == 0)
mips_cpu = 4600;
else if (strcmp (p, "4650") == 0)
mips_cpu = 4650;
- /* start-sanitize-tx49 */
- else if (strcmp (p, "4900") == 0)
- mips_cpu = 4900;
- /* end-sanitize-tx49 */
else if (strcmp (p, "4010") == 0)
mips_cpu = 4010;
break;
|| strcmp (p, "5k") == 0
|| strcmp (p, "5K") == 0)
mips_cpu = 5000;
- /* start-sanitize-vr5400 */
- else if (strcmp (p, "5400") == 0)
- mips_cpu = 5400;
- /* end-sanitize-vr5400 */
- /* start-sanitize-r5900 */
- else if (strcmp (p, "5900") == 0)
- mips_cpu = 5900;
- /* end-sanitize-r5900 */
break;
case '6':
if (strcmp (p, "orion") == 0)
mips_cpu = 4600;
break;
- }
+ case 'm':
+ case 'M':
+ switch (atoi (p + 1))
+ {
+ case 5200:
+ case 5230:
+ case 5231:
+ case 5261:
+ case 5721:
+ case 7000:
+ mips_cpu = 5000;
+ break;
+ default:
+ break;
+ }
+ }
+
if (sv
&& (mips_cpu != 4300
&& mips_cpu != 4100
- /* start-sanitize-vr4320 */
- && mips_cpu != 4320
- /* end-sanitize-vr4320 */
- /* start-sanitize-vr5400 */
- && mips_cpu != 5400
- /* end-sanitize-vr5400 */
+ && mips_cpu != 4111
&& mips_cpu != 5000))
{
as_bad (_("ignoring invalid leading 'v' in -mcpu=%s switch"), arg);
break;
case OPTION_M4650:
- mips_4650 = 1;
+ mips_cpu = 4650;
break;
case OPTION_NO_M4650:
- mips_4650 = 0;
break;
case OPTION_M4010:
- mips_4010 = 1;
+ mips_cpu = 4010;
break;
case OPTION_NO_M4010:
- mips_4010 = 0;
break;
case OPTION_M4100:
- mips_4100 = 1;
+ mips_cpu = 4100;
break;
case OPTION_NO_M4100:
- mips_4100 = 0;
- break;
-
- /* start-sanitize-r5900 */
- case OPTION_M5900:
- mips_5900 = 1;
- break;
-
- case OPTION_NO_M5900:
- mips_5900 = 0;
break;
- /* end-sanitize-r5900 */
- /* start-sanitize-vr4320 */
- case OPTION_M4320:
- mips_4320 = 1;
- break;
-
- case OPTION_NO_M4320:
- mips_4320 = 0;
- break;
-
- /* end-sanitize-vr4320 */
- /* start-sanitize-vr5400 */
- case OPTION_M5400:
- mips_5400 = 1;
- break;
-
- case OPTION_NO_M5400:
- mips_5400 = 0;
- break;
- /* end-sanitize-vr5400 */
case OPTION_M3900:
- mips_3900 = 1;
+ mips_cpu = 3900;
break;
case OPTION_NO_M3900:
- mips_3900 = 0;
break;
- /* start-sanitize-tx49 */
- case OPTION_M4900:
- mips_4900 = 1;
- break;
-
- case OPTION_NO_M4900:
- mips_4900 = 0;
- break;
-
- /* end-sanitize-tx49 */
case OPTION_MIPS16:
mips_opts.mips16 = 1;
mips_no_prev_insn (false);
}
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
+ || strcmp (arg,"n32") == 0
+ || strcmp (arg,"64") == 0
+ || strcmp (arg,"o64") == 0
+ || strcmp (arg,"eabi") == 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;
}
return 1;
}
+
+static void
+show (stream, string, col_p, first_p)
+ FILE *stream;
+ char *string;
+ int *col_p;
+ int *first_p;
+{
+ if (*first_p)
+ {
+ fprintf (stream, "%24s", "");
+ *col_p = 24;
+ }
+ else
+ {
+ fprintf (stream, ", ");
+ *col_p += 2;
+ }
+
+ if (*col_p + strlen (string) > 72)
+ {
+ fprintf (stream, "\n%24s", "");
+ *col_p = 24;
+ }
+
+ fprintf (stream, "%s", string);
+ *col_p += strlen (string);
+
+ *first_p = 0;
+}
+
+
void
md_show_usage (stream)
FILE *stream;
{
+ int column, first;
+
fprintf(stream, _("\
MIPS options:\n\
-membedded-pic generate embedded position independent code\n\
-mips2 generate MIPS ISA II instructions\n\
-mips3 generate MIPS ISA III instructions\n\
-mips4 generate MIPS ISA IV instructions\n\
--mcpu=vr4300 generate code for vr4300\n\
--mcpu=vr4100 generate code for vr4100\n\
--m4650 permit R4650 instructions\n\
--no-m4650 do not permit R4650 instructions\n\
--m4010 permit R4010 instructions\n\
--no-m4010 do not permit R4010 instructions\n\
--m4100 permit VR4100 instructions\n\
--no-m4100 do not permit VR4100 instructions\n"));
+-mcpu=CPU generate code for CPU, where CPU is one of:\n"));
+
+ first = 1;
+
+ show (stream, "2000", &column, &first);
+ show (stream, "3000", &column, &first);
+ show (stream, "3900", &column, &first);
+ show (stream, "4000", &column, &first);
+ show (stream, "4010", &column, &first);
+ show (stream, "4100", &column, &first);
+ show (stream, "4111", &column, &first);
+ show (stream, "4300", &column, &first);
+ show (stream, "4400", &column, &first);
+ show (stream, "4600", &column, &first);
+ show (stream, "4650", &column, &first);
+ show (stream, "5000", &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\
+-no-mCPU don't generate code specific to CPU.\n\
+ For -mCPU and -no-mCPU, CPU must be one of:\n"));
+
+ first = 1;
+
+ show (stream, "3900", &column, &first);
+ show (stream, "4010", &column, &first);
+ show (stream, "4100", &column, &first);
+ show (stream, "4650", &column, &first);
+ fputc ('\n', stream);
+
fprintf(stream, _("\
-mips16 generate mips16 instructions\n\
-no-mips16 do not generate mips16 instructions\n"));
fprintf(stream, _("\
-O0 remove unneeded NOPs, do not swap branches\n\
-O remove unneeded NOPs and swap branches\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"));
#ifdef OBJ_ELF
void
cons_fix_new_mips (frag, where, nbytes, exp)
- fragS *frag;
+ fragS *frag ATTRIBUTE_UNUSED;
int where;
unsigned int nbytes;
expressionS *exp;
if (f != NULL)
break;
+#if 0 /* GCC code motion plus incomplete dead code elimination
+ can leave a %hi without a %lo. */
if (pass == 1)
as_warn_where (l->fixp->fx_file, l->fixp->fx_line,
_("Unmatched %%hi reloc"));
+#endif
}
}
}
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 \
mips_force_relocation (fixp)
fixS *fixp;
{
+ if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 1;
+
return (mips_pic == EMBEDDED_PIC
&& (fixp->fx_pcrel
|| SWITCH_TABLE (fixp)
assert (fixP->fx_size == 4
|| fixP->fx_r_type == BFD_RELOC_16
- || fixP->fx_r_type == BFD_RELOC_64);
+ || fixP->fx_r_type == BFD_RELOC_64
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY);
value = *valueP;
/* If we aren't adjusting this fixup to be against the section
symbol, we need to adjust the value. */
#ifdef OBJ_ELF
- if (fixP->fx_addsy != NULL
- && OUTPUT_FLAVOR == bfd_target_elf_flavour
- && (S_GET_OTHER (fixP->fx_addsy) == STO_MIPS16
- || S_IS_WEAK (fixP->fx_addsy)))
- {
- value -= S_GET_VALUE (fixP->fx_addsy);
- if (value != 0 && ! fixP->fx_pcrel)
+ 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))))
+
+ {
+ value -= S_GET_VALUE (fixP->fx_addsy);
+ if (value != 0 && ! fixP->fx_pcrel)
+ {
+ /* 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. */
+ value -= S_GET_VALUE (fixP->fx_addsy);
+ }
+ }
+
+ /* 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)
{
- /* 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. */
- value -= S_GET_VALUE (fixP->fx_addsy);
+ 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
case BFD_RELOC_MIPS_CALL_HI16:
case BFD_RELOC_MIPS_CALL_LO16:
case BFD_RELOC_MIPS16_GPREL:
- /* start-sanitize-r5900 */
- case BFD_RELOC_MIPS15_S3:
- /* end-sanitize-r5900 */
if (fixP->fx_pcrel)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("Invalid PC relative 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 ((fixP->fx_addsy->bsym->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 ((fixP->fx_addsy->bsym->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 */
md_number_to_chars ((char *) buf, (valueT) insn, 4);
break;
+ case BFD_RELOC_VTABLE_INHERIT:
+ fixP->fx_done = 0;
+ if (fixP->fx_addsy
+ && !S_IS_DEFINED (fixP->fx_addsy)
+ && !S_IS_WEAK (fixP->fx_addsy))
+ S_SET_WEAK (fixP->fx_addsy);
+ break;
+
+ case BFD_RELOC_VTABLE_ENTRY:
+ fixP->fx_done = 0;
+ break;
+
default:
internalError ();
}
if (label != NULL)
{
assert (S_GET_SEGMENT (label) == now_seg);
- label->sy_frag = frag_now;
+ symbol_set_frag (label, frag_now);
S_SET_VALUE (label, (valueT) frag_now_fix ());
}
}
static void
s_align (x)
- int x;
+ int x ATTRIBUTE_UNUSED;
{
register int temp;
register long temp_fill;
| 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;
mips_emit_delays (false);
if (auto_align)
- if (type == 'd')
- mips_align (3, 0, label);
- else
- mips_align (2, 0, label);
+ {
+ if (type == 'd')
+ mips_align (3, 0, label);
+ else
+ mips_align (2, 0, label);
+ }
mips_clear_insn_labels ();
static void
s_mips_globl (x)
- int x;
+ int x ATTRIBUTE_UNUSED;
{
char *name;
int c;
flag = BSF_FUNCTION;
}
- symbolP->bsym->flags |= flag;
+ symbol_get_bfdsym (symbolP)->flags |= flag;
S_SET_EXTERNAL (symbolP);
demand_empty_rest_of_line ();
static void
s_option (x)
- int x;
+ int x ATTRIBUTE_UNUSED;
{
char *opt;
char c;
static void
s_mipsset (x)
- int x;
+ int x ATTRIBUTE_UNUSED;
{
char *name = input_line_pointer, ch;
static void
s_abicalls (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
mips_pic = SVR4_PIC;
if (USE_GLOBAL_POINTER_OPT)
static void
s_cpload (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
expressionS ex;
int icnt = 0;
ex.X_add_number = 0;
/* In ELF, this symbol is implicitly an STT_OBJECT symbol. */
- ex.X_add_symbol->bsym->flags |= BSF_OBJECT;
+ symbol_get_bfdsym (ex.X_add_symbol)->flags |= BSF_OBJECT;
macro_build_lui ((char *) NULL, &icnt, &ex, GP);
macro_build ((char *) NULL, &icnt, &ex, "addiu", "t,r,j", GP, GP,
static void
s_cprestore (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
expressionS ex;
int icnt = 0;
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);
static void
s_gpword (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
symbolS *label;
expressionS ex;
static void
s_cpadd (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
int icnt = 0;
int reg;
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);
static void
s_insn (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
if (mips_opts.mips16)
mips16_mark_labels ();
static void
s_mips_weakext (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
char *name;
int c;
ignore_rest_of_line();
return;
}
- symbolP->sy_value = exp;
+ symbol_set_value_expression (symbolP, &exp);
}
demand_empty_rest_of_line ();
else if ((! S_IS_DEFINED (sym) || S_IS_COMMON (sym))
&& (0
#ifndef NO_ECOFF_DEBUGGING
- || (sym->ecoff_extern_size != 0
- && sym->ecoff_extern_size <= g_switch_value)
+ || (symbol_get_obj (sym)->ecoff_extern_size != 0
+ && (symbol_get_obj (sym)->ecoff_extern_size
+ <= g_switch_value))
#endif
/* We must defer this decision until after the whole
file has been read, since there might be a .extern
after the first use of this symbol. */
|| (before_relaxing
#ifndef NO_ECOFF_DEBUGGING
- && sym->ecoff_extern_size == 0
+ && symbol_get_obj (sym)->ecoff_extern_size == 0
#endif
&& S_GET_VALUE (sym) == 0)
|| (S_GET_VALUE (sym) != 0
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;
}
maxtiny = (1 << (op->nbits - 1)) - 1;
}
- /* We can't call S_GET_VALUE here, because we don't want to lock in
- a particular frag address. */
- if (fragp->fr_symbol->sy_value.X_op == O_constant)
+ /* We can't always call S_GET_VALUE here, because we don't want to
+ lock in a particular frag address. */
+ if (symbol_constant_p (fragp->fr_symbol))
{
- val = (fragp->fr_symbol->sy_value.X_add_number
- + fragp->fr_symbol->sy_frag->fr_address);
+ val = (S_GET_VALUE (fragp->fr_symbol)
+ + symbol_get_frag (fragp->fr_symbol)->fr_address);
symsec = S_GET_SEGMENT (fragp->fr_symbol);
}
- else if (fragp->fr_symbol->sy_value.X_op == O_symbol
- && (fragp->fr_symbol->sy_value.X_add_symbol->sy_value.X_op
- == O_constant))
+ else if (symbol_equated_p (fragp->fr_symbol)
+ && (symbol_constant_p
+ (symbol_get_value_expression (fragp->fr_symbol)->X_add_symbol)))
{
- val = (fragp->fr_symbol->sy_value.X_add_symbol->sy_value.X_add_number
- + fragp->fr_symbol->sy_value.X_add_symbol->sy_frag->fr_address
- + fragp->fr_symbol->sy_value.X_add_number
- + fragp->fr_symbol->sy_frag->fr_address);
- symsec = S_GET_SEGMENT (fragp->fr_symbol->sy_value.X_add_symbol);
+ symbolS *eqsym;
+
+ eqsym = symbol_get_value_expression (fragp->fr_symbol)->X_add_symbol;
+ val = (S_GET_VALUE (eqsym)
+ + symbol_get_frag (eqsym)->fr_address
+ + symbol_get_value_expression (fragp->fr_symbol)->X_add_number
+ + symbol_get_frag (fragp->fr_symbol)->fr_address);
+ symsec = S_GET_SEGMENT (eqsym);
}
else
return 1;
in STRETCH in order to get a better estimate of the address.
This particularly matters because of the shift bits. */
if (stretch != 0
- && fragp->fr_symbol->sy_frag->fr_address >= fragp->fr_address)
+ && (symbol_get_frag (fragp->fr_symbol)->fr_address
+ >= fragp->fr_address))
{
fragS *f;
a maximum number of bytes to skip when doing an
alignment. */
for (f = fragp;
- f != NULL && f != fragp->fr_symbol->sy_frag;
+ f != NULL && f != symbol_get_frag (fragp->fr_symbol);
f = f->fr_next)
{
if (f->fr_type == rs_align || f->fr_type == rs_align_code)
fragS *fragp;
asection *segtype;
{
- int change;
+ int change = 0;
+ boolean linkonce = false;
if (RELAX_MIPS16_P (fragp->fr_subtype))
{
sym = fragp->fr_symbol;
/* Handle the case of a symbol equated to another symbol. */
- while (sym->sy_value.X_op == O_symbol
+ while (symbol_equated_p (sym)
&& (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
{
symbolS *n;
/* It's possible to get a loop here in a badly written
program. */
- n = sym->sy_value.X_add_symbol;
+ n = symbol_get_value_expression (sym)->X_add_symbol;
if (n == sym)
break;
sym = n;
symsec = S_GET_SEGMENT (sym);
+ /* duplicate the test for LINK_ONCE sections as in adjust_reloc_syms */
+ if (symsec != segtype && ! S_IS_LOCAL (sym))
+ {
+ if ((bfd_get_section_flags (stdoutput, symsec) & SEC_LINK_ONCE)
+ != 0)
+ linkonce = true;
+
+ /* The GNU toolchain uses an extension for ELF: a section
+ beginning with the magic string .gnu.linkonce is a linkonce
+ section. */
+ if (strncmp (segment_name (symsec), ".gnu.linkonce",
+ sizeof ".gnu.linkonce" - 1) == 0)
+ linkonce = true;
+ }
+
/* 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)
+ && !linkonce
+#ifdef OBJ_ELF
+ /* A weak symbol is treated as external. */
+ && ! S_IS_WEAK (sym)
+#endif
+ );
}
else
abort ();
{
if (fixp->fx_r_type == BFD_RELOC_MIPS16_JMP)
return 0;
+ if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
+ || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ return 0;
if (fixp->fx_addsy == NULL)
return 1;
#ifdef OBJ_ELF
arelent **
tc_gen_reloc (section, fixp)
- asection *section;
+ asection *section ATTRIBUTE_UNUSED;
fixS *fixp;
{
static arelent *retval[4];
reloc = retval[0] = (arelent *) xmalloc (sizeof (arelent));
retval[1] = NULL;
- reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+ reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
if (mips_pic == EMBEDDED_PIC
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. */
- if (fixp->fx_addsy->bsym->flags & BSF_SECTION_SYM)
+ if (symbol_section_p (fixp->fx_addsy))
reloc->addend = reloc->address - S_GET_VALUE (fixp->fx_subsy);
else
reloc->addend = fixp->fx_addnumber + reloc->address;
/* We use a special addend for an internal RELHI reloc. The
reloc is relative to the RELLO; adjust the addend
accordingly. */
- if (fixp->fx_addsy->bsym->flags & BSF_SECTION_SYM)
+ if (symbol_section_p (fixp->fx_addsy))
reloc->addend = (fixp->fx_next->fx_frag->fr_address
+ fixp->fx_next->fx_where
- S_GET_VALUE (fixp->fx_subsy));
+ 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)
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
reloc2 = retval[1] = (arelent *) xmalloc (sizeof (arelent));
retval[2] = NULL;
- reloc2->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+ reloc2->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+ *reloc2->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
reloc2->address = (reloc->address
+ (RELAX_RELOC2 (fixp->fx_frag->fr_subtype)
- RELAX_RELOC1 (fixp->fx_frag->fr_subtype)));
abort ();
}
+ /* Since MIPS ELF uses Rel instead of Rela, encode the vtable entry
+ to be used in the relocation's section offset. */
+ if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
+ {
+ reloc->address = reloc->addend;
+ reloc->addend = 0;
+ }
+
/* Since DIFF_EXPR_OK is defined in tc-mips.h, it is possible that
fixup_segment converted a non-PC relative reloc into a PC
relative reloc. In such a case, we need to convert the reloc
/* 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;
void
md_convert_frag (abfd, asec, fragp)
- bfd *abfd;
+ bfd *abfd ATTRIBUTE_UNUSED;
segT asec;
fragS *fragp;
{
elf_elfheader (stdoutput)->e_flags |= EF_MIPS_NOREORDER;
if (mips_pic != NO_PIC)
elf_elfheader (stdoutput)->e_flags |= EF_MIPS_PIC;
+
+ /* Set the MIPS ELF ABI flags. */
+ if (mips_abi_string == 0)
+ ;
+ else if (strcmp (mips_abi_string,"32") == 0)
+ elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_O32;
+ else if (strcmp (mips_abi_string,"o64") == 0)
+ elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_O64;
+ else if (strcmp (mips_abi_string,"eabi") == 0)
+ {
+ if (mips_eabi64)
+ elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_EABI64;
+ else
+ elf_elfheader (stdoutput)->e_flags |= E_MIPS_ABI_EABI32;
+ }
+
+ if (mips_32bitmode)
+ elf_elfheader (stdoutput)->e_flags |= EF_MIPS_32BITMODE;
}
#endif /* OBJ_ELF || OBJ_MAYBE_ELF */
\f
-/* These functions should really be defined by the object file format,
- since they are related to debugging information. However, this
- code has to work for the a.out format, which does not define them,
- so we provide simple versions here. These don't actually generate
- any debugging information, but they do simple checking and someday
- somebody may make them useful. */
-
-typedef struct loc
-{
- struct loc *loc_next;
- unsigned long loc_fileno;
- unsigned long loc_lineno;
- unsigned long loc_offset;
- unsigned short loc_delta;
- unsigned short loc_count;
-#if 0
- fragS *loc_frag;
-#endif
-}
-locS;
-
typedef struct proc
{
- struct proc *proc_next;
- struct symbol *proc_isym;
- struct symbol *proc_end;
- unsigned long proc_reg_mask;
- unsigned long proc_reg_offset;
- unsigned long proc_fpreg_mask;
- unsigned long proc_fpreg_offset;
- unsigned long proc_frameoffset;
- unsigned long proc_framereg;
- unsigned long proc_pcreg;
- locS *proc_iline;
- struct file *proc_file;
- int proc_index;
+ symbolS *isym;
+ unsigned long reg_mask;
+ unsigned long reg_offset;
+ unsigned long fpreg_mask;
+ unsigned long fpreg_offset;
+ unsigned long frame_offset;
+ unsigned long frame_reg;
+ unsigned long pc_reg;
}
procS;
-typedef struct file
- {
- struct file *file_next;
- unsigned long file_fileno;
- struct symbol *file_symbol;
- struct symbol *file_end;
- struct proc *file_proc;
- int file_numprocs;
- }
-fileS;
-
-static struct obstack proc_frags;
-static procS *proc_lastP;
-static procS *proc_rootP;
+static procS cur_proc;
+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 ATTRIBUTE_UNUSED;
+ 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 ()
{
- obstack_begin (&proc_frags, 0x2000);
}
static void
md_obj_end ()
{
/* check for premature end, nesting errors, etc */
- if (proc_lastP && proc_lastP->proc_end == NULL)
+ if (cur_proc_ptr)
as_warn (_("missing `.end' at end of assembly"));
}
++input_line_pointer;
negative = 1;
}
- if (!isdigit (*input_line_pointer))
+ if (!isdigit ((unsigned char) *input_line_pointer))
as_bad (_("Expected simple number."));
if (input_line_pointer[0] == '0')
{
if (input_line_pointer[1] == 'x')
{
input_line_pointer += 2;
- while (isxdigit (*input_line_pointer))
+ while (isxdigit ((unsigned char) *input_line_pointer))
{
val <<= 4;
val |= hex_value (*input_line_pointer++);
else
{
++input_line_pointer;
- while (isdigit (*input_line_pointer))
+ while (isdigit ((unsigned char) *input_line_pointer))
{
val <<= 3;
val |= *input_line_pointer++ - '0';
return negative ? -val : val;
}
}
- if (!isdigit (*input_line_pointer))
+ if (!isdigit ((unsigned char) *input_line_pointer))
{
printf (_(" *input_line_pointer == '%c' 0x%02x\n"),
*input_line_pointer, *input_line_pointer);
as_warn (_("Invalid number"));
return -1;
}
- while (isdigit (*input_line_pointer))
+ while (isdigit ((unsigned char) *input_line_pointer))
{
val *= 10;
val += *input_line_pointer++ - '0';
static void
s_file (x)
- int x;
+ int x ATTRIBUTE_UNUSED;
{
int line;
/* The .end directive. */
static void
-s_mipsend (x)
- int x;
+s_mips_end (x)
+ int x ATTRIBUTE_UNUSED;
{
symbolS *p;
+ int maybe_text;
if (!is_end_of_line[(unsigned char) *input_line_pointer])
{
}
else
p = NULL;
- if (now_seg != text_section)
+
+#ifdef BFD_ASSEMBLER
+ if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
+ maybe_text = 1;
+ else
+ maybe_text = 0;
+#else
+ if (now_seg != data_section && now_seg != bss_section)
+ maybe_text = 1;
+ else
+ maybe_text = 0;
+#endif
+
+ if (!maybe_text)
as_warn (_(".end not in text section"));
- if (!proc_lastP)
+
+ if (!cur_proc_ptr)
{
- as_warn (_(".end and no .ent seen yet."));
+ as_warn (_(".end directive without a preceding .ent directive."));
+ demand_empty_rest_of_line ();
return;
}
if (p != NULL)
{
assert (S_GET_NAME (p));
- if (strcmp (S_GET_NAME (p), S_GET_NAME (proc_lastP->proc_isym)))
+ if (strcmp (S_GET_NAME (p), S_GET_NAME (cur_proc_ptr->isym)))
as_warn (_(".end symbol does not match .ent symbol."));
}
+ else
+ as_warn (_(".end directive missing or unknown symbol"));
- proc_lastP->proc_end = (symbolS *) 1;
+#ifdef MIPS_STABS_ELF
+ {
+ segT saved_seg = now_seg;
+ subsegT saved_subseg = now_subseg;
+ fragS *saved_frag = frag_now;
+ valueT dot;
+ segT seg;
+ expressionS exp;
+ char *fragp;
+
+ dot = frag_now_fix ();
+
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
+#endif
+
+ assert (pdr_seg);
+ subseg_set (pdr_seg, 0);
+
+ /* Write the symbol */
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = p;
+ exp.X_add_number = 0;
+ emit_expr (&exp, 4);
+
+ fragp = frag_more (7*4);
+
+ md_number_to_chars (fragp, (valueT) cur_proc_ptr->reg_mask, 4);
+ md_number_to_chars (fragp + 4, (valueT) cur_proc_ptr->reg_offset, 4);
+ md_number_to_chars (fragp + 8, (valueT) cur_proc_ptr->fpreg_mask, 4);
+ md_number_to_chars (fragp +12, (valueT) cur_proc_ptr->fpreg_offset, 4);
+ md_number_to_chars (fragp +16, (valueT) cur_proc_ptr->frame_offset, 4);
+ md_number_to_chars (fragp +20, (valueT) cur_proc_ptr->frame_reg, 4);
+ md_number_to_chars (fragp +24, (valueT) cur_proc_ptr->pc_reg, 4);
+
+ subseg_set (saved_seg, saved_subseg);
+ }
+#endif
+
+ cur_proc_ptr = NULL;
}
/* The .aent and .ent directives. */
static void
-s_ent (aent)
+s_mips_ent (aent)
int aent;
{
int number = 0;
- procS *procP;
symbolS *symbolP;
+ int maybe_text;
symbolP = get_symbol ();
if (*input_line_pointer == ',')
input_line_pointer++;
SKIP_WHITESPACE ();
- if (isdigit (*input_line_pointer) || *input_line_pointer == '-')
+ if (isdigit ((unsigned char) *input_line_pointer)
+ || *input_line_pointer == '-')
number = get_number ();
- if (now_seg != text_section)
+
+#ifdef BFD_ASSEMBLER
+ if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
+ maybe_text = 1;
+ else
+ maybe_text = 0;
+#else
+ if (now_seg != data_section && now_seg != bss_section)
+ maybe_text = 1;
+ else
+ maybe_text = 0;
+#endif
+
+ if (!maybe_text)
as_warn (_(".ent or .aent not in text section."));
- if (!aent && proc_lastP && proc_lastP->proc_end == NULL)
+ if (!aent && cur_proc_ptr)
as_warn (_("missing `.end'"));
if (!aent)
{
- procP = (procS *) obstack_alloc (&proc_frags, sizeof (*procP));
- procP->proc_isym = symbolP;
- procP->proc_reg_mask = 0;
- procP->proc_reg_offset = 0;
- procP->proc_fpreg_mask = 0;
- procP->proc_fpreg_offset = 0;
- procP->proc_frameoffset = 0;
- procP->proc_framereg = 0;
- procP->proc_pcreg = 0;
- procP->proc_end = NULL;
- procP->proc_next = NULL;
- if (proc_lastP)
- proc_lastP->proc_next = procP;
- else
- proc_rootP = procP;
- proc_lastP = procP;
+ cur_proc_ptr = &cur_proc;
+ memset (cur_proc_ptr, '\0', sizeof (procS));
+
+ cur_proc_ptr->isym = symbolP;
+
+ symbol_get_bfdsym (symbolP)->flags |= BSF_FUNCTION;
+
numprocs++;
}
+
demand_empty_rest_of_line ();
}
-/* The .frame directive. */
+/* The .frame directive. If the mdebug section is present (IRIX 5 native)
+ then ecoff.c (ecoff_directive_frame) is used. For embedded targets,
+ s_mips_frame is used so that we can set the PDR information correctly.
+ We can't use the ecoff routines because they make reference to the ecoff
+ symbol table (in the mdebug section). */
-#if 0
static void
-s_frame (x)
- int x;
+s_mips_frame (ignore)
+ int ignore;
{
- char str[100];
- symbolS *symP;
- int frame_reg;
- int frame_off;
- int pcreg;
+#ifdef MIPS_STABS_ELF
- frame_reg = tc_get_register (1);
- if (*input_line_pointer == ',')
- input_line_pointer++;
- frame_off = get_absolute_expression ();
- if (*input_line_pointer == ',')
- input_line_pointer++;
- pcreg = tc_get_register (0);
-
- /* bob third eye */
- assert (proc_rootP);
- proc_rootP->proc_framereg = frame_reg;
- proc_rootP->proc_frameoffset = frame_off;
- proc_rootP->proc_pcreg = pcreg;
- /* bob macho .frame */
-
- /* We don't have to write out a frame stab for unoptimized code. */
- if (!(frame_reg == FP && frame_off == 0))
- {
- if (!proc_lastP)
- as_warn (_("No .ent for .frame to use."));
- (void) sprintf (str, "R%d;%d", frame_reg, frame_off);
- symP = symbol_new (str, N_VFP, 0, frag_now);
- S_SET_TYPE (symP, N_RMASK);
- S_SET_OTHER (symP, 0);
- S_SET_DESC (symP, 0);
- symP->sy_forward = proc_lastP->proc_isym;
- /* bob perhaps I should have used pseudo set */
+ long val;
+
+ if (cur_proc_ptr == (procS *) NULL)
+ {
+ as_warn (_(".frame outside of .ent"));
+ demand_empty_rest_of_line ();
+ return;
}
+
+ cur_proc_ptr->frame_reg = tc_get_register (1);
+
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer++ != ','
+ || get_absolute_expression_and_terminator (&val) != ',')
+ {
+ as_warn (_("Bad .frame directive"));
+ --input_line_pointer;
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ cur_proc_ptr->frame_offset = val;
+ cur_proc_ptr->pc_reg = tc_get_register (0);
+
demand_empty_rest_of_line ();
+#else
+ s_ignore (ignore);
+#endif /* MIPS_STABS_ELF */
}
-#endif
-/* The .fmask and .mask directives. */
+/* The .fmask and .mask directives. If the mdebug section is present
+ (IRIX 5 native) then ecoff.c (ecoff_directive_mask) is used. For
+ embedded targets, s_mips_mask is used so that we can set the PDR
+ information correctly. We can't use the ecoff routines because they
+ make reference to the ecoff symbol table (in the mdebug section). */
-#if 0
static void
-s_mask (reg_type)
+s_mips_mask (reg_type)
char reg_type;
{
- char str[100], *strP;
- symbolS *symP;
- int i;
- unsigned int mask;
- int off;
+#ifdef MIPS_STABS_ELF
+ long mask, off;
+
+ if (cur_proc_ptr == (procS *) NULL)
+ {
+ as_warn (_(".mask/.fmask outside of .ent"));
+ demand_empty_rest_of_line ();
+ return;
+ }
+
+ if (get_absolute_expression_and_terminator (&mask) != ',')
+ {
+ as_warn (_("Bad .mask/.fmask directive"));
+ --input_line_pointer;
+ demand_empty_rest_of_line ();
+ return;
+ }
- mask = get_number ();
- if (*input_line_pointer == ',')
- input_line_pointer++;
off = get_absolute_expression ();
- /* bob only for coff */
- assert (proc_rootP);
if (reg_type == 'F')
{
- proc_rootP->proc_fpreg_mask = mask;
- proc_rootP->proc_fpreg_offset = off;
+ cur_proc_ptr->fpreg_mask = mask;
+ cur_proc_ptr->fpreg_offset = off;
}
else
{
- proc_rootP->proc_reg_mask = mask;
- proc_rootP->proc_reg_offset = off;
+ cur_proc_ptr->reg_mask = mask;
+ cur_proc_ptr->reg_offset = off;
}
- /* bob macho .mask + .fmask */
-
- /* We don't have to write out a mask stab if no saved regs. */
- if (!(mask == 0))
- {
- if (!proc_lastP)
- as_warn (_("No .ent for .mask to use."));
- strP = str;
- for (i = 0; i < 32; i++)
- {
- if (mask % 2)
- {
- sprintf (strP, "%c%d,", reg_type, i);
- strP += strlen (strP);
- }
- mask /= 2;
- }
- sprintf (strP, ";%d,", off);
- symP = symbol_new (str, N_RMASK, 0, frag_now);
- S_SET_TYPE (symP, N_RMASK);
- S_SET_OTHER (symP, 0);
- S_SET_DESC (symP, 0);
- symP->sy_forward = proc_lastP->proc_isym;
- /* bob perhaps I should have used pseudo set */
- }
+ demand_empty_rest_of_line ();
+#else
+ s_ignore (reg_type);
+#endif /* MIPS_STABS_ELF */
}
-#endif
/* The .loc directive. */