#endif
#define ZERO 0
-#define AT 1
+#define ATREG 1
#define TREG 24
#define PIC_CALL_REG 25
#define KT0 26
#define ILLEGAL_REG (32)
+#define AT mips_opts.at
+
/* Allow override of standard little-endian ECOFF format. */
#ifndef ECOFF_LITTLE_FORMAT
/* 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 not permit the register designated "assembler
+ temporary" to be used in instructions. The value is the register
+ number, normally $at ($1). Changed by `.set at=REG', `.set noat'
+ (same as `.set at=$0') and `.set at' (same as `.set at=$1'). */
+ unsigned int at;
/* Non-zero if we should warn when a macro instruction expands into
more than one machine instruction. Changed by `.set nomacro' and
`.set macro'. */
static struct mips_set_options mips_opts =
{
- ISA_UNKNOWN, -1, -1, 0, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, CPU_UNKNOWN, FALSE
+ ISA_UNKNOWN, -1, -1, 0, -1, -1, -1, -1, 0, ATREG, 0, 0, 0, 0, 0, 0, CPU_UNKNOWN, FALSE
};
/* These variables are filled in with the masks of registers used.
/* Relatively generic pseudo-ops that happen to be used on MIPS
chips. */
- {"asciiz", stringer, 1},
+ {"asciiz", stringer, 8 + 1},
{"bss", s_change_sec, 'b'},
{"err", s_err, 0},
{"half", s_cons, 1},
.set noat if we use $at for PIC computations. If it turns
out that the branch was out-of-range, we'll get an error. */
&& !mips_opts.warn_about_macros
- && !(mips_opts.noat && mips_pic != NO_PIC)
+ && (mips_opts.at || mips_pic == NO_PIC)
&& !mips_opts.mips16)
{
relaxed_branch = TRUE;
macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", AT, AT, breg);
macro_build (ep, op, "t,o(b)", treg, BFD_RELOC_LO16, AT);
- if (mips_opts.noat)
+ if (!mips_opts.at)
as_bad (_("Macro used $at after \".set noat\""));
}
}
relax_switch ();
}
- if (*used_at == 0 && !mips_opts.noat)
+ if (*used_at == 0 && mips_opts.at)
{
macro_build (ep, "lui", "t,u", reg, BFD_RELOC_MIPS_HIGHEST);
macro_build (ep, "lui", "t,u", AT, BFD_RELOC_HI16_S);
else
abort ();
- if (mips_opts.noat && *used_at == 1)
+ if (!mips_opts.at && *used_at == 1)
as_bad (_("Macro used $at after \".set noat\""));
}
static void
macro (struct mips_cl_insn *ip)
{
- int treg, sreg, dreg, breg;
- int tempreg;
+ unsigned int treg, sreg, dreg, breg;
+ unsigned int tempreg;
int mask;
int used_at = 0;
expressionS expr1;
break;
}
- if (!mips_opts.noat && (treg == breg))
+ if (mips_opts.at && (treg == breg))
{
tempreg = AT;
used_at = 1;
relax_switch ();
}
- if (used_at == 0 && !mips_opts.noat)
+ if (used_at == 0 && mips_opts.at)
{
macro_build (&offset_expr, "lui", "t,u",
tempreg, BFD_RELOC_MIPS_HIGHEST);
relax_switch ();
}
- if (used_at == 0 && !mips_opts.noat)
+ if (used_at == 0 && mips_opts.at)
{
macro_build (&offset_expr, "lui", "t,u", tempreg,
BFD_RELOC_MIPS_HIGHEST);
macro2 (ip);
break;
}
- if (mips_opts.noat && used_at)
+ if (!mips_opts.at && used_at)
as_bad (_("Macro used $at after \".set noat\""));
}
static void
macro2 (struct mips_cl_insn *ip)
{
- int treg, sreg, dreg, breg;
- int tempreg;
+ unsigned int treg, sreg, dreg, breg;
+ unsigned int tempreg;
int mask;
int used_at;
expressionS expr1;
as_bad (_("Macro %s not implemented yet"), ip->insn_mo->name);
break;
}
- if (mips_opts.noat && used_at)
+ if (!mips_opts.at && used_at)
as_bad (_("Macro used $at after \".set noat\""));
}
else
{
ok = reg_lookup (&s, RTYPE_NUM | RTYPE_GP, ®no);
- if (regno == AT && ! mips_opts.noat)
- as_warn ("Used $at without \".set noat\"");
+ if (regno == AT && mips_opts.at)
+ {
+ if (mips_opts.at == ATREG)
+ as_warn (_("used $at without \".set noat\""));
+ else
+ as_warn (_("used $%u with \".set at=$%u\""),
+ regno, mips_opts.at);
+ }
}
if (ok)
{
case 'X':
case 'Y':
- if (regno == AT && ! mips_opts.noat)
- as_warn (_("used $at without \".set noat\""));
+ if (regno == AT && mips_opts.at)
+ {
+ if (mips_opts.at == ATREG)
+ as_warn (_("used $at without \".set noat\""));
+ else
+ as_warn (_("used $%u with \".set at=$%u\""),
+ regno, mips_opts.at);
+ }
break;
default:
S_SET_VALUE (ep->X_add_symbol, val + 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
- returned, or NULL on OK. */
-
char *
md_atof (int type, char *litP, int *sizeP)
{
- int prec;
- LITTLENUM_TYPE words[4];
- char *t;
- int i;
-
- switch (type)
- {
- case 'f':
- prec = 2;
- break;
-
- case 'd':
- prec = 4;
- break;
-
- default:
- *sizeP = 0;
- return _("bad call to md_atof");
- }
-
- t = atof_ieee (input_line_pointer, type, words);
- if (t)
- input_line_pointer = t;
-
- *sizeP = prec * 2;
-
- if (! target_big_endian)
- {
- for (i = prec - 1; i >= 0; i--)
- {
- md_number_to_chars (litP, words[i], 2);
- litP += 2;
- }
- }
- else
- {
- for (i = 0; i < prec; i++)
- {
- md_number_to_chars (litP, words[i], 2);
- litP += 2;
- }
- }
-
- return NULL;
+ return ieee_md_atof (type, litP, sizeP, target_big_endian);
}
void
break;
case 'O':
- if (arg && arg[0] == '0')
+ if (arg == NULL)
+ mips_optimize = 1;
+ else if (arg[0] == '0')
+ mips_optimize = 0;
+ else if (arg[0] == '1')
mips_optimize = 1;
else
mips_optimize = 2;
{
int temp;
long temp_fill;
- long max_alignment = 15;
+ long max_alignment = 28;
/* o Note that the assembler pulls down any immediately preceding label
to the aligned address.
if (!mips_opts.noreorder)
start_noreorder ();
}
+ else if (strncmp (name, "at=", 3) == 0)
+ {
+ char *s = name + 3;
+
+ if (!reg_lookup (&s, RTYPE_NUM | RTYPE_GP, &mips_opts.at))
+ as_bad (_("Unrecognized register name `%s'"), s);
+ }
else if (strcmp (name, "at") == 0)
{
- mips_opts.noat = 0;
+ mips_opts.at = ATREG;
}
else if (strcmp (name, "noat") == 0)
{
- mips_opts.noat = 1;
+ mips_opts.at = ZERO;
}
else if (strcmp (name, "macro") == 0)
{
{ "sb1a", MIPS_CPU_ASE_MIPS3D | MIPS_CPU_ASE_MDMX,
ISA_MIPS64, CPU_SB1 },
+ /* ST Microelectronics Loongson 2E and 2F cores */
+ { "loongson2e", 0, ISA_MIPS3, CPU_LOONGSON_2E },
+ { "loongson2f", 0, ISA_MIPS3, CPU_LOONGSON_2F },
+
/* End marker */
{ NULL, 0, 0, 0 }
};