#define GPOPT
#endif
+/* The default target format to use. */
+#ifdef OBJ_AOUT
+#ifdef TARGET_BYTES_BIG_ENDIAN
+#define DEFAULT_TARGET_FORMAT "a.out-mips-big"
+#else
+#define DEFAULT_TARGET_FORMAT "a.out-mips-little"
+#endif
+#endif /* OBJ_AOUT */
+#ifdef OBJ_ECOFF
+#ifdef TARGET_BYTES_BIG_ENDIAN
+#define DEFAULT_TARGET_FORMAT "ecoff-bigmips"
+#else
+#define DEFAULT_TARGET_FORMAT "ecoff-littlemips"
+#endif
+#endif /* OBJ_ECOFF */
+#ifdef OBJ_ELF
+#ifdef TARGET_BYTES_BIG_ENDIAN
+#define DEFAULT_TARGET_FORMAT "elf32-bigmips"
+#else
+#define DEFAULT_TARGET_FORMAT "elf32-littlemips"
+#endif
+#endif /* OBJ_ELF */
+
+const char *mips_target_format = DEFAULT_TARGET_FORMAT;
+
/* 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. */
+/* 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;
+
/* MIPS PIC level. 0 is normal, non-PIC code. 2 means to generate
SVR4 ABI PIC calls. 1 doesn't mean anything. */
static int mips_pic;
#ifdef GPOPT
/* The size of the small data section. */
static int g_switch_value = 8;
+/* Whether the -G option was used. */
+static int g_switch_seen = 0;
#endif
#define N_RMASK 0xc4
{"double", s_float_cons, 'd'},
{"extern", s_extern, 0},
{"float", s_float_cons, 'f'},
+ {"hword", s_cons, 1},
+ {"int", s_cons, 2},
+ {"long", s_cons, 2},
+ {"octa", s_cons, 4},
+ {"quad", s_cons, 3},
+ {"short", s_cons, 1},
+ {"single", s_float_cons, 'f'},
{"space", s_mips_space, 0},
{"text", s_change_sec, 't'},
{"word", s_cons, 2},
{ 0 }
};
-
static char *expr_end;
static expressionS imm_expr;
if (! ok)
as_warn ("Could not set architecture and machine");
+ file_mips_isa = mips_isa;
+
op_hash = hash_new ();
for (i = 0; i < NUMOPCODES;)
subseg = now_subseg;
sec = subseg_new (".reginfo", (subsegT) 0);
- /* I don't know why this section should be loaded, but the ABI
- says that SHF_ALLOC should be set. */
+ /* The ABI says this section should be loaded so that the running
+ program can access it. */
(void) bfd_set_section_flags (stdoutput, sec,
(SEC_ALLOC | SEC_LOAD
| SEC_READONLY | SEC_DATA));
|| r == BFD_RELOC_MIPS_LITERAL
|| r == BFD_RELOC_LO16
|| r == BFD_RELOC_MIPS_GOT16
- || r== BFD_RELOC_MIPS_CALL16);
+ || r == BFD_RELOC_MIPS_CALL16);
continue;
case 'u':
/* If this is a reference to a GP relative symbol, we want
addiu $reg,$gp,<sym> (BFD_RELOC_MIPS_GPREL)
Otherwise we want
- lui $reg,$gp,<sym> (BFD_RELOC_HI16_S)
+ lui $reg,<sym> (BFD_RELOC_HI16_S)
addiu $reg,$reg,<sym> (BFD_RELOC_LO16)
If we have an addend, we always use the latter form. */
if (ep->X_add_number != 0)
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),
+ (mips_warn_about_macros
+ || (used_at && mips_noat))),
offset_expr.X_add_symbol, (long) 0,
(char *) NULL);
+ used_at = 0;
}
macro_build_lui (p, &icnt, &offset_expr, tempreg);
if (p != NULL)
(int) BFD_RELOC_MIPS_GPREL, tempreg);
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_noat),
offset_expr.X_add_symbol, (long) 0,
(char *) NULL);
++insn;
continue;
}
- insn_error = "ERROR: instruction not supported on this processor";
- return;
+ as_warn ("Instruction not supported on this processor");
}
ip->insn_mo = insn;
if (strcmp (*argP, "EL") == 0
|| strcmp (*argP, "EB") == 0)
{
+ if ((*argP)[1] == 'B')
+ byte_order = BIG_ENDIAN;
+ else
+ byte_order = LITTLE_ENDIAN;
+
+#ifdef OBJ_AOUT
+ if ((*argP)[1] == 'B')
+ mips_target_format = "a.out-mips-big";
+ else
+ mips_target_format = "a.out-mips-little";
+#endif
+#ifdef OBJ_ECOFF
+ if ((*argP)[1] == 'B')
+ mips_target_format = "ecoff-bigmips";
+ else
+ mips_target_format = "ecoff-littlemips";
+#endif
+#ifdef OBJ_ELF
+ if ((*argP)[1] == 'B')
+ mips_target_format = "elf32-bigmips";
+ else
+ mips_target_format = "elf32-littlemips";
+#endif
+
/* FIXME: This breaks -L -EL. */
flagseen['L'] = 0;
*argP = "";
}
else
as_warn ("Number expected after -G");
+ g_switch_seen = 1;
*argP = "";
return 1;
}
mips_pic = atoi (opt + 3);
/* Supposedly no other values are used. */
assert (mips_pic == 0 || mips_pic == 2);
+
+ if (mips_pic == 2)
+ {
+ if (g_switch_seen && g_switch_value != 0)
+ as_warn ("-G may not be used with PIC code");
+ g_switch_value = 0;
+ bfd_set_gp_size (stdoutput, 0);
+ }
}
else
as_warn ("Unrecognized option \"%s\"", opt);
{
mips_nobopt = 1;
}
+ else if (strncmp (name, "mips", 4) == 0)
+ {
+ int isa;
+
+ /* Permit the user to change the ISA on the fly. Needless to
+ say, misuse can cause serious problems. */
+ isa = atoi (name + 4);
+ if (isa == 0)
+ mips_isa = file_mips_isa;
+ else if (isa < 1 || isa > 3)
+ as_bad ("unknown ISA level");
+ else
+ mips_isa = isa;
+ }
else
{
as_warn ("Tried to set unrecognized symbol: %s\n", name);