? ".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. */
+
+struct mips_set_options
+{
+ /* MIPS ISA (Instruction Set Architecture) level. This is set to -1
+ if it has not been initialized. Changed by `.set mipsN', and the
+ -mipsN command line option, and the default CPU. */
+ int isa;
+ /* Whether we are assembling for the mips16 processor. 0 if we are
+ not, 1 if we are, and -1 if the value has not been initialized.
+ Changed by `.set mips16' and `.set nomips16', and the -mips16 and
+ -nomips16 command line options, and the default CPU. */
+ int mips16;
+ /* Non-zero if we should not reorder instructions. Changed by `.set
+ reorder' and `.set noreorder'. */
+ int noreorder;
+ /* Non-zero if we should not permit the $at ($1) register to be used
+ in instructions. Changed by `.set at' and `.set noat'. */
+ int noat;
+ /* Non-zero if we should warn when a macro instruction expands into
+ more than one machine instruction. Changed by `.set nomacro' and
+ `.set macro'. */
+ int warn_about_macros;
+ /* Non-zero if we should not move instructions. Changed by `.set
+ move', `.set volatile', `.set nomove', and `.set novolatile'. */
+ int nomove;
+ /* Non-zero if we should not optimize branches by moving the target
+ of the branch into the delay slot. Actually, we don't perform
+ this optimization anyhow. Changed by `.set bopt' and `.set
+ nobopt'. */
+ int nobopt;
+ /* Non-zero if we should not autoextend mips16 instructions.
+ Changed by `.set autoextend' and `.set noautoextend'. */
+ int noautoextend;
+};
+
+/* This is the struct we use to hold the current set of options. Note
+ 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 };
+
/* These variables are filled in with the masks of registers used.
The object format code reads them and puts them in the appropriate
place. */
unsigned long mips_gprmask;
unsigned long mips_cprmask[4];
-/* MIPS ISA (Instruction Set Architecture) level (may be changed
- temporarily using .set mipsN). */
-static int mips_isa = -1;
-
/* MIPS ISA we are using for this output file. */
static int file_mips_isa;
-/* Whether we are assembling for the mips16 processor. */
-static int mips16 = -1;
-
/* The CPU type as a number: 2000, 3000, 4000, 4400, etc. */
static int mips_cpu = -1;
instructions. */
static int mips_trap;
-/* 1 if we should autoextend mips16 instructions. */
-static int mips16_autoextend = 1;
+/* Non-zero if any .set noreorder directives were used. */
-static int mips_warn_about_macros;
-static int mips_noreorder;
static int mips_any_noreorder;
-static int mips_nomove;
-static int mips_noat;
-static int mips_nobopt;
/* The size of the small data section. */
static int g_switch_value = 8;
static int insn_uses_reg PARAMS ((struct mips_cl_insn *ip,
unsigned int reg, enum mips_regclass class));
static int reg_needs_delay PARAMS ((int));
+static void mips16_mark_labels PARAMS ((void));
static void append_insn PARAMS ((char *place,
struct mips_cl_insn * ip,
expressionS * p,
static void s_ent PARAMS ((int));
static void s_mipsend PARAMS ((int));
static void s_file PARAMS ((int));
+static void s_mips_stab PARAMS ((int));
static int mips16_extended_frag PARAMS ((fragS *, asection *, long));
\f
/* Pseudo-op table.
{"quad", s_cons, 3},
{"short", s_cons, 1},
{"single", s_float_cons, 'f'},
+ {"stabn", s_mips_stab, 'n'},
{"text", s_change_sec, 't'},
{"word", s_cons, 2},
{ 0 },
register const char *retval = NULL;
register unsigned int i = 0;
- if (mips_isa == -1)
+ if (mips_opts.isa == -1)
{
const char *cpu;
char *a = NULL;
if (strcmp (cpu, "mips") == 0)
{
- mips_isa = 1;
+ mips_opts.isa = 1;
if (mips_cpu == -1)
mips_cpu = 3000;
}
else if (strcmp (cpu, "r6000") == 0
|| strcmp (cpu, "mips2") == 0)
{
- mips_isa = 2;
+ mips_opts.isa = 2;
if (mips_cpu == -1)
mips_cpu = 6000;
}
|| strcmp (cpu, "r4000") == 0
|| strcmp (cpu, "mips3") == 0)
{
- mips_isa = 3;
+ mips_opts.isa = 3;
if (mips_cpu == -1)
mips_cpu = 4000;
}
else if (strcmp (cpu, "r4400") == 0)
{
- mips_isa = 3;
+ mips_opts.isa = 3;
if (mips_cpu == -1)
mips_cpu = 4400;
}
else if (strcmp (cpu, "mips64orion") == 0
|| strcmp (cpu, "r4600") == 0)
{
- mips_isa = 3;
+ mips_opts.isa = 3;
if (mips_cpu == -1)
mips_cpu = 4600;
}
else if (strcmp (cpu, "r4650") == 0)
{
- mips_isa = 3;
+ mips_opts.isa = 3;
if (mips_cpu == -1)
mips_cpu = 4650;
if (mips_4650 == -1)
}
else if (strcmp (cpu, "mips64vr4300") == 0)
{
- mips_isa = 3;
+ mips_opts.isa = 3;
if (mips_cpu == -1)
mips_cpu = 4300;
}
else if (strcmp (cpu, "mips64vr4100") == 0)
{
- mips_isa = 3;
+ mips_opts.isa = 3;
if (mips_cpu == -1)
mips_cpu = 4100;
if (mips_4100 == -1)
}
else if (strcmp (cpu, "r4010") == 0)
{
- mips_isa = 2;
+ mips_opts.isa = 2;
if (mips_cpu == -1)
mips_cpu = 4010;
if (mips_4010 == -1)
else if (strcmp (cpu, "r5000") == 0
|| strcmp (cpu, "mips64vr5000") == 0)
{
- mips_isa = 4;
+ mips_opts.isa = 4;
if (mips_cpu == -1)
mips_cpu = 5000;
}
|| strcmp (cpu, "mips64vr5900") == 0
|| strcmp (cpu, "mips64vr5900el") == 0)
{
- mips_isa = 3;
+ mips_opts.isa = 3;
if (mips_cpu == -1)
mips_cpu = 5900;
if (mips_5900 == -1)
else if (strcmp (cpu, "r8000") == 0
|| strcmp (cpu, "mips4") == 0)
{
- mips_isa = 4;
+ mips_opts.isa = 4;
if (mips_cpu == -1)
mips_cpu = 8000;
}
else if (strcmp (cpu, "r10000") == 0)
{
- mips_isa = 4;
+ mips_opts.isa = 4;
if (mips_cpu == -1)
mips_cpu = 10000;
}
else if (strcmp (cpu, "mips16") == 0)
{
- mips_isa = 3;
+ mips_opts.isa = 3;
if (mips_cpu == -1)
mips_cpu = 0; /* FIXME */
}
else
{
- mips_isa = 1;
+ mips_opts.isa = 1;
if (mips_cpu == -1)
mips_cpu = 3000;
}
free (a);
}
- if (mips16 < 0)
+ if (mips_opts.mips16 < 0)
{
if (strncmp (TARGET_CPU, "mips16", sizeof "mips16" - 1) == 0)
- mips16 = 1;
+ mips_opts.mips16 = 1;
else
- mips16 = 0;
+ mips_opts.mips16 = 0;
}
if (mips_4650 < 0)
mips_5900 = 0;
/* end-sanitize-r5900 */
- if (mips_4010 || mips_4100 || mips_cpu == 4300)
+ if (mips_4010 || mips_cpu == 4300)
interlocks = 1;
else
interlocks = 0;
else
cop_interlocks = 0;
- if (mips_isa < 2 && mips_trap)
+ if (mips_opts.isa < 2 && mips_trap)
as_bad ("trap exception not supported at ISA 1");
- switch (mips_isa)
+ switch (mips_opts.isa)
{
case 1:
ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, 3000);
if (! ok)
as_warn ("Could not set architecture and machine");
- file_mips_isa = mips_isa;
+ file_mips_isa = mips_opts.isa;
op_hash = hash_new ();
offset_expr.X_op = O_absent;
offset_reloc = BFD_RELOC_UNUSED;
- if (mips16)
+ if (mips_opts.mips16)
mips16_ip (str, &insn);
else
{
if (insn.insn_mo->pinfo == INSN_MACRO)
{
- if (mips16)
+ if (mips_opts.mips16)
mips16_macro (&insn);
else
macro (&insn);
{
if (class == MIPS16_REG)
{
- assert (mips16);
+ assert (mips_opts.mips16);
reg = mips16_to_32_reg_map[reg];
class = MIPS_GR_REG;
}
if (class == MIPS_FP_REG)
{
- assert (! mips16);
+ assert (! mips_opts.mips16);
/* If we are called with either $f0 or $f1, we must check $f0.
This is not optimal, because it will introduce an unnecessary
NOP between "lwc1 $f0" and "swc1 $f1". To fix this we would
== (reg &~ (unsigned) 1)))
return 1;
}
- else if (! mips16)
+ else if (! mips_opts.mips16)
{
if ((ip->insn_mo->pinfo & INSN_READ_GPR_S)
&& ((ip->insn_opcode >> OP_SH_RS) & OP_MASK_RS) == reg)
unsigned long prev_pinfo;
prev_pinfo = prev_insn.insn_mo->pinfo;
- if (! mips_noreorder
- && mips_isa < 4
+ if (! mips_opts.noreorder
+ && mips_opts.isa < 4
&& ((prev_pinfo & INSN_LOAD_COPROC_DELAY)
- || (mips_isa < 2
+ || (mips_opts.isa < 2
&& (prev_pinfo & INSN_LOAD_MEMORY_DELAY))))
{
/* A load from a coprocessor or from memory. All load
return 0;
}
+/* Mark instruction labels in mips16 mode. This permits the linker to
+ handle them specially, such as generating jalx instructions when
+ needed. We also make them odd for the duration of the assembly, in
+ order to generate the right sort of code. We will make them even
+ in the adjust_symtab routine, while leaving them marked. This is
+ convenient for the debugger and the disassembler. The linker knows
+ to make them odd again. */
+
+static void
+mips16_mark_labels ()
+{
+ if (mips_opts.mips16)
+ {
+ struct insn_label_list *l;
+
+ for (l = insn_labels; l != NULL; l = l->next)
+ {
+#ifdef S_SET_OTHER
+ 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;
+ }
+ }
+}
+
/* Output an instruction. PLACE is where to put the instruction; if
it is NULL, this uses frag_more to get room. IP is the instruction
information. ADDRESS_EXPR is an operand of the instruction to be
fixS *fixp;
int nops = 0;
- /* Mark instruction labels in mips16 mode. This permits the linker
- to handle them specially, such as generating jalx instructions
- when needed. We also make them odd for the duration of the
- assembly, in order to generate the right sort of code. We will
- make them even in the adjust_symtab routine, while leaving them
- marked. This is convenient for the debugger and the
- disassembler. The linker knows to make them odd again. */
- if (mips16)
- {
- struct insn_label_list *l;
-
- for (l = insn_labels; l != NULL; l = l->next)
- {
-#ifdef S_SET_OTHER
- if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
- S_SET_OTHER (l->label, STO_MIPS16);
-#endif
- ++l->label->sy_value.X_add_number;
- }
- }
+ /* Mark instruction labels in mips16 mode. */
+ if (mips_opts.mips16)
+ mips16_mark_labels ();
prev_pinfo = prev_insn.insn_mo->pinfo;
pinfo = ip->insn_mo->pinfo;
- if (place == NULL && (! mips_noreorder || prev_nop_frag != NULL))
+ if (place == NULL && (! mips_opts.noreorder || prev_nop_frag != NULL))
{
int prev_prev_nop;
/* This is how a NOP is emitted. */
#define emit_nop() \
- (mips16 \
+ (mips_opts.mips16 \
? md_number_to_chars (frag_more (2), 0x6500, 2) \
: md_number_to_chars (frag_more (4), 0, 4))
/* The previous insn might require a delay slot, depending upon
the contents of the current insn. */
- if (! mips16
- && mips_isa < 4
+ if (! mips_opts.mips16
+ && mips_opts.isa < 4
&& (((prev_pinfo & INSN_LOAD_COPROC_DELAY)
&& ! cop_interlocks)
- || (mips_isa < 2
+ || (mips_opts.isa < 2
&& (prev_pinfo & INSN_LOAD_MEMORY_DELAY))))
{
/* A load from a coprocessor or from memory. All load
MIPS_GR_REG))
++nops;
}
- else if (! mips16
- && mips_isa < 4
+ else if (! mips_opts.mips16
+ && mips_opts.isa < 4
&& (((prev_pinfo & INSN_COPROC_MOVE_DELAY)
&& ! cop_interlocks)
- || (mips_isa < 2
+ || (mips_opts.isa < 2
&& (prev_pinfo & INSN_COPROC_MEMORY_DELAY))))
{
/* A generic coprocessor delay. The previous instruction
++nops;
}
}
- else if (! mips16
- && mips_isa < 4
+ else if (! mips_opts.mips16
+ && mips_opts.isa < 4
&& (prev_pinfo & INSN_WRITE_COND_CODE)
&& ! cop_interlocks)
{
which have interlocks). If we are not already emitting a NOP
instruction, we must check for these cases compared to the
instruction previous to the previous instruction. */
- if ((! mips16
- && mips_isa < 4
+ if ((! mips_opts.mips16
+ && mips_opts.isa < 4
&& (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)
happen when a nop instruction is used with mips_optimize set
to 0. */
if (nops > 0
- && ! mips_noreorder
- && ip->insn_opcode == (mips16 ? 0x6500 : 0))
+ && ! mips_opts.noreorder
+ && ip->insn_opcode == (mips_opts.mips16 ? 0x6500 : 0))
--nops;
/* Now emit the right number of NOP instructions. */
- if (nops > 0 && ! mips_noreorder)
+ if (nops > 0 && ! mips_opts.noreorder)
{
fragS *old_frag;
unsigned long old_frag_offset;
l->label->sy_frag = frag_now;
S_SET_VALUE (l->label, (valueT) frag_now_fix ());
/* mips16 text labels are stored as odd. */
- if (mips16)
+ if (mips_opts.mips16)
++l->label->sy_value.X_add_number;
}
{
if (nops == 0)
{
- prev_nop_frag->fr_fix -= mips16 ? 2 : 4;
+ prev_nop_frag->fr_fix -= mips_opts.mips16 ? 2 : 4;
--prev_nop_frag_holds;
}
else
{
if (prev_prev_nop == 0)
{
- prev_nop_frag->fr_fix -= mips16 ? 2 : 4;
+ prev_nop_frag->fr_fix -= mips_opts.mips16 ? 2 : 4;
--prev_nop_frag_holds;
}
else
if (reloc_type > BFD_RELOC_UNUSED)
{
/* We need to set up a variant frag. */
- assert (mips16 && address_expr != NULL);
+ assert (mips_opts.mips16 && address_expr != NULL);
f = frag_var (rs_machine_dependent, 4, 0,
RELAX_MIPS16_ENCODE (reloc_type - BFD_RELOC_UNUSED,
mips16_small, mips16_ext,
}
else if (place != NULL)
f = place;
- else if (mips16 && ! ip->use_extend && reloc_type != BFD_RELOC_MIPS16_JMP)
+ else if (mips_opts.mips16
+ && ! ip->use_extend
+ && reloc_type != BFD_RELOC_MIPS16_JMP)
{
/* Make sure there is enough room to swap this instruction with
a following jump instruction. */
}
else
{
- if (mips16
- && mips_noreorder
+ if (mips_opts.mips16
+ && mips_opts.noreorder
&& (prev_pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
as_warn ("extended instruction in delay slot");
}
}
- if (! mips16)
+ if (! mips_opts.mips16)
md_number_to_chars (f, ip->insn_opcode, 4);
else if (reloc_type == BFD_RELOC_MIPS16_JMP)
{
}
/* Update the register mask information. */
- if (! mips16)
+ if (! mips_opts.mips16)
{
if (pinfo & INSN_WRITE_GPR_D)
mips_gprmask |= 1 << ((ip->insn_opcode >> OP_SH_RD) & OP_MASK_RD);
& MIPS16OP_MASK_REGR32);
}
- if (place == NULL && ! mips_noreorder)
+ if (place == NULL && ! mips_opts.noreorder)
{
/* Filling the branch delay slot is more complex. We try to
switch the branch with the previous instruction, which we can
if (mips_optimize < 2
/* If we have seen .set volatile or .set nomove, don't
optimize. */
- || mips_nomove != 0
+ || mips_opts.nomove != 0
/* If we had to emit any NOP instructions, then we
already know we can not swap. */
|| nops != 0
can not do the swap. This does not apply to the
mips16, which uses variant frags for different
purposes. */
- || (! mips16
+ || (! mips_opts.mips16
&& prev_insn_frag->fr_type == rs_machine_dependent)
/* If the branch reads the condition codes, we don't
even try to swap, because in the sequence
bc1t LABEL
we can not swap, and I don't feel like handling that
case. */
- || (! mips16
- && mips_isa < 4
+ || (! mips_opts.mips16
+ && mips_opts.isa < 4
&& (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. */
- || (! mips16
- && mips_isa < 4
+ || (! mips_opts.mips16
+ && mips_opts.isa < 4
&& (prev_pinfo
/* Itbl support may require additional care here. */
& (INSN_LOAD_COPROC_DELAY
&& (prev_pinfo
& (INSN_READ_LO
| INSN_READ_HI)))
- || (! mips16
- && mips_isa < 2
+ || (! mips_opts.mips16
+ && mips_opts.isa < 2
&& (prev_pinfo
& (INSN_LOAD_MEMORY_DELAY
/* Itbl support may require additional care here. */
|| (prev_pinfo & INSN_TRAP)
/* If the branch reads a register that the previous
instruction sets, we can not swap. */
- || (! mips16
+ || (! mips_opts.mips16
&& (prev_pinfo & INSN_WRITE_GPR_T)
&& insn_uses_reg (ip,
((prev_insn.insn_opcode >> OP_SH_RT)
& OP_MASK_RT),
MIPS_GR_REG))
- || (! mips16
+ || (! mips_opts.mips16
&& (prev_pinfo & INSN_WRITE_GPR_D)
&& insn_uses_reg (ip,
((prev_insn.insn_opcode >> OP_SH_RD)
& OP_MASK_RD),
MIPS_GR_REG))
- || (mips16
+ || (mips_opts.mips16
&& (((prev_pinfo & MIPS16_INSN_WRITE_X)
&& insn_uses_reg (ip,
((prev_insn.insn_opcode
/* If the branch writes a register that the previous
instruction sets, we can not swap (we know that
branches write only to RD or to $31). */
- || (! mips16
+ || (! mips_opts.mips16
&& (prev_pinfo & INSN_WRITE_GPR_T)
&& (((pinfo & INSN_WRITE_GPR_D)
&& (((prev_insn.insn_opcode >> OP_SH_RT) & OP_MASK_RT)
&& (((prev_insn.insn_opcode >> OP_SH_RT)
& OP_MASK_RT)
== 31))))
- || (! mips16
+ || (! mips_opts.mips16
&& (prev_pinfo & INSN_WRITE_GPR_D)
&& (((pinfo & INSN_WRITE_GPR_D)
&& (((prev_insn.insn_opcode >> OP_SH_RD) & OP_MASK_RD)
&& (((prev_insn.insn_opcode >> OP_SH_RD)
& OP_MASK_RD)
== 31))))
- || (mips16
+ || (mips_opts.mips16
&& (pinfo & MIPS16_INSN_WRITE_31)
&& ((prev_pinfo & MIPS16_INSN_WRITE_31)
|| ((prev_pinfo & MIPS16_INSN_WRITE_GPR_Y)
/* If the branch writes a register that the previous
instruction reads, we can not swap (we know that
branches only write to RD or to $31). */
- || (! mips16
+ || (! mips_opts.mips16
&& (pinfo & INSN_WRITE_GPR_D)
&& insn_uses_reg (&prev_insn,
((ip->insn_opcode >> OP_SH_RD)
& OP_MASK_RD),
MIPS_GR_REG))
- || (! mips16
+ || (! mips_opts.mips16
&& (pinfo & INSN_WRITE_GPR_31)
&& insn_uses_reg (&prev_insn, 31, MIPS_GR_REG))
- || (mips16
+ || (mips_opts.mips16
&& (pinfo & MIPS16_INSN_WRITE_31)
&& insn_uses_reg (&prev_insn, RA, MIPS_GR_REG))
/* If we are generating embedded PIC code, the branch
/* If the previous previous instruction has a load
delay, and sets a register that the branch reads, we
can not swap. */
- || (! mips16
- && mips_isa < 4
+ || (! mips_opts.mips16
+ && mips_opts.isa < 4
/* Itbl support may require additional care here. */
&& ((prev_prev_insn.insn_mo->pinfo & INSN_LOAD_COPROC_DELAY)
- || (mips_isa < 2
+ || (mips_opts.isa < 2
&& (prev_prev_insn.insn_mo->pinfo
& INSN_LOAD_MEMORY_DELAY)))
&& insn_uses_reg (ip,
&& (prev_pinfo & INSN_READ_COND_CODE))
/* If the previous instruction uses the PC, we can not
swap. */
- || (mips16
+ || (mips_opts.mips16
&& (prev_pinfo & MIPS16_INSN_READ_PC))
/* If the previous instruction was extended, we can not
swap. */
- || (mips16 && prev_insn_extended)
+ || (mips_opts.mips16 && prev_insn_extended)
/* 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. */
- || (mips16 && prev_insn_fixp))
+ || (mips_opts.mips16 && prev_insn_fixp))
{
/* We could do even better for unconditional branches to
portions of this object file; we could pick up the
else
{
/* It looks like we can actually do the swap. */
- if (! mips16)
+ if (! mips_opts.mips16)
{
char *prev_f;
char temp[4];
prev_insn_fixp = fixp;
prev_insn_reloc_type = reloc_type;
- if (mips16)
+ if (mips_opts.mips16)
prev_insn_extended = (ip->use_extend
|| reloc_type > BFD_RELOC_UNUSED);
}
mips_emit_delays (insns)
boolean insns;
{
- if (! mips_noreorder)
+ if (! mips_opts.noreorder)
{
int nops;
nops = 0;
- if ((! mips16
- && mips_isa < 4
+ if ((! mips_opts.mips16
+ && mips_opts.isa < 4
&& (! cop_interlocks
&& (prev_insn.insn_mo->pinfo
& (INSN_LOAD_COPROC_DELAY
&& (prev_insn.insn_mo->pinfo
& (INSN_READ_LO
| INSN_READ_HI)))
- || (! mips16
- && mips_isa < 2
+ || (! mips_opts.mips16
+ && mips_opts.isa < 2
&& (prev_insn.insn_mo->pinfo
& (INSN_LOAD_MEMORY_DELAY
| INSN_COPROC_MEMORY_DELAY))))
{
/* Itbl support may require additional care here. */
++nops;
- if ((! mips16
- && mips_isa < 4
+ if ((! mips_opts.mips16
+ && mips_opts.isa < 4
&& (! cop_interlocks
&& prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE))
|| (! interlocks
if (prev_insn_unreordered)
nops = 0;
}
- else if ((! mips16
- && mips_isa < 4
+ else if ((! mips_opts.mips16
+ && mips_opts.isa < 4
&& (! cop_interlocks
&& prev_prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE))
|| (! interlocks
{
/* Record the frag which holds the nop instructions, so
that we can remove them if we don't need them. */
- frag_grow (mips16 ? nops * 2 : nops * 4);
+ frag_grow (mips_opts.mips16 ? nops * 2 : nops * 4);
prev_nop_frag = frag_now;
prev_nop_frag_holds = nops;
prev_nop_frag_required = 0;
l->label->sy_frag = frag_now;
S_SET_VALUE (l->label, (valueT) frag_now_fix ());
/* mips16 text labels are stored as odd. */
- if (mips16)
+ if (mips_opts.mips16)
++l->label->sy_value.X_add_number;
}
}
}
- /* Mark instruction labels in mips16 mode. This permits the linker
- to handle them specially, such as generating jalx instructions
- when needed. We also make them odd for the duration of the
- assembly, in order to generate the right sort of code. We will
- make them even in the adjust_symtab routine, while leaving them
- marked. This is convenient for the debugger and the
- disassembler. The linker knows to make them odd again. */
- if (mips16 && insns)
- {
- struct insn_label_list *l;
-
- for (l = insn_labels; l != NULL; l = l->next)
- {
-#ifdef S_SET_OTHER
- 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;
- }
- }
+ /* Mark instruction labels in mips16 mode. */
+ if (mips_opts.mips16 && insns)
+ mips16_mark_labels ();
mips_no_prev_insn (insns);
}
* print a warning if needed. We need to pass ip as a parameter
* to generate a better warning message here...
*/
- if (mips_warn_about_macros && place == NULL && *counter == 1)
+ if (mips_opts.warn_about_macros && place == NULL && *counter == 1)
as_warn ("Macro instruction expanded into multiple instructions");
if (place == NULL)
*counter += 1; /* bump instruction counter */
- if (mips16)
+ if (mips_opts.mips16)
{
mips16_macro_build (place, counter, ep, name, fmt, args);
va_end (args);
while (strcmp (fmt, insn.insn_mo->args) != 0
|| insn.insn_mo->pinfo == INSN_MACRO
|| ((insn.insn_mo->pinfo & INSN_ISA) == INSN_ISA2
- && mips_isa < 2)
+ && mips_opts.isa < 2)
|| ((insn.insn_mo->pinfo & INSN_ISA) == INSN_ISA3
- && mips_isa < 3)
+ && mips_opts.isa < 3)
|| ((insn.insn_mo->pinfo & INSN_ISA) == INSN_ISA4
- && mips_isa < 4)
+ && mips_opts.isa < 4)
|| ((insn.insn_mo->pinfo & INSN_ISA) == INSN_4650
&& ! mips_4650)
|| ((insn.insn_mo->pinfo & INSN_ISA) == INSN_4010
CONST char *name = "lui";
CONST char *fmt = "t,u";
- assert (! mips16);
+ assert (! mips_opts.mips16);
if (place == NULL)
high_expr = *ep;
* print a warning if needed. We need to pass ip as a parameter
* to generate a better warning message here...
*/
- if (mips_warn_about_macros && place == NULL && *counter == 1)
+ if (mips_opts.warn_about_macros && place == NULL && *counter == 1)
as_warn ("Macro instruction expanded into multiple instructions");
if (place == NULL)
|| ! ep->X_unsigned
|| sizeof (ep->X_add_number) > 4
|| (ep->X_add_number & 0x80000000) == 0))
- || ((mips_isa < 3 || ! dbl)
+ || ((mips_opts.isa < 3 || ! dbl)
&& (ep->X_add_number &~ (offsetT) 0xffffffff) == 0)
- || (mips_isa < 3
+ || (mips_opts.isa < 3
&& ! dbl
&& ((ep->X_add_number &~ (offsetT) 0xffffffff)
== ~ (offsetT) 0xffffffff)))
/* The value is larger than 32 bits. */
- if (mips_isa < 3)
+ if (mips_opts.isa < 3)
{
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,
- mips_isa < 3 ? "addiu" : "daddiu",
+ mips_opts.isa < 3 ? "addiu" : "daddiu",
"t,r,j", reg, GP, (int) BFD_RELOC_MIPS_GPREL);
p = frag_var (rs_machine_dependent, 8, 0,
- RELAX_ENCODE (4, 8, 0, 4, 0, mips_warn_about_macros),
+ RELAX_ENCODE (4, 8, 0, 4, 0,
+ mips_opts.warn_about_macros),
ep->X_add_symbol, (offsetT) 0, (char *) NULL);
}
macro_build_lui (p, counter, ep, reg);
if (p != NULL)
p += 4;
macro_build (p, counter, ep,
- mips_isa < 3 ? "addiu" : "daddiu",
+ mips_opts.isa < 3 ? "addiu" : "daddiu",
"t,r,j", reg, reg, (int) BFD_RELOC_LO16);
}
else if (mips_pic == SVR4_PIC && ! mips_big_got)
ep->X_add_number = 0;
frag_grow (20);
macro_build ((char *) NULL, counter, ep,
- mips_isa < 3 ? "lw" : "ld",
+ mips_opts.isa < 3 ? "lw" : "ld",
"t,o(b)", reg, (int) BFD_RELOC_MIPS_GOT16, GP);
macro_build ((char *) NULL, counter, (expressionS *) NULL, "nop", "");
p = frag_var (rs_machine_dependent, 4, 0,
- RELAX_ENCODE (0, 4, -8, 0, 0, mips_warn_about_macros),
+ RELAX_ENCODE (0, 4, -8, 0, 0, mips_opts.warn_about_macros),
ep->X_add_symbol, (offsetT) 0, (char *) NULL);
macro_build (p, counter, ep,
- mips_isa < 3 ? "addiu" : "daddiu",
+ mips_opts.isa < 3 ? "addiu" : "daddiu",
"t,r,j", reg, reg, (int) BFD_RELOC_LO16);
if (ex.X_add_number != 0)
{
as_bad ("PIC code offset overflow (max 16 signed bits)");
ex.X_op = O_constant;
macro_build ((char *) NULL, counter, &ex,
- mips_isa < 3 ? "addiu" : "daddiu",
+ mips_opts.isa < 3 ? "addiu" : "daddiu",
"t,r,j", reg, reg, (int) BFD_RELOC_LO16);
}
}
macro_build ((char *) NULL, counter, ep, "lui", "t,u", reg,
(int) BFD_RELOC_MIPS_GOT_HI16);
macro_build ((char *) NULL, counter, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", reg, reg, GP);
macro_build ((char *) NULL, counter, ep,
- mips_isa < 3 ? "lw" : "ld",
+ mips_opts.isa < 3 ? "lw" : "ld",
"t,o(b)", reg, (int) BFD_RELOC_MIPS_GOT_LO16, reg);
p = frag_var (rs_machine_dependent, 12 + off, 0,
RELAX_ENCODE (12, 12 + off, off, 8 + off, 0,
- mips_warn_about_macros),
+ mips_opts.warn_about_macros),
ep->X_add_symbol, (offsetT) 0, (char *) NULL);
if (off > 0)
{
p += 4;
}
macro_build (p, counter, ep,
- mips_isa < 3 ? "lw" : "ld",
+ mips_opts.isa < 3 ? "lw" : "ld",
"t,o(b)", reg, (int) BFD_RELOC_MIPS_GOT16, GP);
p += 4;
macro_build (p, counter, (expressionS *) NULL, "nop", "");
p += 4;
macro_build (p, counter, ep,
- mips_isa < 3 ? "addiu" : "daddiu",
+ mips_opts.isa < 3 ? "addiu" : "daddiu",
"t,r,j", reg, reg, (int) BFD_RELOC_LO16);
if (ex.X_add_number != 0)
{
as_bad ("PIC code offset overflow (max 16 signed bits)");
ex.X_op = O_constant;
macro_build ((char *) NULL, counter, &ex,
- mips_isa < 3 ? "addiu" : "daddiu",
+ mips_opts.isa < 3 ? "addiu" : "daddiu",
"t,r,j", reg, reg, (int) BFD_RELOC_LO16);
}
}
addiu $reg,$gp,<sym> (BFD_RELOC_MIPS_GPREL)
*/
macro_build ((char *) NULL, counter, ep,
- mips_isa < 3 ? "addiu" : "daddiu",
+ mips_opts.isa < 3 ? "addiu" : "daddiu",
"t,r,j", reg, GP, (int) BFD_RELOC_MIPS_GPREL);
}
else
char *p;
int hold_mips_optimize;
- assert (! mips16);
+ assert (! mips_opts.mips16);
treg = (ip->insn_opcode >> 16) & 0x1f;
dreg = (ip->insn_opcode >> 11) & 0x1f;
*/
mips_emit_delays (true);
- ++mips_noreorder;
+ ++mips_opts.noreorder;
mips_any_noreorder = 1;
expr1.X_add_number = 8;
dbl ? "dsub" : "sub",
"d,v,t", dreg, 0, sreg);
- --mips_noreorder;
+ --mips_opts.noreorder;
return;
case M_ADD_I:
case M_BGT_I:
/* check for > max integer */
maxnum = 0x7fffffff;
- if (mips_isa >= 3)
+ if (mips_opts.isa >= 3)
{
maxnum <<= 16;
maxnum |= 0xffff;
maxnum |= 0xffff;
}
if (imm_expr.X_add_number >= maxnum
- && (mips_isa < 3 || sizeof (maxnum) > 4))
+ && (mips_opts.isa < 3 || sizeof (maxnum) > 4))
{
do_false:
/* result is always false */
return;
}
maxnum = 0x7fffffff;
- if (mips_isa >= 3)
+ if (mips_opts.isa >= 3)
{
maxnum <<= 16;
maxnum |= 0xffff;
}
maxnum = - maxnum - 1;
if (imm_expr.X_add_number <= maxnum
- && (mips_isa < 3 || sizeof (maxnum) > 4))
+ && (mips_opts.isa < 3 || sizeof (maxnum) > 4))
{
do_true:
/* result is always true */
likely = 1;
case M_BLE_I:
maxnum = 0x7fffffff;
- if (mips_isa >= 3)
+ if (mips_opts.isa >= 3)
{
maxnum <<= 16;
maxnum |= 0xffff;
maxnum |= 0xffff;
}
if (imm_expr.X_add_number >= maxnum
- && (mips_isa < 3 || sizeof (maxnum) > 4))
+ && (mips_opts.isa < 3 || sizeof (maxnum) > 4))
goto do_true;
imm_expr.X_add_number++;
/* FALLTHROUGH */
}
mips_emit_delays (true);
- ++mips_noreorder;
+ ++mips_opts.noreorder;
mips_any_noreorder = 1;
macro_build ((char *) NULL, &icnt, NULL,
dbl ? "ddiv" : "div",
macro_build ((char *) NULL, &icnt, NULL, "nop", "", 0);
macro_build ((char *) NULL, &icnt, NULL, "break", "c", 6);
}
- --mips_noreorder;
+ --mips_opts.noreorder;
macro_build ((char *) NULL, &icnt, NULL, s, "d", dreg);
break;
s2 = "mfhi";
do_divu3:
mips_emit_delays (true);
- ++mips_noreorder;
+ ++mips_opts.noreorder;
mips_any_noreorder = 1;
macro_build ((char *) NULL, &icnt, NULL, s, "z,s,t", sreg, treg);
if (mips_trap)
macro_build ((char *) NULL, &icnt, NULL, "nop", "", 0);
macro_build ((char *) NULL, &icnt, NULL, "break", "c", 7);
}
- --mips_noreorder;
+ --mips_opts.noreorder;
macro_build ((char *) NULL, &icnt, NULL, s2, "d", dreg);
return;
macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",
treg, (int) BFD_RELOC_PCREL_HI16_S);
macro_build ((char *) NULL, &icnt, &offset_expr,
- mips_isa < 3 ? "addiu" : "daddiu",
+ mips_opts.isa < 3 ? "addiu" : "daddiu",
"t,r,j", treg, treg, (int) BFD_RELOC_PCREL_LO16);
return;
}
{
frag_grow (20);
macro_build ((char *) NULL, &icnt, &offset_expr,
- mips_isa < 3 ? "addiu" : "daddiu",
+ mips_opts.isa < 3 ? "addiu" : "daddiu",
"t,r,j", tempreg, GP, (int) BFD_RELOC_MIPS_GPREL);
p = frag_var (rs_machine_dependent, 8, 0,
RELAX_ENCODE (4, 8, 0, 4, 0,
- mips_warn_about_macros),
+ mips_opts.warn_about_macros),
offset_expr.X_add_symbol, (offsetT) 0,
(char *) NULL);
}
if (p != NULL)
p += 4;
macro_build (p, &icnt, &offset_expr,
- mips_isa < 3 ? "addiu" : "daddiu",
+ mips_opts.isa < 3 ? "addiu" : "daddiu",
"t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
}
else if (mips_pic == SVR4_PIC && ! mips_big_got)
p = frag_var (rs_machine_dependent, 8 - off, 0,
RELAX_ENCODE (0, 8 - off, -4 - off, 4 - off, 0,
(breg == 0
- ? mips_warn_about_macros
+ ? mips_opts.warn_about_macros
: 0)),
offset_expr.X_add_symbol, (offsetT) 0,
(char *) NULL);
p += 4;
}
macro_build (p, &icnt, &expr1,
- mips_isa < 3 ? "addiu" : "daddiu",
+ mips_opts.isa < 3 ? "addiu" : "daddiu",
"t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
/* FIXME: If breg == 0, and the next instruction uses
$tempreg, then if this variant case is used an extra
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
"nop", "");
macro_build ((char *) NULL, &icnt, &expr1,
- mips_isa < 3 ? "addiu" : "daddiu",
+ mips_opts.isa < 3 ? "addiu" : "daddiu",
"t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
(void) frag_var (rs_machine_dependent, 0, 0,
RELAX_ENCODE (0, 0, -12, -4, 0, 0),
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
"nop", "");
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", treg, AT, breg);
breg = 0;
tempreg = treg;
mips_optimize = hold_mips_optimize;
macro_build ((char *) NULL, &icnt, &expr1,
- mips_isa < 3 ? "addiu" : "daddiu",
+ mips_opts.isa < 3 ? "addiu" : "daddiu",
"t,r,j", AT, AT, (int) BFD_RELOC_LO16);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", tempreg, tempreg, AT);
(void) frag_var (rs_machine_dependent, 0, 0,
RELAX_ENCODE (0, 0, -16 + off1, -8, 0, 0),
macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",
tempreg, (int) BFD_RELOC_MIPS_GOT_HI16);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", tempreg, tempreg, GP);
macro_build ((char *) NULL, &icnt, &offset_expr,
dbl ? "ld" : "lw",
RELAX_ENCODE (12 + off, 12 + gpdel, gpdel,
8 + gpdel, 0,
(breg == 0
- ? mips_warn_about_macros
+ ? mips_opts.warn_about_macros
: 0)),
offset_expr.X_add_symbol, (offsetT) 0,
(char *) NULL);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
"nop", "");
macro_build ((char *) NULL, &icnt, &expr1,
- mips_isa < 3 ? "addiu" : "daddiu",
+ mips_opts.isa < 3 ? "addiu" : "daddiu",
"t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
p = frag_var (rs_machine_dependent, 12 + gpdel, 0,
RELAX_ENCODE (20, 12 + gpdel, gpdel, 8 + gpdel, 0,
(breg == 0
- ? mips_warn_about_macros
+ ? mips_opts.warn_about_macros
: 0)),
offset_expr.X_add_symbol, (offsetT) 0,
(char *) NULL);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
"nop", "");
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", treg, AT, breg);
dreg = treg;
adj = 8;
mips_optimize = hold_mips_optimize;
macro_build ((char *) NULL, &icnt, &expr1,
- mips_isa < 3 ? "addiu" : "daddiu",
+ mips_opts.isa < 3 ? "addiu" : "daddiu",
"t,r,j", AT, AT, (int) BFD_RELOC_LO16);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", dreg, dreg, AT);
p = frag_var (rs_machine_dependent, 16 + gpdel + adj, 0,
RELAX_ENCODE (24 + adj, 16 + gpdel + adj, gpdel,
8 + gpdel, 0,
(breg == 0
- ? mips_warn_about_macros
+ ? mips_opts.warn_about_macros
: 0)),
offset_expr.X_add_symbol, (offsetT) 0,
(char *) NULL);
macro_build (p, &icnt, (expressionS *) NULL, "nop", "");
p += 4;
macro_build (p, &icnt, &expr1,
- mips_isa < 3 ? "addiu" : "daddiu",
+ mips_opts.isa < 3 ? "addiu" : "daddiu",
"t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
/* FIXME: If add_number is 0, and there was no base
register, the external symbol case ended with a load,
macro_build (p, &icnt, (expressionS *) NULL, "nop", "");
p += 4;
macro_build (p, &icnt, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", treg, AT, breg);
p += 4;
tempreg = treg;
macro_build_lui (p, &icnt, &expr1, AT);
p += 4;
macro_build (p, &icnt, &expr1,
- mips_isa < 3 ? "addiu" : "daddiu",
+ mips_opts.isa < 3 ? "addiu" : "daddiu",
"t,r,j", AT, AT, (int) BFD_RELOC_LO16);
p += 4;
macro_build (p, &icnt, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", tempreg, tempreg, AT);
p += 4;
}
addiu $tempreg,$gp,<sym> (BFD_RELOC_MIPS_GPREL)
*/
macro_build ((char *) NULL, &icnt, &offset_expr,
- mips_isa < 3 ? "addiu" : "daddiu",
+ mips_opts.isa < 3 ? "addiu" : "daddiu",
"t,r,j", tempreg, GP, (int) BFD_RELOC_MIPS_GPREL);
}
else
if (breg != 0)
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", treg, tempreg, breg);
if (! used_at)
{
expr1.X_add_number = mips_cprestore_offset;
macro_build ((char *) NULL, &icnt, &expr1,
- mips_isa < 3 ? "lw" : "ld",
+ mips_opts.isa < 3 ? "lw" : "ld",
"t,o(b)", GP, (int) BFD_RELOC_LO16, mips_frame_reg);
}
}
if (! mips_big_got)
{
macro_build ((char *) NULL, &icnt, &offset_expr,
- mips_isa < 3 ? "lw" : "ld",
+ mips_opts.isa < 3 ? "lw" : "ld",
"t,o(b)", PIC_CALL_REG,
(int) BFD_RELOC_MIPS_CALL16, GP);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",
PIC_CALL_REG, (int) BFD_RELOC_MIPS_CALL_HI16);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", PIC_CALL_REG, PIC_CALL_REG, GP);
macro_build ((char *) NULL, &icnt, &offset_expr,
- mips_isa < 3 ? "lw" : "ld",
+ mips_opts.isa < 3 ? "lw" : "ld",
"t,o(b)", PIC_CALL_REG,
(int) BFD_RELOC_MIPS_CALL_LO16, PIC_CALL_REG);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
p += 4;
}
macro_build (p, &icnt, &offset_expr,
- mips_isa < 3 ? "lw" : "ld",
+ mips_opts.isa < 3 ? "lw" : "ld",
"t,o(b)", PIC_CALL_REG,
(int) BFD_RELOC_MIPS_GOT16, GP);
p += 4;
p += 4;
}
macro_build (p, &icnt, &offset_expr,
- mips_isa < 3 ? "addiu" : "daddiu",
+ mips_opts.isa < 3 ? "addiu" : "daddiu",
"t,r,j", PIC_CALL_REG, PIC_CALL_REG,
(int) BFD_RELOC_LO16);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
as_warn ("No .cprestore pseudo-op used in PIC code");
else
{
- if (mips_noreorder)
+ if (mips_opts.noreorder)
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
"nop", "");
expr1.X_add_number = mips_cprestore_offset;
macro_build ((char *) NULL, &icnt, &expr1,
- mips_isa < 3 ? "lw" : "ld",
+ mips_opts.isa < 3 ? "lw" : "ld",
"t,o(b)", GP, (int) BFD_RELOC_LO16,
mips_frame_reg);
}
treg, (int) BFD_RELOC_MIPS_GPREL, GP);
p = frag_var (rs_machine_dependent, 8, 0,
RELAX_ENCODE (4, 8, 0, 4, 0,
- (mips_warn_about_macros
- || (used_at && mips_noat))),
+ (mips_opts.warn_about_macros
+ || (used_at
+ && mips_opts.noat))),
offset_expr.X_add_symbol, (offsetT) 0,
(char *) NULL);
used_at = 0;
{
frag_grow (28);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", tempreg, breg, GP);
macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,
treg, (int) BFD_RELOC_MIPS_GPREL, tempreg);
if (p != NULL)
p += 4;
macro_build (p, &icnt, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", tempreg, tempreg, breg);
if (p != NULL)
p += 4;
as_bad ("PIC code offset overflow (max 16 signed bits)");
frag_grow (20);
macro_build ((char *) NULL, &icnt, &offset_expr,
- mips_isa < 3 ? "lw" : "ld",
+ mips_opts.isa < 3 ? "lw" : "ld",
"t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT16, GP);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "nop", "");
p = frag_var (rs_machine_dependent, 4, 0,
offset_expr.X_add_symbol, (offsetT) 0,
(char *) NULL);
macro_build (p, &icnt, &offset_expr,
- mips_isa < 3 ? "addiu" : "daddiu",
+ mips_opts.isa < 3 ? "addiu" : "daddiu",
"t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
if (breg != 0)
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", tempreg, tempreg, breg);
macro_build ((char *) NULL, &icnt, &expr1, s, fmt, treg,
(int) BFD_RELOC_LO16, tempreg);
macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",
tempreg, (int) BFD_RELOC_MIPS_GOT_HI16);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", tempreg, tempreg, GP);
macro_build ((char *) NULL, &icnt, &offset_expr,
- mips_isa < 3 ? "lw" : "ld",
+ mips_opts.isa < 3 ? "lw" : "ld",
"t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT_LO16,
tempreg);
p = frag_var (rs_machine_dependent, 12 + gpdel, 0,
p += 4;
}
macro_build (p, &icnt, &offset_expr,
- mips_isa < 3 ? "lw" : "ld",
+ mips_opts.isa < 3 ? "lw" : "ld",
"t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT16, GP);
p += 4;
macro_build (p, &icnt, (expressionS *) NULL, "nop", "");
p += 4;
macro_build (p, &icnt, &offset_expr,
- mips_isa < 3 ? "addiu" : "daddiu",
+ mips_opts.isa < 3 ? "addiu" : "daddiu",
"t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);
if (breg != 0)
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", tempreg, tempreg, breg);
macro_build ((char *) NULL, &icnt, &expr1, s, fmt, treg,
(int) BFD_RELOC_LO16, tempreg);
else
{
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", tempreg, breg, GP);
macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,
treg, (int) BFD_RELOC_MIPS_GPREL, tempreg);
else if (mips_pic == SVR4_PIC)
{
macro_build ((char *) NULL, &icnt, &offset_expr,
- mips_isa < 3 ? "lw" : "ld",
+ mips_opts.isa < 3 ? "lw" : "ld",
"t,o(b)", AT, (int) BFD_RELOC_MIPS_GOT16, GP);
}
else if (mips_pic == EMBEDDED_PIC)
/* For embedded PIC we pick up the entire address off $gp in
a single instruction. */
macro_build ((char *) NULL, &icnt, &offset_expr,
- mips_isa < 3 ? "addiu" : "daddiu",
+ mips_opts.isa < 3 ? "addiu" : "daddiu",
"t,r,j", AT, GP, (int) BFD_RELOC_MIPS_GPREL);
offset_expr.X_op = O_constant;
offset_expr.X_add_number = 0;
abort ();
/* Now we load the register(s). */
- if (mips_isa >= 3)
+ if (mips_opts.isa >= 3)
macro_build ((char *) NULL, &icnt, &offset_expr, "ld", "t,o(b)",
treg, (int) BFD_RELOC_LO16, AT);
else
s = segment_name (S_GET_SEGMENT (offset_expr.X_add_symbol));
if (strcmp (s, ".lit8") == 0)
{
- if (mips_isa >= 2)
+ if (mips_opts.isa >= 2)
{
macro_build ((char *) NULL, &icnt, &offset_expr, "ldc1",
"T,o(b)", treg, (int) BFD_RELOC_MIPS_LITERAL, GP);
assert (strcmp (s, RDATA_SECTION_NAME) == 0);
if (mips_pic == SVR4_PIC)
macro_build ((char *) NULL, &icnt, &offset_expr,
- mips_isa < 3 ? "lw" : "ld",
+ mips_opts.isa < 3 ? "lw" : "ld",
"t,o(b)", AT, (int) BFD_RELOC_MIPS_GOT16, GP);
else
{
macro_build_lui ((char *) NULL, &icnt, &offset_expr, AT);
}
- if (mips_isa >= 2)
+ if (mips_opts.isa >= 2)
{
macro_build ((char *) NULL, &icnt, &offset_expr, "ldc1",
"T,o(b)", treg, (int) BFD_RELOC_LO16, AT);
to adjust when loading from memory. */
r = BFD_RELOC_LO16;
dob:
- assert (mips_isa < 2);
+ assert (mips_opts.isa < 2);
macro_build ((char *) NULL, &icnt, &offset_expr, "lwc1", "T,o(b)",
target_big_endian ? treg + 1 : treg,
(int) r, breg);
*/
/* Itbl support may require additional care here. */
coproc = 1;
- if (mips_isa >= 2)
+ if (mips_opts.isa >= 2)
{
s = "ldc1";
goto ld;
goto ldd_std;
case M_S_DAB:
- if (mips_isa >= 2)
+ if (mips_opts.isa >= 2)
{
s = "sdc1";
goto st;
goto ldd_std;
case M_LD_AB:
- if (mips_isa >= 3)
+ if (mips_opts.isa >= 3)
{
s = "ld";
goto ld;
goto ldd_std;
case M_SD_AB:
- if (mips_isa >= 3)
+ if (mips_opts.isa >= 3)
{
s = "sd";
goto st;
{
frag_grow (36);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", AT, breg, GP);
tempreg = AT;
off = 4;
p = frag_var (rs_machine_dependent, 12 + off, 0,
RELAX_ENCODE (8 + off, 12 + off, 0, 4 + off, 1,
- used_at && mips_noat),
+ used_at && mips_opts.noat),
offset_expr.X_add_symbol, (offsetT) 0,
(char *) NULL);
if (breg != 0)
{
macro_build (p, &icnt, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", AT, breg, AT);
if (p != NULL)
p += 4;
off = 4;
frag_grow (24 + off);
macro_build ((char *) NULL, &icnt, &offset_expr,
- mips_isa < 3 ? "lw" : "ld",
+ mips_opts.isa < 3 ? "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,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", AT, breg, AT);
/* Itbl support may require additional care here. */
macro_build ((char *) NULL, &icnt, &expr1, s, fmt,
macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",
AT, (int) BFD_RELOC_MIPS_GOT_HI16);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", AT, AT, GP);
macro_build ((char *) NULL, &icnt, &offset_expr,
- mips_isa < 3 ? "lw" : "ld",
+ mips_opts.isa < 3 ? "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,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", AT, breg, AT);
/* Itbl support may require additional care here. */
macro_build ((char *) NULL, &icnt, &expr1, s, fmt,
p += 4;
}
macro_build (p, &icnt, &offset_expr,
- mips_isa < 3 ? "lw" : "ld",
+ mips_opts.isa < 3 ? "lw" : "ld",
"t,o(b)", AT, (int) BFD_RELOC_MIPS_GOT16, GP);
p += 4;
macro_build (p, &icnt, (expressionS *) NULL, "nop", "");
if (breg != 0)
{
macro_build (p, &icnt, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", AT, breg, AT);
p += 4;
}
else
{
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", AT, breg, GP);
tempreg = AT;
used_at = 1;
case M_SD_OB:
s = "sw";
sd_ob:
- assert (mips_isa < 3);
+ assert (mips_opts.isa < 3);
macro_build ((char *) NULL, &icnt, &offset_expr, s, "t,o(b)", treg,
(int) BFD_RELOC_LO16, breg);
offset_expr.X_add_number += 4;
macro2 (ip);
return;
}
- if (mips_noat)
+ if (mips_opts.noat)
as_warn ("Macro used $at after \".set noat\"");
}
dbl = 1;
case M_MULO:
mips_emit_delays (true);
- ++mips_noreorder;
+ ++mips_opts.noreorder;
mips_any_noreorder = 1;
macro_build ((char *) NULL, &icnt, NULL,
dbl ? "dmult" : "mult",
macro_build ((char *) NULL, &icnt, NULL, "nop", "", 0);
macro_build ((char *) NULL, &icnt, NULL, "break", "c", 6);
}
- --mips_noreorder;
+ --mips_opts.noreorder;
macro_build ((char *) NULL, &icnt, NULL, "mflo", "d", dreg);
break;
dbl = 1;
case M_MULOU:
mips_emit_delays (true);
- ++mips_noreorder;
+ ++mips_opts.noreorder;
mips_any_noreorder = 1;
macro_build ((char *) NULL, &icnt, NULL,
dbl ? "dmultu" : "multu",
macro_build ((char *) NULL, &icnt, NULL, "nop", "", 0);
macro_build ((char *) NULL, &icnt, NULL, "break", "c", 6);
}
- --mips_noreorder;
+ --mips_opts.noreorder;
break;
case M_ROL:
break;
case M_S_DOB:
- assert (mips_isa < 2);
+ assert (mips_opts.isa < 2);
/* 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,
- mips_isa < 3 ? "addiu" : "daddiu",
+ mips_opts.isa < 3 ? "addiu" : "daddiu",
"t,r,j", dreg, sreg,
(int) BFD_RELOC_LO16);
used_at = 0;
as_warn ("Instruction %s: result is always true",
ip->insn_mo->name);
macro_build ((char *) NULL, &icnt, &expr1,
- mips_isa < 3 ? "addiu" : "daddiu",
+ mips_opts.isa < 3 ? "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,
- mips_isa < 3 ? "addiu" : "daddiu",
+ mips_opts.isa < 3 ? "addiu" : "daddiu",
"t,r,j", dreg, sreg, (int) BFD_RELOC_LO16);
used_at = 0;
}
case M_TRUNCWD:
case M_TRUNCWS:
- assert (mips_isa < 2);
+ assert (mips_opts.isa < 2);
sreg = (ip->insn_opcode >> 11) & 0x1f; /* floating reg */
dreg = (ip->insn_opcode >> 06) & 0x1f; /* floating reg */
* or is there a reason for it?
*/
mips_emit_delays (true);
- ++mips_noreorder;
+ ++mips_opts.noreorder;
mips_any_noreorder = 1;
macro_build ((char *) NULL, &icnt, NULL, "cfc1", "t,G", treg, 31);
macro_build ((char *) NULL, &icnt, NULL, "cfc1", "t,G", treg, 31);
mask == M_TRUNCWD ? "cvt.w.d" : "cvt.w.s", "D,S", dreg, sreg);
macro_build ((char *) NULL, &icnt, NULL, "ctc1", "t,G", treg, 31);
macro_build ((char *) NULL, &icnt, NULL, "nop", "");
- --mips_noreorder;
+ --mips_opts.noreorder;
break;
case M_ULH:
load_address (&icnt, AT, &offset_expr);
if (breg != 0)
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", AT, AT, breg);
if (! target_big_endian)
expr1.X_add_number = off;
load_address (&icnt, AT, &offset_expr);
if (breg != 0)
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", AT, AT, breg);
if (target_big_endian)
expr1.X_add_number = 0;
load_address (&icnt, AT, &offset_expr);
if (breg != 0)
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", AT, AT, breg);
if (! target_big_endian)
expr1.X_add_number = off;
load_address (&icnt, AT, &offset_expr);
if (breg != 0)
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", AT, AT, breg);
if (! target_big_endian)
expr1.X_add_number = 0;
as_bad ("Macro %s not implemented yet", ip->insn_mo->name);
break;
}
- if (mips_noat)
+ if (mips_opts.noat)
as_warn ("Macro used $at after \".set noat\"");
}
s = "mfhi";
do_div3:
mips_emit_delays (true);
- ++mips_noreorder;
+ ++mips_opts.noreorder;
mips_any_noreorder = 1;
macro_build ((char *) NULL, &icnt, NULL,
dbl ? "ddiv" : "div",
since that causes an overflow. We should do that as well,
but I don't see how to do the comparisons without a temporary
register. */
- --mips_noreorder;
+ --mips_opts.noreorder;
macro_build ((char *) NULL, &icnt, NULL, s, "x", zreg);
break;
s2 = "mfhi";
do_divu3:
mips_emit_delays (true);
- ++mips_noreorder;
+ ++mips_opts.noreorder;
mips_any_noreorder = 1;
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);
macro_build ((char *) NULL, &icnt, NULL, "break", "6", 7);
- --mips_noreorder;
+ --mips_opts.noreorder;
macro_build ((char *) NULL, &icnt, NULL, s2, "x", zreg);
break;
else
insn_isa = 1;
- if (insn_isa > mips_isa
+ if (insn_isa > mips_opts.isa
|| (insn->pinfo != INSN_MACRO
&& (((insn->pinfo & INSN_ISA) == INSN_4650
&& ! mips_4650)
++insn;
continue;
}
- if (insn_isa <= mips_isa)
+ if (insn_isa <= mips_opts.isa)
insn_error = "opcode not supported on this processor";
else
{
goto notreg;
}
if (regno == AT
- && ! mips_noat
+ && ! mips_opts.noat
&& *args != 'E'
&& *args != 'G')
as_warn ("Used $at without \".set noat\"");
as_bad ("Invalid float register number (%d)", regno);
if ((regno & 1) != 0
- && mips_isa < 3
+ && mips_opts.isa < 3
&& ! (strcmp (str, "mtc1") == 0
|| strcmp (str, "mfc1") == 0
|| strcmp (str, "lwc1") == 0
&& imm_expr.X_op == O_constant)
|| (more
&& imm_expr.X_add_number < 0
- && mips_isa >= 3
+ && mips_opts.isa >= 3
&& imm_expr.X_unsigned
&& sizeof (imm_expr.X_add_number) <= 4))
{
return;
}
- if (! mips16_autoextend && ! mips16_ext)
+ if (mips_opts.noautoextend && ! mips16_ext)
mips16_small = true;
if ((insn = (struct mips_opcode *) hash_find (mips16_op_hash, str)) == NULL)
case 'X':
case 'Y':
- if (regno == AT && ! mips_noat)
+ if (regno == AT && ! mips_opts.noat)
as_warn ("used $at without \".set noat\"");
break;
then we bump the value of the symbol by 1 since that is how other
text symbols are handled. We don't bother to handle complex
expressions, just `.' plus or minus a constant. */
- if (mips16
+ if (mips_opts.mips16
&& 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
break;
case OPTION_MIPS1:
- mips_isa = 1;
+ mips_opts.isa = 1;
if (mips_cpu == -1)
mips_cpu = 3000;
break;
case OPTION_MIPS2:
- mips_isa = 2;
+ mips_opts.isa = 2;
if (mips_cpu == -1)
mips_cpu = 6000;
break;
case OPTION_MIPS3:
- mips_isa = 3;
+ mips_opts.isa = 3;
if (mips_cpu == -1)
mips_cpu = 4000;
break;
case OPTION_MIPS4:
- mips_isa = 4;
+ mips_opts.isa = 4;
if (mips_cpu == -1)
mips_cpu = 8000;
break;
/* end-sanitize-r5900 */
case OPTION_MIPS16:
- mips16 = 1;
+ mips_opts.mips16 = 1;
mips_no_prev_insn (false);
break;
case OPTION_NO_MIPS16:
- mips16 = 0;
+ mips_opts.mips16 = 0;
mips_no_prev_insn (false);
break;
demand_empty_rest_of_line ();
}
+/* This structure is used to hold a stack of .set values. */
+
+struct mips_option_stack
+{
+ struct mips_option_stack *next;
+ struct mips_set_options options;
+};
+
+static struct mips_option_stack *mips_opts_stack;
+
+/* Handle the .set pseudo-op. */
+
static void
s_mipsset (x)
int x;
if (strcmp (name, "reorder") == 0)
{
- if (mips_noreorder && prev_nop_frag != NULL)
+ if (mips_opts.noreorder && prev_nop_frag != NULL)
{
/* If we still have pending nops, we can discard them. The
usual nop handling will insert any that are still
needed. */
- prev_nop_frag->fr_fix -= prev_nop_frag_holds * (mips16 ? 2 : 4);
+ prev_nop_frag->fr_fix -= (prev_nop_frag_holds
+ * (mips_opts.mips16 ? 2 : 4));
prev_nop_frag = NULL;
}
- mips_noreorder = 0;
+ mips_opts.noreorder = 0;
}
else if (strcmp (name, "noreorder") == 0)
{
mips_emit_delays (true);
- mips_noreorder = 1;
+ mips_opts.noreorder = 1;
mips_any_noreorder = 1;
}
else if (strcmp (name, "at") == 0)
{
- mips_noat = 0;
+ mips_opts.noat = 0;
}
else if (strcmp (name, "noat") == 0)
{
- mips_noat = 1;
+ mips_opts.noat = 1;
}
else if (strcmp (name, "macro") == 0)
{
- mips_warn_about_macros = 0;
+ mips_opts.warn_about_macros = 0;
}
else if (strcmp (name, "nomacro") == 0)
{
- if (mips_noreorder == 0)
+ if (mips_opts.noreorder == 0)
as_bad ("`noreorder' must be set before `nomacro'");
- mips_warn_about_macros = 1;
+ mips_opts.warn_about_macros = 1;
}
else if (strcmp (name, "move") == 0 || strcmp (name, "novolatile") == 0)
{
- mips_nomove = 0;
+ mips_opts.nomove = 0;
}
else if (strcmp (name, "nomove") == 0 || strcmp (name, "volatile") == 0)
{
- mips_nomove = 1;
+ mips_opts.nomove = 1;
}
else if (strcmp (name, "bopt") == 0)
{
- mips_nobopt = 0;
+ mips_opts.nobopt = 0;
}
else if (strcmp (name, "nobopt") == 0)
{
- mips_nobopt = 1;
+ mips_opts.nobopt = 1;
}
else if (strcmp (name, "mips16") == 0
|| strcmp (name, "MIPS-16") == 0)
- mips16 = 1;
+ mips_opts.mips16 = 1;
else if (strcmp (name, "nomips16") == 0
|| strcmp (name, "noMIPS-16") == 0)
- mips16 = 0;
+ mips_opts.mips16 = 0;
else if (strncmp (name, "mips", 4) == 0)
{
int isa;
say, misuse can cause serious problems. */
isa = atoi (name + 4);
if (isa == 0)
- mips_isa = file_mips_isa;
+ mips_opts.isa = file_mips_isa;
else if (isa < 1 || isa > 4)
as_bad ("unknown ISA level");
else
- mips_isa = isa;
+ mips_opts.isa = isa;
}
else if (strcmp (name, "autoextend") == 0)
- mips16_autoextend = 1;
+ mips_opts.noautoextend = 0;
else if (strcmp (name, "noautoextend") == 0)
- mips16_autoextend = 0;
+ mips_opts.noautoextend = 1;
+ else if (strcmp (name, "push") == 0)
+ {
+ struct mips_option_stack *s;
+
+ s = (struct mips_option_stack *) xmalloc (sizeof *s);
+ s->next = mips_opts_stack;
+ s->options = mips_opts;
+ mips_opts_stack = s;
+ }
+ else if (strcmp (name, "pop") == 0)
+ {
+ struct mips_option_stack *s;
+
+ s = mips_opts_stack;
+ if (s == NULL)
+ as_bad (".set pop with no .set push");
+ else
+ {
+ /* If we're changing the reorder mode we need to handle
+ delay slots correctly. */
+ if (s->options.noreorder && ! mips_opts.noreorder)
+ mips_emit_delays (true);
+ else if (! s->options.noreorder && mips_opts.noreorder)
+ {
+ if (prev_nop_frag != NULL)
+ {
+ prev_nop_frag->fr_fix -= (prev_nop_frag_holds
+ * (mips_opts.mips16 ? 2 : 4));
+ prev_nop_frag = NULL;
+ }
+ }
+
+ mips_opts = s->options;
+ mips_opts_stack = s->next;
+ free (s);
+ }
+ }
else
{
as_warn ("Tried to set unrecognized symbol: %s\n", name);
}
/* .cpload should be a in .set noreorder section. */
- if (mips_noreorder == 0)
+ if (mips_opts.noreorder == 0)
as_warn (".cpload not in noreorder section");
ex.X_op = O_symbol;
ex.X_add_number = mips_cprestore_offset;
macro_build ((char *) NULL, &icnt, &ex,
- mips_isa < 3 ? "sw" : "sd",
+ mips_opts.isa < 3 ? "sw" : "sd",
"t,o(b)", GP, (int) BFD_RELOC_LO16, SP);
demand_empty_rest_of_line ();
/* Add $gp to the register named as an argument. */
reg = tc_get_register (0);
macro_build ((char *) NULL, &icnt, (expressionS *) NULL,
- mips_isa < 3 ? "addu" : "daddu",
+ mips_opts.isa < 3 ? "addu" : "daddu",
"d,v,t", reg, reg, GP);
demand_empty_rest_of_line ();
s_insn (ignore)
int ignore;
{
- if (mips16)
- {
- struct insn_label_list *l;
+ if (mips_opts.mips16)
+ mips16_mark_labels ();
- for (l = insn_labels; l != NULL; l = l->next)
- {
-#ifdef S_SET_OTHER
- if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
- S_SET_OTHER (l->label, STO_MIPS16);
-#endif
- ++l->label->sy_value.X_add_number;
- }
+ demand_empty_rest_of_line ();
+}
- mips_clear_insn_labels ();
- }
+/* Handle a .stabn directive. We need these in order to mark a label
+ as being a mips16 text label correctly. Sometimes the compiler
+ will emit a label, followed by a .stabn, and then switch sections.
+ If the label and .stabn are in mips16 mode, then the label is
+ really a mips16 text label. */
- demand_empty_rest_of_line ();
+static void
+s_mips_stab (type)
+ int type;
+{
+ if (type == 'n' && mips_opts.mips16)
+ mips16_mark_labels ();
+
+ s_stab (type);
}
/* Parse a register string into a number. Called from the ECOFF code