aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog4
-rw-r--r--gas/config/tc-mips.c258
2 files changed, 188 insertions, 74 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index fe40435..0416606 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,7 @@
+Mon Jun 2 11:55:12 1997 Gavin Koch <gavin@cygnus.com>
+
+ * config/tc-mips.c: Added r3900 support.
+
Thu May 29 12:58:26 1997 Ben Pfaff <pfaffben@pilot.msu.edu>
* as.c: (parse_args) `-t' option requires an argument.
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index 61623ae..5e92c73 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -204,11 +204,20 @@ static int mips_4100 = -1;
static int mips_5900 = -1;
/* end-sanitize-r5900 */
-/* Whether the processor uses hardware interlocks, and thus does not
+/* Whether Toshiba r3900 instructions are permitted. */
+static int mips_3900 = -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. */
+static int hilo_interlocks = -1;
+
+/* Whether the processor uses hardware interlocks to protect
+ reads from the GPRs, and thus does not
require nops to be inserted. */
-static int interlocks = -1;
+static int gpr_interlocks = -1;
-/* As with "interlocks" this is used by hardware that has FP
+/* As with other "interlocks" this is used by hardware that has FP
(co-processor) interlocks. */
/* Itbl support may require additional care here. */
static int cop_interlocks = -1;
@@ -787,6 +796,15 @@ md_begin ()
if (mips_cpu == -1)
mips_cpu = 3000;
}
+ else if (strcmp (cpu, "r3900") == 0
+ || strcmp (cpu, "mipsr3900") == 0)
+ {
+ mips_opts.isa = 1;
+ if (mips_cpu == -1)
+ mips_cpu = 3900;
+ if (mips_3900 == -1)
+ mips_3900 = 1;
+ }
else if (strcmp (cpu, "r6000") == 0
|| strcmp (cpu, "mips2") == 0)
{
@@ -916,10 +934,23 @@ md_begin ()
mips_5900 = 0;
/* end-sanitize-r5900 */
- if (mips_4010 || mips_cpu == 4300)
- interlocks = 1;
+ if (mips_3900 < 0)
+ mips_3900 = 0;
+
+ if (mips_4010
+ || mips_cpu == 4300
+ || mips_3900
+ )
+ hilo_interlocks = 1;
else
- interlocks = 0;
+ hilo_interlocks = 0;
+
+ if (mips_opts.isa >= 2
+ || mips_3900
+ )
+ gpr_interlocks = 1;
+ else
+ gpr_interlocks = 0;
/* Itbl support may require additional care here. */
if (mips_cpu == 4300)
@@ -1273,7 +1304,7 @@ reg_needs_delay (reg)
if (! mips_opts.noreorder
&& mips_opts.isa < 4
&& ((prev_pinfo & INSN_LOAD_COPROC_DELAY)
- || (mips_opts.isa < 2
+ || (! gpr_interlocks
&& (prev_pinfo & INSN_LOAD_MEMORY_DELAY))))
{
/* A load from a coprocessor or from memory. All load
@@ -1377,7 +1408,7 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
&& mips_opts.isa < 4
&& (((prev_pinfo & INSN_LOAD_COPROC_DELAY)
&& ! cop_interlocks)
- || (mips_opts.isa < 2
+ || (! gpr_interlocks
&& (prev_pinfo & INSN_LOAD_MEMORY_DELAY))))
{
/* A load from a coprocessor or from memory. All load
@@ -1472,7 +1503,7 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
/* 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 (! interlocks
+ if (! hilo_interlocks
&& (mips_optimize == 0
|| (pinfo & INSN_WRITE_LO)))
nops += 2;
@@ -1482,7 +1513,7 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_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 (! interlocks
+ if (! hilo_interlocks
&& (mips_optimize == 0
|| (pinfo & INSN_WRITE_HI)))
nops += 2;
@@ -1510,10 +1541,10 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
&& ! cop_interlocks)
|| ((prev_prev_insn.insn_mo->pinfo & INSN_READ_LO)
&& (pinfo & INSN_WRITE_LO)
- && ! interlocks)
+ && ! hilo_interlocks)
|| ((prev_prev_insn.insn_mo->pinfo & INSN_READ_HI)
&& (pinfo & INSN_WRITE_HI)
- && ! interlocks))
+ && ! hilo_interlocks))
prev_prev_nop = 1;
else
prev_prev_nop = 0;
@@ -1862,16 +1893,17 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
& (INSN_LOAD_COPROC_DELAY
| INSN_COPROC_MOVE_DELAY
| INSN_WRITE_COND_CODE)))
- || (! interlocks
+ || (! hilo_interlocks
&& (prev_pinfo
& (INSN_READ_LO
| INSN_READ_HI)))
|| (! mips_opts.mips16
+ && ! gpr_interlocks
+ && (prev_pinfo & INSN_LOAD_MEMORY_DELAY))
+ || (! mips_opts.mips16
&& mips_opts.isa < 2
- && (prev_pinfo
- & (INSN_LOAD_MEMORY_DELAY
- /* Itbl support may require additional care here. */
- | INSN_COPROC_MEMORY_DELAY)))
+ /* Itbl support may require additional care here. */
+ && (prev_pinfo & INSN_COPROC_MEMORY_DELAY))
/* We can not swap with a branch instruction. */
|| (prev_pinfo
& (INSN_UNCOND_BRANCH_DELAY
@@ -1977,7 +2009,7 @@ append_insn (place, ip, address_expr, reloc_type, unmatched_hi)
&& mips_opts.isa < 4
/* Itbl support may require additional care here. */
&& ((prev_prev_insn.insn_mo->pinfo & INSN_LOAD_COPROC_DELAY)
- || (mips_opts.isa < 2
+ || (! gpr_interlocks
&& (prev_prev_insn.insn_mo->pinfo
& INSN_LOAD_MEMORY_DELAY)))
&& insn_uses_reg (ip,
@@ -2183,15 +2215,18 @@ mips_emit_delays (insns)
& (INSN_LOAD_COPROC_DELAY
| INSN_COPROC_MOVE_DELAY
| INSN_WRITE_COND_CODE))))
- || (! interlocks
+ || (! hilo_interlocks
&& (prev_insn.insn_mo->pinfo
& (INSN_READ_LO
| INSN_READ_HI)))
|| (! mips_opts.mips16
+ && ! gpr_interlocks
+ && (prev_insn.insn_mo->pinfo
+ & INSN_LOAD_MEMORY_DELAY))
+ || (! mips_opts.mips16
&& mips_opts.isa < 2
&& (prev_insn.insn_mo->pinfo
- & (INSN_LOAD_MEMORY_DELAY
- | INSN_COPROC_MEMORY_DELAY))))
+ & INSN_COPROC_MEMORY_DELAY)))
{
/* Itbl support may require additional care here. */
++nops;
@@ -2199,7 +2234,7 @@ mips_emit_delays (insns)
&& mips_opts.isa < 4
&& (! cop_interlocks
&& prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE))
- || (! interlocks
+ || (! hilo_interlocks
&& ((prev_insn.insn_mo->pinfo & INSN_READ_HI)
|| (prev_insn.insn_mo->pinfo & INSN_READ_LO))))
++nops;
@@ -2211,7 +2246,7 @@ mips_emit_delays (insns)
&& mips_opts.isa < 4
&& (! cop_interlocks
&& prev_prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE))
- || (! interlocks
+ || (! hilo_interlocks
&& ((prev_prev_insn.insn_mo->pinfo & INSN_READ_HI)
|| (prev_prev_insn.insn_mo->pinfo & INSN_READ_LO))))
{
@@ -2324,20 +2359,22 @@ macro_build (place, counter, ep, name, fmt, va_alist)
while (strcmp (fmt, insn.insn_mo->args) != 0
|| insn.insn_mo->pinfo == INSN_MACRO
- || ((insn.insn_mo->pinfo & INSN_ISA) == INSN_ISA2
+ || ((insn.insn_mo->membership & INSN_ISA) == INSN_ISA2
&& mips_opts.isa < 2)
- || ((insn.insn_mo->pinfo & INSN_ISA) == INSN_ISA3
+ || ((insn.insn_mo->membership & INSN_ISA) == INSN_ISA3
&& mips_opts.isa < 3)
- || ((insn.insn_mo->pinfo & INSN_ISA) == INSN_ISA4
+ || ((insn.insn_mo->membership & INSN_ISA) == INSN_ISA4
&& mips_opts.isa < 4)
- || ((insn.insn_mo->pinfo & INSN_ISA) == INSN_4650
+ || ((insn.insn_mo->membership & INSN_ISA) == INSN_3900
+ && ! mips_3900)
+ || ((insn.insn_mo->membership & INSN_ISA) == INSN_4650
&& ! mips_4650)
- || ((insn.insn_mo->pinfo & INSN_ISA) == INSN_4010
+ || ((insn.insn_mo->membership & INSN_ISA) == INSN_4010
&& ! mips_4010)
- || ((insn.insn_mo->pinfo & INSN_ISA) == INSN_4100
+ || ((insn.insn_mo->membership & INSN_ISA) == INSN_4100
&& ! mips_4100)
/* start-sanitize-r5900 */
- || ((insn.insn_mo->pinfo & INSN_ISA) == INSN_5900
+ || ((insn.insn_mo->membership & INSN_ISA) == INSN_5900
&& ! mips_5900)
/* end-sanitize-r5900 */
)
@@ -2679,7 +2716,9 @@ set_at (counter, reg, unsignedp)
int reg;
int unsignedp;
{
- if (imm_expr.X_add_number >= -0x8000 && imm_expr.X_add_number < 0x8000)
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= -0x8000
+ && imm_expr.X_add_number < 0x8000)
macro_build ((char *) NULL, counter, &imm_expr,
unsignedp ? "sltiu" : "slti",
"t,r,j", AT, reg, (int) BFD_RELOC_LO16);
@@ -2699,7 +2738,9 @@ check_absolute_expr (ip, ex)
struct mips_cl_insn *ip;
expressionS *ex;
{
- if (ex->X_op != O_constant)
+ if (ex->X_op == O_big)
+ as_bad ("unsupported large constant");
+ else if (ex->X_op != O_constant)
as_warn ("Instruction %s requires absolute expression", ip->insn_mo->name);
}
@@ -3305,7 +3346,9 @@ macro (ip)
s = "daddiu";
s2 = "daddu";
do_addi:
- if (imm_expr.X_add_number >= -0x8000 && imm_expr.X_add_number < 0x8000)
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= -0x8000
+ && imm_expr.X_add_number < 0x8000)
{
macro_build ((char *) NULL, &icnt, &imm_expr, s, "t,r,j", treg, sreg,
(int) BFD_RELOC_LO16);
@@ -3331,7 +3374,9 @@ macro (ip)
s = "xori";
s2 = "xor";
do_bit:
- if (imm_expr.X_add_number >= 0 && imm_expr.X_add_number < 0x10000)
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= 0
+ && imm_expr.X_add_number < 0x10000)
{
if (mask != M_NOR_I)
macro_build ((char *) NULL, &icnt, &imm_expr, s, "t,r,i", treg,
@@ -3364,7 +3409,7 @@ macro (ip)
s = "bnel";
likely = 1;
beq_i:
- if (imm_expr.X_add_number == 0)
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
{
macro_build ((char *) NULL, &icnt, &offset_expr, s, "s,t,p", sreg,
0);
@@ -3402,14 +3447,15 @@ macro (ip)
case M_BGT_I:
/* check for > max integer */
maxnum = 0x7fffffff;
- if (mips_opts.isa >= 3)
+ if (mips_opts.isa >= 3 && sizeof (maxnum) > 4)
{
maxnum <<= 16;
maxnum |= 0xffff;
maxnum <<= 16;
maxnum |= 0xffff;
}
- if (imm_expr.X_add_number >= maxnum
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= maxnum
&& (mips_opts.isa < 3 || sizeof (maxnum) > 4))
{
do_false:
@@ -3427,20 +3473,22 @@ macro (ip)
}
return;
}
+ if (imm_expr.X_op != O_constant)
+ as_bad ("Unsupported large constant");
imm_expr.X_add_number++;
/* FALLTHROUGH */
case M_BGE_I:
case M_BGEL_I:
if (mask == M_BGEL_I)
likely = 1;
- if (imm_expr.X_add_number == 0)
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
{
macro_build ((char *) NULL, &icnt, &offset_expr,
likely ? "bgezl" : "bgez",
"s,p", sreg);
return;
}
- if (imm_expr.X_add_number == 1)
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
{
macro_build ((char *) NULL, &icnt, &offset_expr,
likely ? "bgtzl" : "bgtz",
@@ -3448,7 +3496,7 @@ macro (ip)
return;
}
maxnum = 0x7fffffff;
- if (mips_opts.isa >= 3)
+ if (mips_opts.isa >= 3 && sizeof (maxnum) > 4)
{
maxnum <<= 16;
maxnum |= 0xffff;
@@ -3456,7 +3504,8 @@ macro (ip)
maxnum |= 0xffff;
}
maxnum = - maxnum - 1;
- if (imm_expr.X_add_number <= maxnum
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number <= maxnum
&& (mips_opts.isa < 3 || sizeof (maxnum) > 4))
{
do_true:
@@ -3493,17 +3542,22 @@ macro (ip)
case M_BGTUL_I:
likely = 1;
case M_BGTU_I:
- if (sreg == 0 || imm_expr.X_add_number == -1)
+ if (sreg == 0
+ || (mips_opts.isa < 3
+ && imm_expr.X_op == O_constant
+ && imm_expr.X_add_number == 0xffffffff))
goto do_false;
+ if (imm_expr.X_op != O_constant)
+ as_bad ("Unsupported large constant");
imm_expr.X_add_number++;
/* FALLTHROUGH */
case M_BGEU_I:
case M_BGEUL_I:
if (mask == M_BGEUL_I)
likely = 1;
- if (imm_expr.X_add_number == 0)
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
goto do_true;
- if (imm_expr.X_add_number == 1)
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
{
macro_build ((char *) NULL, &icnt, &offset_expr,
likely ? "bnel" : "bne",
@@ -3585,30 +3639,33 @@ macro (ip)
likely = 1;
case M_BLE_I:
maxnum = 0x7fffffff;
- if (mips_opts.isa >= 3)
+ if (mips_opts.isa >= 3 && sizeof (maxnum) > 4)
{
maxnum <<= 16;
maxnum |= 0xffff;
maxnum <<= 16;
maxnum |= 0xffff;
}
- if (imm_expr.X_add_number >= maxnum
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= maxnum
&& (mips_opts.isa < 3 || sizeof (maxnum) > 4))
goto do_true;
+ if (imm_expr.X_op != O_constant)
+ as_bad ("Unsupported large constant");
imm_expr.X_add_number++;
/* FALLTHROUGH */
case M_BLT_I:
case M_BLTL_I:
if (mask == M_BLTL_I)
likely = 1;
- if (imm_expr.X_add_number == 0)
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
{
macro_build ((char *) NULL, &icnt, &offset_expr,
likely ? "bltzl" : "bltz",
"s,p", sreg);
return;
}
- if (imm_expr.X_add_number == 1)
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
{
macro_build ((char *) NULL, &icnt, &offset_expr,
likely ? "blezl" : "blez",
@@ -3643,17 +3700,22 @@ macro (ip)
case M_BLEUL_I:
likely = 1;
case M_BLEU_I:
- if (sreg == 0 || imm_expr.X_add_number == -1)
+ if (sreg == 0
+ || (mips_opts.isa < 3
+ && imm_expr.X_op == O_constant
+ && imm_expr.X_add_number == 0xffffffff))
goto do_true;
+ if (imm_expr.X_op != O_constant)
+ as_bad ("Unsupported large constant");
imm_expr.X_add_number++;
/* FALLTHROUGH */
case M_BLTU_I:
case M_BLTUL_I:
if (mask == M_BLTUL_I)
likely = 1;
- if (imm_expr.X_add_number == 0)
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
goto do_false;
- if (imm_expr.X_add_number == 1)
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
{
macro_build ((char *) NULL, &icnt, &offset_expr,
likely ? "beql" : "beq",
@@ -3812,7 +3874,7 @@ macro (ip)
s = "ddivu";
s2 = "mfhi";
do_divi:
- if (imm_expr.X_add_number == 0)
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
{
as_warn ("Divide by zero.");
if (mips_trap)
@@ -3821,7 +3883,7 @@ macro (ip)
macro_build ((char *) NULL, &icnt, NULL, "break", "c", 7);
return;
}
- if (imm_expr.X_add_number == 1)
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
{
if (strcmp (s2, "mflo") == 0)
macro_build ((char *) NULL, &icnt, NULL, "move", "d,s", dreg,
@@ -3830,7 +3892,8 @@ macro (ip)
macro_build ((char *) NULL, &icnt, NULL, "move", "d,s", dreg, 0);
return;
}
- if (imm_expr.X_add_number == -1
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number == -1
&& s[strlen (s) - 1] != 'u')
{
if (strcmp (s2, "mflo") == 0)
@@ -5636,6 +5699,8 @@ macro2 (ip)
break;
case M_ROL_I:
+ if (imm_expr.X_op != O_constant)
+ as_bad ("rotate count too large");
macro_build ((char *) NULL, &icnt, NULL, "sll", "d,w,<", AT, sreg,
(int) (imm_expr.X_add_number & 0x1f));
macro_build ((char *) NULL, &icnt, NULL, "srl", "d,w,<", dreg, sreg,
@@ -5652,6 +5717,8 @@ macro2 (ip)
break;
case M_ROR_I:
+ if (imm_expr.X_op != O_constant)
+ as_bad ("rotate count too large");
macro_build ((char *) NULL, &icnt, NULL, "srl", "d,w,<", AT, sreg,
(int) (imm_expr.X_add_number & 0x1f));
macro_build ((char *) NULL, &icnt, NULL, "sll", "d,w,<", dreg, sreg,
@@ -5689,7 +5756,7 @@ macro2 (ip)
return;
case M_SEQ_I:
- if (imm_expr.X_add_number == 0)
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
{
macro_build ((char *) NULL, &icnt, &expr1, "sltiu", "t,r,j", dreg,
sreg, (int) BFD_RELOC_LO16);
@@ -5702,13 +5769,17 @@ macro2 (ip)
macro_build ((char *) NULL, &icnt, NULL, "move", "d,s", dreg, 0);
return;
}
- if (imm_expr.X_add_number >= 0 && imm_expr.X_add_number < 0x10000)
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= 0
+ && imm_expr.X_add_number < 0x10000)
{
macro_build ((char *) NULL, &icnt, &imm_expr, "xori", "t,r,i", dreg,
sreg, (int) BFD_RELOC_LO16);
used_at = 0;
}
- else if (imm_expr.X_add_number > -0x8000 && imm_expr.X_add_number < 0)
+ else if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number > -0x8000
+ && imm_expr.X_add_number < 0)
{
imm_expr.X_add_number = -imm_expr.X_add_number;
macro_build ((char *) NULL, &icnt, &imm_expr,
@@ -5743,7 +5814,9 @@ macro2 (ip)
case M_SGE_I: /* sreg >= I <==> not (sreg < I) */
case M_SGEU_I:
- if (imm_expr.X_add_number >= -0x8000 && imm_expr.X_add_number < 0x8000)
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= -0x8000
+ && imm_expr.X_add_number < 0x8000)
{
macro_build ((char *) NULL, &icnt, &expr1,
mask == M_SGE_I ? "slti" : "sltiu",
@@ -5807,7 +5880,9 @@ macro2 (ip)
break;
case M_SLT_I:
- if (imm_expr.X_add_number >= -0x8000 && imm_expr.X_add_number < 0x8000)
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= -0x8000
+ && imm_expr.X_add_number < 0x8000)
{
macro_build ((char *) NULL, &icnt, &imm_expr, "slti", "t,r,j",
dreg, sreg, (int) BFD_RELOC_LO16);
@@ -5818,7 +5893,9 @@ macro2 (ip)
break;
case M_SLTU_I:
- if (imm_expr.X_add_number >= -0x8000 && imm_expr.X_add_number < 0x8000)
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= -0x8000
+ && imm_expr.X_add_number < 0x8000)
{
macro_build ((char *) NULL, &icnt, &imm_expr, "sltiu", "t,r,j",
dreg, sreg, (int) BFD_RELOC_LO16);
@@ -5846,7 +5923,7 @@ macro2 (ip)
return;
case M_SNE_I:
- if (imm_expr.X_add_number == 0)
+ if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
{
macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", dreg, 0,
sreg);
@@ -5861,13 +5938,17 @@ macro2 (ip)
"t,r,j", dreg, 0, (int) BFD_RELOC_LO16);
return;
}
- if (imm_expr.X_add_number >= 0 && imm_expr.X_add_number < 0x10000)
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number >= 0
+ && imm_expr.X_add_number < 0x10000)
{
macro_build ((char *) NULL, &icnt, &imm_expr, "xori", "t,r,i",
dreg, sreg, (int) BFD_RELOC_LO16);
used_at = 0;
}
- else if (imm_expr.X_add_number > -0x8000 && imm_expr.X_add_number < 0)
+ else if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number > -0x8000
+ && imm_expr.X_add_number < 0)
{
imm_expr.X_add_number = -imm_expr.X_add_number;
macro_build ((char *) NULL, &icnt, &imm_expr,
@@ -5890,7 +5971,9 @@ macro2 (ip)
case M_DSUB_I:
dbl = 1;
case M_SUB_I:
- if (imm_expr.X_add_number > -0x8000 && imm_expr.X_add_number <= 0x8000)
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number > -0x8000
+ && imm_expr.X_add_number <= 0x8000)
{
imm_expr.X_add_number = -imm_expr.X_add_number;
macro_build ((char *) NULL, &icnt, &imm_expr,
@@ -5907,7 +5990,9 @@ macro2 (ip)
case M_DSUBU_I:
dbl = 1;
case M_SUBU_I:
- if (imm_expr.X_add_number > -0x8000 && imm_expr.X_add_number <= 0x8000)
+ if (imm_expr.X_op == O_constant
+ && imm_expr.X_add_number > -0x8000
+ && imm_expr.X_add_number <= 0x8000)
{
imm_expr.X_add_number = -imm_expr.X_add_number;
macro_build ((char *) NULL, &icnt, &imm_expr,
@@ -6284,6 +6369,8 @@ mips16_macro (ip)
goto do_subu;
case M_SUBU_I:
do_subu:
+ if (imm_expr.X_op != O_constant)
+ as_bad ("Unsupported large constant");
imm_expr.X_add_number = -imm_expr.X_add_number;
macro_build ((char *) NULL, &icnt, &imm_expr,
dbl ? "daddiu" : "addiu",
@@ -6291,12 +6378,16 @@ mips16_macro (ip)
break;
case M_SUBU_I_2:
+ if (imm_expr.X_op != O_constant)
+ as_bad ("Unsupported large constant");
imm_expr.X_add_number = -imm_expr.X_add_number;
macro_build ((char *) NULL, &icnt, &imm_expr, "addiu",
"x,k", xreg);
break;
case M_DSUBU_I_2:
+ if (imm_expr.X_op != O_constant)
+ as_bad ("Unsupported large constant");
imm_expr.X_add_number = -imm_expr.X_add_number;
macro_build ((char *) NULL, &icnt, &imm_expr, "daddiu",
"y,j", yreg);
@@ -6404,6 +6495,8 @@ mips16_macro (ip)
s3 = "x,8";
do_addone_branch_i:
+ if (imm_expr.X_op != O_constant)
+ as_bad ("Unsupported large constant");
++imm_expr.X_add_number;
do_branch_i:
@@ -6464,28 +6557,30 @@ mips_ip (str, ip)
if (insn->pinfo == INSN_MACRO)
insn_isa = insn->match;
- else if ((insn->pinfo & INSN_ISA) == INSN_ISA2)
+ else if ((insn->membership & INSN_ISA) == INSN_ISA2)
insn_isa = 2;
- else if ((insn->pinfo & INSN_ISA) == INSN_ISA3)
+ else if ((insn->membership & INSN_ISA) == INSN_ISA3)
insn_isa = 3;
- else if ((insn->pinfo & INSN_ISA) == INSN_ISA4)
+ else if ((insn->membership & INSN_ISA) == INSN_ISA4)
insn_isa = 4;
else
insn_isa = 1;
if (insn_isa > mips_opts.isa
|| (insn->pinfo != INSN_MACRO
- && (((insn->pinfo & INSN_ISA) == INSN_4650
- && ! mips_4650)
- || ((insn->pinfo & INSN_ISA) == INSN_4010
+ && (((insn->membership & INSN_ISA) == INSN_4650
+ && ! mips_4650)
+ || ((insn->membership & INSN_ISA) == INSN_4010
&& ! mips_4010)
- || ((insn->pinfo & INSN_ISA) == INSN_4100
+ || ((insn->membership & INSN_ISA) == INSN_4100
&& ! mips_4100)
/* start-sanitize-r5900 */
- || ((insn->pinfo & INSN_ISA) == INSN_5900
+ || ((insn->membership & INSN_ISA) == INSN_5900
&& ! mips_5900)
/* end-sanitize-r5900 */
- )))
+ || ((insn->membership & INSN_ISA) == INSN_3900
+ && ! mips_3900)
+ )))
{
if (insn + 1 < &mips_opcodes[NUMOPCODES]
&& strcmp (insn->name, insn[1].name) == 0)
@@ -8224,6 +8319,11 @@ struct option md_longopts[] = {
#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},
+
#define OPTION_CALL_SHARED (OPTION_MD_BASE + 7)
#define OPTION_NON_SHARED (OPTION_MD_BASE + 8)
@@ -8355,6 +8455,8 @@ md_parse_option (c, arg)
|| strcmp (p, "3k") == 0
|| strcmp (p, "3K") == 0)
mips_cpu = 3000;
+ else if (strcmp (p, "3900") == 0)
+ mips_cpu = 3900;
break;
case '4':
@@ -8468,6 +8570,14 @@ md_parse_option (c, arg)
break;
/* end-sanitize-r5900 */
+ case OPTION_M3900:
+ mips_3900 = 1;
+ break;
+
+ case OPTION_NO_M3900:
+ mips_3900 = 0;
+ break;
+
case OPTION_MIPS16:
mips_opts.mips16 = 1;
mips_no_prev_insn (false);