\f
static char *expr_end;
-/* Expressions which appear in macro instructions. These are set by
- mips_ip and read by macro. */
+/* An expression in a macro instruction. This is set by mips_ip and
+ mips16_ip and when populated is always an O_constant. */
static expressionS imm_expr;
-static expressionS imm2_expr;
/* The relocatable field in an instruction and the relocs associated
with it. These variables are used for instructions like LUI and
base = mips_opts.micromips ? "microMIPS" : "MIPS";
size = ISA_HAS_64BIT_REGS (mips_opts.isa) ? 64 : 32;
if (min_rev < 0)
- as_warn (_("The %d-bit %s architecture does not support the"
+ as_warn (_("the %d-bit %s architecture does not support the"
" `%s' extension"), size, base, ase->name);
else
- as_warn (_("The `%s' extension requires %s%d revision %d or greater"),
+ as_warn (_("the `%s' extension requires %s%d revision %d or greater"),
ase->name, base, size, min_rev);
}
if ((ase->flags & FP64_ASES)
&& (warned_fp32 & ase->flags) != ase->flags)
{
warned_fp32 |= ase->flags;
- as_warn (_("The `%s' extension requires 64-bit FPRs"), ase->name);
+ as_warn (_("the `%s' extension requires 64-bit FPRs"), ase->name);
}
}
else
{
if (types & RWARN)
- as_warn (_("Unrecognized register name `%s'"), *s);
+ as_warn (_("unrecognized register name `%s'"), *s);
regno = ~0;
}
if (regnop)
SKIP_SPACE_TABS (s);
if (!mips_parse_register (&s, ®no2, NULL))
{
- set_insn_error (0, _("Invalid register range"));
+ set_insn_error (0, _("invalid register range"));
return 0;
}
my_getExpression (&element, s);
if (element.X_op != O_constant)
{
- set_insn_error (0, _("Vector element must be constant"));
+ set_insn_error (0, _("vector element must be constant"));
return 0;
}
s = expr_end;
SKIP_SPACE_TABS (s);
if (*s != ']')
{
- set_insn_error (0, _("Missing `]'"));
+ set_insn_error (0, _("missing `]'"));
return 0;
}
++s;
length = micromips_insn_length (opc);
if (length != 2 && length != 4)
{
- as_bad (_("Internal error: bad microMIPS opcode (incorrect length: %u): "
+ as_bad (_("internal error: bad microMIPS opcode (incorrect length: %u): "
"%s %s"), length, opc->name, opc->args);
return 0;
}
if ((length == 2 && (major & 7) != 1 && (major & 6) != 2)
|| (length == 4 && (major & 7) != 0 && (major & 4) != 4))
{
- as_bad (_("Internal error: bad microMIPS opcode "
+ as_bad (_("internal error: bad microMIPS opcode "
"(opcode/length mismatch): %s %s"), opc->name, opc->args);
return 0;
}
}
if (! bfd_set_arch_mach (stdoutput, bfd_arch_mips, file_mips_arch))
- as_warn (_("Could not set architecture and machine"));
+ as_warn (_("could not set architecture and machine"));
op_hash = hash_new ();
fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
mips_opcodes[i].name, retval);
/* Probably a memory allocation problem? Give up now. */
- as_fatal (_("Broken assembler. No assembly attempted."));
+ as_fatal (_("broken assembler, no assembly attempted"));
}
do
{
}
if (broken)
- as_fatal (_("Broken assembler. No assembly attempted."));
+ as_fatal (_("broken assembler, no assembly attempted"));
/* We add all the general register names to the symbol table. This
helps us detect invalid uses of them. */
= {BFD_RELOC_UNUSED, BFD_RELOC_UNUSED, BFD_RELOC_UNUSED};
imm_expr.X_op = O_absent;
- imm2_expr.X_op = O_absent;
offset_expr.X_op = O_absent;
offset_reloc[0] = BFD_RELOC_UNUSED;
offset_reloc[1] = BFD_RELOC_UNUSED;
return FALSE;
}
-/* Report that user-supplied argument ARGNUM for INSN was VAL, but should
- have been in the range [MIN_VAL, MAX_VAL]. PRINT_HEX says whether
- this operand is normally printed in hex or decimal. */
-
-static void
-report_bad_range (struct mips_cl_insn *insn, int argnum,
- offsetT val, int min_val, int max_val,
- bfd_boolean print_hex)
-{
- if (print_hex && val >= 0)
- as_bad (_("Operand %d of `%s' must be in the range [0x%x, 0x%x],"
- " was 0x%lx."),
- argnum, insn->insn_mo->name, min_val, max_val, (unsigned long) val);
- else if (print_hex)
- as_bad (_("Operand %d of `%s' must be in the range [0x%x, 0x%x],"
- " was %ld."),
- argnum, insn->insn_mo->name, min_val, max_val, (unsigned long) val);
- else
- as_bad (_("Operand %d of `%s' must be in the range [%d, %d],"
- " was %ld."),
- argnum, insn->insn_mo->name, min_val, max_val, (unsigned long) val);
-}
-
-/* Report an invalid combination of position and size operands for a bitfield
- operation. POS and SIZE are the values that were given. */
-
-static void
-report_bad_field (offsetT pos, offsetT size)
-{
- as_bad (_("Invalid field specification (position %ld, size %ld)"),
- (unsigned long) pos, (unsigned long) size);
-}
-
/* Information about an instruction argument that we're trying to match. */
struct mips_arg_info
{
where it gives the lsb position. */
unsigned int last_op_int;
- /* If true, the OP_INT match routine should treat plain symbolic operands
- as if a relocation operator like %lo(...) had been used. This is only
- ever true if the operand can be relocated. */
- bfd_boolean allow_nonconst;
-
- /* When true, the OP_INT match routine should allow unsigned N-bit
- arguments to be used where a signed N-bit operand is expected. */
- bfd_boolean lax_max;
+ /* If true, match routines should assume that no later instruction
+ alternative matches and should therefore be as accomodating as
+ possible. Match routines should not report errors if something
+ is only invalid for !LAX_MATCH. */
+ bfd_boolean lax_match;
/* True if a reference to the current AT register was seen. */
bfd_boolean seen_at;
match_expression (struct mips_arg_info *arg, expressionS *value,
bfd_reloc_code_real_type *r)
{
- if (arg->token->type == OT_INTEGER)
+ /* If the next token is a '(' that was parsed as being part of a base
+ expression, assume we have an elided offset. The later match will fail
+ if this turns out to be wrong. */
+ if (arg->token->type == OT_CHAR && arg->token->u.ch == '(')
{
- *value = arg->token->u.integer.value;
- memcpy (r, arg->token->u.integer.relocs, 3 * sizeof (*r));
- ++arg->token;
+ value->X_op = O_constant;
+ value->X_add_number = 0;
+ r[0] = r[1] = r[2] = BFD_RELOC_UNUSED;
return TRUE;
}
- /* Error-reporting is more consistent if we treat registers as O_register
- rather than rejecting them outright. "$1", "($1)" and "(($1))" are
- then handled in the same way. */
- if (arg->token->type == OT_REG)
+ /* Reject register-based expressions such as "0+$2" and "(($2))".
+ For plain registers the default error seems more appropriate. */
+ if (arg->token->type == OT_INTEGER
+ && arg->token->u.integer.value.X_op == O_register)
{
- value->X_add_number = arg->token->u.regno;
- ++arg->token;
+ set_insn_error (arg->argnum, _("register value used as expression"));
+ return FALSE;
}
- else if (arg->token[0].type == OT_CHAR
- && arg->token[0].u.ch == '('
- && arg->token[1].type == OT_REG
- && arg->token[2].type == OT_CHAR
- && arg->token[2].u.ch == ')')
+
+ if (arg->token->type == OT_INTEGER)
{
- value->X_add_number = arg->token[1].u.regno;
- arg->token += 3;
+ *value = arg->token->u.integer.value;
+ memcpy (r, arg->token->u.integer.relocs, 3 * sizeof (*r));
+ ++arg->token;
+ return TRUE;
}
- else
- return FALSE;
- value->X_op = O_register;
- r[0] = r[1] = r[2] = BFD_RELOC_UNUSED;
- return TRUE;
+ set_insn_error_i
+ (arg->argnum, _("operand %d must be an immediate expression"),
+ arg->argnum);
+ return FALSE;
}
/* Try to get a constant expression from the next tokens in ARG. Consume
&& (regno & 1) != 0
&& HAVE_32BIT_FPRS
&& !mips_oddfpreg_ok (arg->insn->insn_mo, arg->opnum))
- as_warn (_("Float register should be even, was %d"), regno);
+ as_warn (_("float register should be even, was %d"), regno);
if (type == OP_REG_CCC)
{
if ((regno & 1) != 0
&& ((length >= 3 && strcmp (name + length - 3, ".ps") == 0)
|| (length >= 5 && strncmp (name + length - 5, "any2", 4) == 0)))
- as_warn (_("Condition code register should be even for %s, was %d"),
+ as_warn (_("condition code register should be even for %s, was %d"),
name, regno);
if ((regno & 3) != 0
&& (length >= 5 && strncmp (name + length - 5, "any4", 4) == 0))
- as_warn (_("Condition code register should be 0 or 4 for %s, was %d"),
+ as_warn (_("condition code register should be 0 or 4 for %s, was %d"),
name, regno);
}
}
factor = 1 << operand->shift;
min_val = mips_int_operand_min (operand);
max_val = mips_int_operand_max (operand);
- if (arg->lax_max)
- max_val = ((1 << operand_base->size) - 1) << operand->shift;
- if (arg->token->type == OT_CHAR && arg->token->u.ch == '(')
- /* Assume we have an elided offset. The later match will fail
- if this turns out to be wrong. */
- sval = 0;
- else if (operand_base->lsb == 0
- && operand_base->size == 16
- && operand->shift == 0
- && operand->bias == 0
- && (operand->max_val == 32767 || operand->max_val == 65535))
+ if (operand_base->lsb == 0
+ && operand_base->size == 16
+ && operand->shift == 0
+ && operand->bias == 0
+ && (operand->max_val == 32767 || operand->max_val == 65535))
{
/* The operand can be relocated. */
if (!match_expression (arg, &offset_expr, offset_reloc))
if (offset_expr.X_op != O_constant)
{
- /* If non-constant operands are allowed then leave them for
- the caller to process, otherwise fail the match. */
- if (!arg->allow_nonconst)
- {
- match_not_constant (arg);
- return FALSE;
- }
+ /* Accept non-constant operands if no later alternative matches,
+ leaving it for the caller to process. */
+ if (!arg->lax_match)
+ return FALSE;
offset_reloc[0] = BFD_RELOC_LO16;
return TRUE;
}
ourselves. */
sval = offset_expr.X_add_number;
offset_expr.X_op = O_absent;
+
+ /* For compatibility with older assemblers, we accept
+ 0x8000-0xffff as signed 16-bit numbers when only
+ signed numbers are allowed. */
+ if (sval > max_val)
+ {
+ max_val = ((1 << operand_base->size) - 1) << operand->shift;
+ if (!arg->lax_match && sval <= max_val)
+ return FALSE;
+ }
}
else
{
else
record_alignment (new_seg, length == 4 ? 2 : 3);
if (seg == now_seg)
- as_bad (_("Can't use floating point insn in this section"));
+ as_bad (_("cannot use `%s' in this section"), arg->insn->insn_mo->name);
/* Set the argument to the current address in the section. */
imm->X_op = O_absent;
if (arg->seen_at)
{
if (AT == ATREG)
- as_warn (_("Used $at without \".set noat\""));
+ as_warn (_("used $at without \".set noat\""));
else
- as_warn (_("Used $%u with \".set at=$%u\""), AT, AT);
+ as_warn (_("used $%u with \".set at=$%u\""), AT, AT);
}
}
&& micromips_insn_length (ip->insn_mo) != 2)
|| ((prev_pinfo2 & INSN2_BRANCH_DELAY_32BIT) != 0
&& micromips_insn_length (ip->insn_mo) != 4)))
- as_warn (_("Wrong size instruction in a %u-bit branch delay slot"),
+ as_warn (_("wrong size instruction in a %u-bit branch delay slot"),
(prev_pinfo2 & INSN2_BRANCH_DELAY_16BIT) != 0 ? 16 : 32);
if (address_expr == NULL)
static bfd_boolean
match_insn (struct mips_cl_insn *insn, const struct mips_opcode *opcode,
struct mips_operand_token *tokens, unsigned int opcode_extra,
- bfd_boolean more_alts)
+ bfd_boolean lax_match, bfd_boolean complete_p)
{
const char *args;
struct mips_arg_info arg;
char c;
imm_expr.X_op = O_absent;
- imm2_expr.X_op = O_absent;
offset_expr.X_op = O_absent;
offset_reloc[0] = BFD_RELOC_UNUSED;
offset_reloc[1] = BFD_RELOC_UNUSED;
offset_reloc[2] = BFD_RELOC_UNUSED;
create_insn (insn, opcode);
- insn->insn_opcode |= opcode_extra;
+ /* When no opcode suffix is specified, assume ".xyzw". */
+ if ((opcode->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX) != 0 && opcode_extra == 0)
+ insn->insn_opcode |= 0xf << mips_vu0_channel_mask.lsb;
+ else
+ insn->insn_opcode |= opcode_extra;
memset (&arg, 0, sizeof (arg));
arg.insn = insn;
arg.token = tokens;
arg.argnum = 1;
arg.last_regno = ILLEGAL_REG;
arg.dest_regno = ILLEGAL_REG;
+ arg.lax_match = lax_match;
for (args = opcode->args;; ++args)
{
if (arg.token->type == OT_END)
return FALSE;
/* Successful match. */
+ if (!complete_p)
+ return TRUE;
clear_insn_error ();
if (arg.dest_regno == arg.last_regno
&& strncmp (insn->insn_mo->name, "jalr", 4) == 0)
{
if (arg.opnum == 2)
set_insn_error
- (0, _("Source and destination must be different"));
+ (0, _("source and destination must be different"));
else if (arg.last_regno == 31)
set_insn_error
- (0, _("A destination register must be supplied"));
+ (0, _("a destination register must be supplied"));
}
+ else if (arg.last_regno == 31
+ && (strncmp (insn->insn_mo->name, "bltzal", 6) == 0
+ || strncmp (insn->insn_mo->name, "bgezal", 6) == 0))
+ set_insn_error (0, _("the source register must not be $31"));
check_completed_insn (&arg);
return TRUE;
}
/* Handle special macro operands. Work out the properties of
other operands. */
arg.opnum += 1;
- arg.lax_max = FALSE;
switch (*args)
{
case '+':
switch (args[1])
{
- case 'I':
- /* "+I" is like "I", except that imm2_expr is used. */
- if (!match_const_int (&arg, &imm2_expr.X_add_number))
- return FALSE;
- imm2_expr.X_op = O_constant;
- if (HAVE_32BIT_GPRS)
- normalize_constant_expr (&imm2_expr);
- ++args;
- continue;
-
case 'i':
*offset_reloc = BFD_RELOC_MIPS_JMP;
break;
return FALSE;
continue;
- /* ??? This is the traditional behavior, but is flaky if
- there are alternative versions of the same instruction
- for different subarchitectures. The next alternative
- might not be suitable. */
- case 'j':
- /* For compatibility with older assemblers, we accept
- 0x8000-0xffff as signed 16-bit numbers when only
- signed numbers are allowed. */
- arg.lax_max = !more_alts;
- case 'i':
- /* Only accept non-constant operands if this is the
- final alternative. Later alternatives might include
- a macro implementation. */
- arg.allow_nonconst = !more_alts;
- break;
-
- case 'u':
- /* There are no macro implementations for out-of-range values. */
- arg.allow_nonconst = TRUE;
- break;
-
- case 'o':
- /* There should always be a macro implementation. */
- arg.allow_nonconst = FALSE;
- break;
-
case 'p':
*offset_reloc = BFD_RELOC_16_PCREL_S2;
break;
create_insn (insn, opcode);
imm_expr.X_op = O_absent;
- imm2_expr.X_op = O_absent;
offset_expr.X_op = O_absent;
offset_reloc[0] = BFD_RELOC_UNUSED;
offset_reloc[1] = BFD_RELOC_UNUSED;
}
}
+/* Record that the current instruction is invalid for the current ISA. */
+
+static void
+match_invalid_for_isa (void)
+{
+ set_insn_error_ss
+ (0, _("opcode not supported on this processor: %s (%s)"),
+ mips_cpu_info_from_arch (mips_opts.arch)->name,
+ mips_cpu_info_from_isa (mips_opts.isa)->name);
+}
+
+/* Try to match TOKENS against a series of opcode entries, starting at FIRST.
+ Return true if a definite match or failure was found, storing any match
+ in INSN. OPCODE_EXTRA is a value that should be ORed into the opcode
+ (to handle things like VU0 suffixes). LAX_MATCH is true if we have already
+ tried and failed to match under normal conditions and now want to try a
+ more relaxed match. */
+
+static bfd_boolean
+match_insns (struct mips_cl_insn *insn, const struct mips_opcode *first,
+ const struct mips_opcode *past, struct mips_operand_token *tokens,
+ int opcode_extra, bfd_boolean lax_match)
+{
+ const struct mips_opcode *opcode;
+ const struct mips_opcode *invalid_delay_slot;
+ bfd_boolean seen_valid_for_isa, seen_valid_for_size;
+
+ /* Search for a match, ignoring alternatives that don't satisfy the
+ current ISA or forced_length. */
+ invalid_delay_slot = 0;
+ seen_valid_for_isa = FALSE;
+ seen_valid_for_size = FALSE;
+ opcode = first;
+ do
+ {
+ gas_assert (strcmp (opcode->name, first->name) == 0);
+ if (is_opcode_valid (opcode))
+ {
+ seen_valid_for_isa = TRUE;
+ if (is_size_valid (opcode))
+ {
+ bfd_boolean delay_slot_ok;
+
+ seen_valid_for_size = TRUE;
+ delay_slot_ok = is_delay_slot_valid (opcode);
+ if (match_insn (insn, opcode, tokens, opcode_extra,
+ lax_match, delay_slot_ok))
+ {
+ if (!delay_slot_ok)
+ {
+ if (!invalid_delay_slot)
+ invalid_delay_slot = opcode;
+ }
+ else
+ return TRUE;
+ }
+ }
+ }
+ ++opcode;
+ }
+ while (opcode < past && strcmp (opcode->name, first->name) == 0);
+
+ /* If the only matches we found had the wrong length for the delay slot,
+ pick the first such match. We'll issue an appropriate warning later. */
+ if (invalid_delay_slot)
+ {
+ if (match_insn (insn, invalid_delay_slot, tokens, opcode_extra,
+ lax_match, TRUE))
+ return TRUE;
+ abort ();
+ }
+
+ /* Handle the case where we didn't try to match an instruction because
+ all the alternatives were incompatible with the current ISA. */
+ if (!seen_valid_for_isa)
+ {
+ match_invalid_for_isa ();
+ return TRUE;
+ }
+
+ /* Handle the case where we didn't try to match an instruction because
+ all the alternatives were of the wrong size. */
+ if (!seen_valid_for_size)
+ {
+ if (mips_opts.insn32)
+ set_insn_error (0, _("opcode not supported in the `insn32' mode"));
+ else
+ set_insn_error_i
+ (0, _("unrecognized %d-bit version of microMIPS opcode"),
+ 8 * forced_insn_length);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* Like match_insns, but for MIPS16. */
+
+static bfd_boolean
+match_mips16_insns (struct mips_cl_insn *insn, const struct mips_opcode *first,
+ struct mips_operand_token *tokens)
+{
+ const struct mips_opcode *opcode;
+ bfd_boolean seen_valid_for_isa;
+
+ /* Search for a match, ignoring alternatives that don't satisfy the
+ current ISA. There are no separate entries for extended forms so
+ we deal with forced_length later. */
+ seen_valid_for_isa = FALSE;
+ opcode = first;
+ do
+ {
+ gas_assert (strcmp (opcode->name, first->name) == 0);
+ if (is_opcode_valid_16 (opcode))
+ {
+ seen_valid_for_isa = TRUE;
+ if (match_mips16_insn (insn, opcode, tokens))
+ return TRUE;
+ }
+ ++opcode;
+ }
+ while (opcode < &mips16_opcodes[bfd_mips16_num_opcodes]
+ && strcmp (opcode->name, first->name) == 0);
+
+ /* Handle the case where we didn't try to match an instruction because
+ all the alternatives were incompatible with the current ISA. */
+ if (!seen_valid_for_isa)
+ {
+ match_invalid_for_isa ();
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
/* Set up global variables for the start of a new macro. */
static void
macro_warning (relax_substateT subtype)
{
if (subtype & RELAX_DELAY_SLOT)
- return _("Macro instruction expanded into multiple instructions"
+ return _("macro instruction expanded into multiple instructions"
" in a branch delay slot");
else if (subtype & RELAX_NOMACRO)
- return _("Macro instruction expanded into multiple instructions");
+ return _("macro instruction expanded into multiple instructions");
else if (subtype & (RELAX_DELAY_SLOT_SIZE_FIRST
| RELAX_DELAY_SLOT_SIZE_SECOND))
return ((subtype & RELAX_DELAY_SLOT_16BIT)
- ? _("Macro instruction expanded into a wrong size instruction"
+ ? _("macro instruction expanded into a wrong size instruction"
" in a 16-bit branch delay slot")
- : _("Macro instruction expanded into a wrong size instruction"
+ : _("macro instruction expanded into a wrong size instruction"
" in a 32-bit branch delay slot"));
else
return 0;
macro_build (ep, op, "t,o(b)", treg, BFD_RELOC_LO16, AT);
if (!mips_opts.at)
- as_bad (_("Macro used $at after \".set noat\""));
+ as_bad (_("macro used $at after \".set noat\""));
}
}
static void
set_at (int reg, int unsignedp)
{
- if (imm_expr.X_op == O_constant
- && imm_expr.X_add_number >= -0x8000
+ if (imm_expr.X_add_number >= -0x8000
&& imm_expr.X_add_number < 0x8000)
macro_build (&imm_expr, unsignedp ? "sltiu" : "slti", "t,r,j",
AT, reg, BFD_RELOC_LO16);
char value[32];
sprintf_vma (value, ep->X_add_number);
- as_bad (_("Number (0x%s) larger than 32 bits"), value);
+ as_bad (_("number (0x%s) larger than 32 bits"), value);
macro_build (ep, "addiu", "t,r,j", reg, 0, BFD_RELOC_LO16);
return;
}
if (ep->X_add_number == 3)
generic_bignum[3] = 0;
else if (ep->X_add_number > 4)
- as_bad (_("Number larger than 64 bits"));
+ as_bad (_("number larger than 64 bits"));
lo32.X_op = O_constant;
lo32.X_add_number = generic_bignum[0] + (generic_bignum[1] << 16);
hi32.X_op = O_constant;
abort ();
if (!mips_opts.at && *used_at == 1)
- as_bad (_("Macro used $at after \".set noat\""));
+ as_bad (_("macro used $at after \".set noat\""));
}
/* Move the contents of register SOURCE into register DEST. */
s2 = "dadd";
if (!mips_opts.micromips)
goto do_addi;
- if (imm_expr.X_op == O_constant
- && imm_expr.X_add_number >= -0x200
+ if (imm_expr.X_add_number >= -0x200
&& imm_expr.X_add_number < 0x200)
{
- macro_build (NULL, s, "t,r,.", op[0], op[1], imm_expr.X_add_number);
+ macro_build (NULL, s, "t,r,.", op[0], op[1],
+ (int) imm_expr.X_add_number);
break;
}
goto do_addi_i;
s = "daddiu";
s2 = "daddu";
do_addi:
- if (imm_expr.X_op == O_constant
- && imm_expr.X_add_number >= -0x8000
+ if (imm_expr.X_add_number >= -0x8000
&& imm_expr.X_add_number < 0x8000)
{
macro_build (&imm_expr, s, "t,r,j", op[0], op[1], BFD_RELOC_LO16);
s = "xori";
s2 = "xor";
do_bit:
- if (imm_expr.X_op == O_constant
- && imm_expr.X_add_number >= 0
+ if (imm_expr.X_add_number >= 0
&& imm_expr.X_add_number < 0x10000)
{
if (mask != M_NOR_I)
case M_BEQL_I:
case M_BNE_I:
case M_BNEL_I:
- if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
+ if (imm_expr.X_add_number == 0)
op[1] = 0;
else
{
likely = 1;
case M_BGT_I:
/* Check for > max integer. */
- if (imm_expr.X_op == O_constant && imm_expr.X_add_number >= GPR_SMAX)
+ if (imm_expr.X_add_number >= GPR_SMAX)
{
do_false:
/* Result is always false. */
macro_build_branch_rsrt (M_BNEL, &offset_expr, ZERO, ZERO);
break;
}
- 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_op == O_constant && imm_expr.X_add_number == 0)
+ if (imm_expr.X_add_number == 0)
{
macro_build_branch_rs (likely ? M_BGEZL : M_BGEZ,
&offset_expr, op[0]);
break;
}
- if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
+ if (imm_expr.X_add_number == 1)
{
macro_build_branch_rs (likely ? M_BGTZL : M_BGTZ,
&offset_expr, op[0]);
break;
}
- if (imm_expr.X_op == O_constant && imm_expr.X_add_number <= GPR_SMIN)
+ if (imm_expr.X_add_number <= GPR_SMIN)
{
do_true:
/* result is always true */
- as_warn (_("Branch %s is always true"), ip->insn_mo->name);
+ as_warn (_("branch %s is always true"), ip->insn_mo->name);
macro_build (&offset_expr, "b", "p");
break;
}
case M_BGTU_I:
if (op[0] == 0
|| (HAVE_32BIT_GPRS
- && imm_expr.X_op == O_constant
&& imm_expr.X_add_number == -1))
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_op == O_constant && imm_expr.X_add_number == 0)
+ if (imm_expr.X_add_number == 0)
goto do_true;
- else if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
+ else if (imm_expr.X_add_number == 1)
macro_build_branch_rsrt (likely ? M_BNEL : M_BNE,
&offset_expr, op[0], ZERO);
else
case M_BLEL_I:
likely = 1;
case M_BLE_I:
- if (imm_expr.X_op == O_constant && imm_expr.X_add_number >= GPR_SMAX)
+ if (imm_expr.X_add_number >= GPR_SMAX)
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_op == O_constant && imm_expr.X_add_number == 0)
+ if (imm_expr.X_add_number == 0)
macro_build_branch_rs (likely ? M_BLTZL : M_BLTZ, &offset_expr, op[0]);
- else if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
+ else if (imm_expr.X_add_number == 1)
macro_build_branch_rs (likely ? M_BLEZL : M_BLEZ, &offset_expr, op[0]);
else
{
case M_BLEU_I:
if (op[0] == 0
|| (HAVE_32BIT_GPRS
- && imm_expr.X_op == O_constant
&& imm_expr.X_add_number == -1))
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_op == O_constant && imm_expr.X_add_number == 0)
+ if (imm_expr.X_add_number == 0)
goto do_false;
- else if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
+ else if (imm_expr.X_add_number == 1)
macro_build_branch_rsrt (likely ? M_BEQL : M_BEQ,
&offset_expr, op[0], ZERO);
else
}
break;
- case M_DEXT:
- {
- /* Use unsigned arithmetic. */
- addressT pos;
- addressT size;
-
- if (imm_expr.X_op != O_constant || imm2_expr.X_op != O_constant)
- {
- as_bad (_("Unsupported large constant"));
- pos = size = 1;
- }
- else
- {
- pos = imm_expr.X_add_number;
- size = imm2_expr.X_add_number;
- }
-
- if (pos > 63)
- {
- report_bad_range (ip, 3, pos, 0, 63, FALSE);
- pos = 1;
- }
- if (size == 0 || size > 64 || (pos + size - 1) > 63)
- {
- report_bad_field (pos, size);
- size = 1;
- }
-
- if (size <= 32 && pos < 32)
- {
- s = "dext";
- fmt = "t,r,+A,+C";
- }
- else if (size <= 32)
- {
- s = "dextu";
- fmt = "t,r,+E,+H";
- }
- else
- {
- s = "dextm";
- fmt = "t,r,+A,+G";
- }
- macro_build ((expressionS *) NULL, s, fmt, op[0], op[1], (int) pos,
- (int) (size - 1));
- }
- break;
-
- case M_DINS:
- {
- /* Use unsigned arithmetic. */
- addressT pos;
- addressT size;
-
- if (imm_expr.X_op != O_constant || imm2_expr.X_op != O_constant)
- {
- as_bad (_("Unsupported large constant"));
- pos = size = 1;
- }
- else
- {
- pos = imm_expr.X_add_number;
- size = imm2_expr.X_add_number;
- }
-
- if (pos > 63)
- {
- report_bad_range (ip, 3, pos, 0, 63, FALSE);
- pos = 1;
- }
- if (size == 0 || size > 64 || (pos + size - 1) > 63)
- {
- report_bad_field (pos, size);
- size = 1;
- }
-
- if (pos < 32 && (pos + size - 1) < 32)
- {
- s = "dins";
- fmt = "t,r,+A,+B";
- }
- else if (pos >= 32)
- {
- s = "dinsu";
- fmt = "t,r,+E,+F";
- }
- else
- {
- s = "dinsm";
- fmt = "t,r,+A,+F";
- }
- macro_build ((expressionS *) NULL, s, fmt, op[0], op[1], (int) pos,
- (int) (pos + size - 1));
- }
- break;
-
case M_DDIV_3:
dbl = 1;
case M_DIV_3:
do_div3:
if (op[2] == 0)
{
- as_warn (_("Divide by zero."));
+ as_warn (_("divide by zero"));
if (mips_trap)
macro_build (NULL, "teq", TRAP_FMT, ZERO, ZERO, 7);
else
s = "ddivu";
s2 = "mfhi";
do_divi:
- if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
+ if (imm_expr.X_add_number == 0)
{
- as_warn (_("Divide by zero."));
+ as_warn (_("divide by zero"));
if (mips_trap)
macro_build (NULL, "teq", TRAP_FMT, ZERO, ZERO, 7);
else
macro_build (NULL, "break", BRK_FMT, 7);
break;
}
- if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)
+ if (imm_expr.X_add_number == 1)
{
if (strcmp (s2, "mflo") == 0)
move_register (op[0], op[1]);
move_register (op[0], ZERO);
break;
}
- if (imm_expr.X_op == O_constant
- && imm_expr.X_add_number == -1
- && s[strlen (s) - 1] != 'u')
+ if (imm_expr.X_add_number == -1 && s[strlen (s) - 1] != 'u')
{
if (strcmp (s2, "mflo") == 0)
macro_build (NULL, dbl ? "dneg" : "neg", "d,w", op[0], op[1]);
if (offset_expr.X_op != O_symbol
&& offset_expr.X_op != O_constant)
{
- as_bad (_("Expression too complex"));
+ as_bad (_("expression too complex"));
offset_expr.X_op = O_constant;
}
relax_switch ();
}
if (!IS_SEXT_32BIT_NUM (offset_expr.X_add_number))
- as_bad (_("Offset too large"));
+ as_bad (_("offset too large"));
macro_build_lui (&offset_expr, tempreg);
macro_build (&offset_expr, ADDRESS_ADDI_INSN, "t,r,j",
tempreg, tempreg, BFD_RELOC_LO16);
gas_assert (mips_opts.micromips);
if (mips_opts.insn32)
{
- as_bad (_("Opcode not supported in the `insn32' mode `%s'"), str);
+ as_bad (_("opcode not supported in the `insn32' mode `%s'"), str);
break;
}
jals = 1;
if (mips_pic == SVR4_PIC && !HAVE_NEWABI)
{
if (mips_cprestore_offset < 0)
- as_warn (_("No .cprestore pseudo-op used in PIC code"));
+ as_warn (_("no .cprestore pseudo-op used in PIC code"));
else
{
if (!mips_frame_reg_valid)
{
- as_warn (_("No .frame pseudo-op used in PIC code"));
+ as_warn (_("no .frame pseudo-op used in PIC code"));
/* Quiet this warning. */
mips_frame_reg_valid = 1;
}
if (!mips_cprestore_valid)
{
- as_warn (_("No .cprestore pseudo-op used in PIC code"));
+ as_warn (_("no .cprestore pseudo-op used in PIC code"));
/* Quiet this warning. */
mips_cprestore_valid = 1;
}
gas_assert (mips_opts.micromips);
if (mips_opts.insn32)
{
- as_bad (_("Opcode not supported in the `insn32' mode `%s'"), str);
+ as_bad (_("opcode not supported in the `insn32' mode `%s'"), str);
break;
}
jals = 1;
macro_build_jalr (&offset_expr, mips_cprestore_offset >= 0);
if (mips_cprestore_offset < 0)
- as_warn (_("No .cprestore pseudo-op used in PIC code"));
+ as_warn (_("no .cprestore pseudo-op used in PIC code"));
else
{
if (!mips_frame_reg_valid)
{
- as_warn (_("No .frame pseudo-op used in PIC code"));
+ as_warn (_("no .frame pseudo-op used in PIC code"));
/* Quiet this warning. */
mips_frame_reg_valid = 1;
}
if (!mips_cprestore_valid)
{
- as_warn (_("No .cprestore pseudo-op used in PIC code"));
+ as_warn (_("no .cprestore pseudo-op used in PIC code"));
/* Quiet this warning. */
mips_cprestore_valid = 1;
}
}
}
else if (mips_pic == VXWORKS_PIC)
- as_bad (_("Non-PIC jump used in PIC library"));
+ as_bad (_("non-PIC jump used in PIC library"));
else
abort ();
if (offset_expr.X_op != O_constant
&& offset_expr.X_op != O_symbol)
{
- as_bad (_("Expression too complex"));
+ as_bad (_("expression too complex"));
offset_expr.X_op = O_constant;
}
char value [32];
sprintf_vma (value, offset_expr.X_add_number);
- as_bad (_("Number (0x%s) larger than 32 bits"), value);
+ as_bad (_("number (0x%s) larger than 32 bits"), value);
}
/* A constant expression in PIC code can be handled just as it
}
else
{
- gas_assert (offset_expr.X_op == O_symbol
+ gas_assert (imm_expr.X_op == O_absent
+ && offset_expr.X_op == O_symbol
&& strcmp (segment_name (S_GET_SEGMENT
(offset_expr.X_add_symbol)),
".lit4") == 0
wide, IMM_EXPR is the entire value. Otherwise IMM_EXPR is the high
order 32 bits of the value and the low order 32 bits are either
zero or in OFFSET_EXPR. */
- if (imm_expr.X_op == O_constant || imm_expr.X_op == O_big)
+ if (imm_expr.X_op == O_constant)
{
if (HAVE_64BIT_GPRS)
load_register (op[0], &imm_expr, 1);
}
break;
}
+ gas_assert (imm_expr.X_op == O_absent);
/* We know that sym is in the .rdata section. First we get the
upper 16 bits of the address. */
bits wide as well. Otherwise IMM_EXPR is the high order 32 bits of
the value and the low order 32 bits are either zero or in
OFFSET_EXPR. */
- if (imm_expr.X_op == O_constant || imm_expr.X_op == O_big)
+ if (imm_expr.X_op == O_constant)
{
used_at = 1;
load_register (AT, &imm_expr, HAVE_64BIT_FPRS);
break;
}
- gas_assert (offset_expr.X_op == O_symbol
+ gas_assert (imm_expr.X_op == O_absent
+ && offset_expr.X_op == O_symbol
&& offset_expr.X_add_number == 0);
s = segment_name (S_GET_SEGMENT (offset_expr.X_add_symbol));
if (strcmp (s, ".lit8") == 0)
if (offset_expr.X_op != O_symbol
&& offset_expr.X_op != O_constant)
{
- as_bad (_("Expression too complex"));
+ as_bad (_("expression too complex"));
offset_expr.X_op = O_constant;
}
char value [32];
sprintf_vma (value, offset_expr.X_add_number);
- as_bad (_("Number (0x%s) larger than 32 bits"), value);
+ as_bad (_("number (0x%s) larger than 32 bits"), value);
}
if (mips_pic == NO_PIC || offset_expr.X_op == O_constant)
char *l;
char *rr;
- if (imm_expr.X_op != O_constant)
- as_bad (_("Improper rotate count"));
rot = imm_expr.X_add_number & 0x3f;
if (ISA_HAS_DROR (mips_opts.isa) || CPU_HAS_DROR (mips_opts.arch))
{
{
unsigned int rot;
- if (imm_expr.X_op != O_constant)
- as_bad (_("Improper rotate count"));
rot = imm_expr.X_add_number & 0x1f;
if (ISA_HAS_ROR (mips_opts.isa) || CPU_HAS_ROR (mips_opts.arch))
{
char *l;
char *rr;
- if (imm_expr.X_op != O_constant)
- as_bad (_("Improper rotate count"));
rot = imm_expr.X_add_number & 0x3f;
if (ISA_HAS_DROR (mips_opts.isa) || CPU_HAS_DROR (mips_opts.arch))
{
{
unsigned int rot;
- if (imm_expr.X_op != O_constant)
- as_bad (_("Improper rotate count"));
rot = imm_expr.X_add_number & 0x1f;
if (ISA_HAS_ROR (mips_opts.isa) || CPU_HAS_ROR (mips_opts.arch))
{
break;
case M_SEQ_I:
- if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
+ if (imm_expr.X_add_number == 0)
{
macro_build (&expr1, "sltiu", "t,r,j", op[0], op[1], BFD_RELOC_LO16);
break;
}
if (op[1] == 0)
{
- as_warn (_("Instruction %s: result is always false"),
+ as_warn (_("instruction %s: result is always false"),
ip->insn_mo->name);
move_register (op[0], 0);
break;
(int) imm_expr.X_add_number);
break;
}
- if (imm_expr.X_op == O_constant
- && imm_expr.X_add_number >= 0
+ if (imm_expr.X_add_number >= 0
&& imm_expr.X_add_number < 0x10000)
macro_build (&imm_expr, "xori", "t,r,i", op[0], op[1], BFD_RELOC_LO16);
- else if (imm_expr.X_op == O_constant
- && imm_expr.X_add_number > -0x8000
+ else if (imm_expr.X_add_number > -0x8000
&& imm_expr.X_add_number < 0)
{
imm_expr.X_add_number = -imm_expr.X_add_number;
case M_SGE_I: /* X >= I <==> not (X < I) */
case M_SGEU_I:
- if (imm_expr.X_op == O_constant
- && imm_expr.X_add_number >= -0x8000
+ if (imm_expr.X_add_number >= -0x8000
&& imm_expr.X_add_number < 0x8000)
macro_build (&imm_expr, mask == M_SGE_I ? "slti" : "sltiu", "t,r,j",
op[0], op[1], BFD_RELOC_LO16);
break;
case M_SLT_I:
- if (imm_expr.X_op == O_constant
- && imm_expr.X_add_number >= -0x8000
+ if (imm_expr.X_add_number >= -0x8000
&& imm_expr.X_add_number < 0x8000)
{
macro_build (&imm_expr, "slti", "t,r,j", op[0], op[1],
break;
case M_SLTU_I:
- if (imm_expr.X_op == O_constant
- && imm_expr.X_add_number >= -0x8000
+ if (imm_expr.X_add_number >= -0x8000
&& imm_expr.X_add_number < 0x8000)
{
macro_build (&imm_expr, "sltiu", "t,r,j", op[0], op[1],
break;
case M_SNE_I:
- if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)
+ if (imm_expr.X_add_number == 0)
{
macro_build (NULL, "sltu", "d,v,t", op[0], 0, op[1]);
break;
}
if (op[1] == 0)
{
- as_warn (_("Instruction %s: result is always true"),
+ as_warn (_("instruction %s: result is always true"),
ip->insn_mo->name);
macro_build (&expr1, HAVE_32BIT_GPRS ? "addiu" : "daddiu", "t,r,j",
op[0], 0, BFD_RELOC_LO16);
(int) imm_expr.X_add_number);
break;
}
- if (imm_expr.X_op == O_constant
- && imm_expr.X_add_number >= 0
+ if (imm_expr.X_add_number >= 0
&& imm_expr.X_add_number < 0x10000)
{
macro_build (&imm_expr, "xori", "t,r,i", op[0], op[1],
BFD_RELOC_LO16);
}
- else if (imm_expr.X_op == O_constant
- && imm_expr.X_add_number > -0x8000
+ else if (imm_expr.X_add_number > -0x8000
&& imm_expr.X_add_number < 0)
{
imm_expr.X_add_number = -imm_expr.X_add_number;
s2 = "dsub";
if (!mips_opts.micromips)
goto do_subi;
- if (imm_expr.X_op == O_constant
- && imm_expr.X_add_number > -0x200
+ if (imm_expr.X_add_number > -0x200
&& imm_expr.X_add_number <= 0x200)
{
- macro_build (NULL, s, "t,r,.", op[0], op[1], -imm_expr.X_add_number);
+ macro_build (NULL, s, "t,r,.", op[0], op[1],
+ (int) -imm_expr.X_add_number);
break;
}
goto do_subi_i;
s = "daddiu";
s2 = "dsubu";
do_subi:
- if (imm_expr.X_op == O_constant
- && imm_expr.X_add_number > -0x8000
+ if (imm_expr.X_add_number > -0x8000
&& imm_expr.X_add_number <= 0x8000)
{
imm_expr.X_add_number = -imm_expr.X_add_number;
default:
/* FIXME: Check if this is one of the itbl macros, since they
are added dynamically. */
- as_bad (_("Macro %s not implemented yet"), ip->insn_mo->name);
+ as_bad (_("macro %s not implemented yet"), ip->insn_mo->name);
break;
}
if (!mips_opts.at && used_at)
- as_bad (_("Macro used $at after \".set noat\""));
+ as_bad (_("macro used $at after \".set noat\""));
}
/* Implement macros in mips16 mode. */
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 (&imm_expr, dbl ? "daddiu" : "addiu", "y,x,4", op[0], op[1]);
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 (&imm_expr, "addiu", "x,k", op[0]);
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 (&imm_expr, "daddiu", "y,j", op[0]);
break;
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:
}
/* Assemble an instruction into its binary format. If the instruction
- is a macro, set imm_expr, imm2_expr and offset_expr to the values
- associated with "I", "+I" and "A" operands respectively. Otherwise
- store the value of the relocatable field (if any) in offset_expr.
- In both cases set offset_reloc to the relocation operators applied
- to offset_expr. */
+ is a macro, set imm_expr and offset_expr to the values associated
+ with "I" and "A" operands respectively. Otherwise store the value
+ of the relocatable field (if any) in offset_expr. In both cases
+ set offset_reloc to the relocation operators applied to offset_expr. */
static void
-mips_ip (char *str, struct mips_cl_insn *ip)
+mips_ip (char *str, struct mips_cl_insn *insn)
{
- bfd_boolean wrong_delay_slot_insns = FALSE;
- bfd_boolean need_delay_slot_ok = TRUE;
- struct mips_opcode *firstinsn = NULL;
- const struct mips_opcode *past;
+ const struct mips_opcode *first, *past;
struct hash_control *hash;
- struct mips_opcode *first, *insn;
char format;
size_t end;
struct mips_operand_token *tokens;
past = &mips_opcodes[NUMOPCODES];
}
forced_insn_length = 0;
- insn = NULL;
opcode_extra = 0;
/* We first try to match an instruction up to a space or to the end. */
for (end = 0; str[end] != '\0' && !ISSPACE (str[end]); end++)
continue;
- first = insn = mips_lookup_insn (hash, str, end, &opcode_extra);
- if (insn == NULL)
+ first = mips_lookup_insn (hash, str, end, &opcode_extra);
+ if (first == NULL)
{
- set_insn_error (0, _("Unrecognized opcode"));
+ set_insn_error (0, _("unrecognized opcode"));
return;
}
- /* When no opcode suffix is specified, assume ".xyzw". */
- if ((insn->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX) != 0 && opcode_extra == 0)
- opcode_extra = 0xf << mips_vu0_channel_mask.lsb;
- if (strcmp (insn->name, "li.s") == 0)
+ if (strcmp (first->name, "li.s") == 0)
format = 'f';
- else if (strcmp (insn->name, "li.d") == 0)
+ else if (strcmp (first->name, "li.d") == 0)
format = 'd';
else
format = 0;
if (!tokens)
return;
- /* For microMIPS instructions placed in a fixed-length branch delay slot
- we make up to two passes over the relevant fragment of the opcode
- table. First we try instructions that meet the delay slot's length
- requirement. If none matched, then we retry with the remaining ones
- and if one matches, then we use it and then issue an appropriate
- warning later on. */
- for (;;)
- {
- bfd_boolean delay_slot_ok;
- bfd_boolean size_ok;
- bfd_boolean ok;
- bfd_boolean more_alts;
-
- gas_assert (strcmp (insn->name, first->name) == 0);
-
- ok = is_opcode_valid (insn);
- size_ok = is_size_valid (insn);
- delay_slot_ok = is_delay_slot_valid (insn);
- if (!delay_slot_ok && !wrong_delay_slot_insns)
- {
- firstinsn = insn;
- wrong_delay_slot_insns = TRUE;
- }
- more_alts = (insn + 1 < past
- && strcmp (insn[0].name, insn[1].name) == 0);
- if (!ok || !size_ok || delay_slot_ok != need_delay_slot_ok)
- {
- if (more_alts)
- {
- ++insn;
- continue;
- }
- if (wrong_delay_slot_insns && need_delay_slot_ok)
- {
- gas_assert (firstinsn);
- need_delay_slot_ok = FALSE;
- past = insn + 1;
- insn = firstinsn;
- continue;
- }
-
- if (!ok)
- set_insn_error_ss
- (0, _("Opcode not supported on this processor: %s (%s)"),
- mips_cpu_info_from_arch (mips_opts.arch)->name,
- mips_cpu_info_from_isa (mips_opts.isa)->name);
- else if (mips_opts.insn32)
- set_insn_error
- (0, _("Opcode not supported in the `insn32' mode"));
- else
- set_insn_error_i
- (0, _("Unrecognized %d-bit version of microMIPS opcode"),
- 8 * forced_insn_length);
- break;
- }
+ if (!match_insns (insn, first, past, tokens, opcode_extra, FALSE)
+ && !match_insns (insn, first, past, tokens, opcode_extra, TRUE))
+ set_insn_error (0, _("invalid operands"));
- if (match_insn (ip, insn, tokens, opcode_extra,
- more_alts || (wrong_delay_slot_insns
- && need_delay_slot_ok)))
- break;
-
- /* Args don't match. */
- set_insn_error (0, _("Illegal operands"));
- if (more_alts)
- {
- ++insn;
- continue;
- }
- if (wrong_delay_slot_insns && need_delay_slot_ok)
- {
- gas_assert (firstinsn);
- need_delay_slot_ok = FALSE;
- past = insn + 1;
- insn = firstinsn;
- continue;
- }
- break;
- }
obstack_free (&mips_operand_tokens, tokens);
}
bytes if the user explicitly requested a small or extended instruction. */
static void
-mips16_ip (char *str, struct mips_cl_insn *ip)
+mips16_ip (char *str, struct mips_cl_insn *insn)
{
char *end, *s, c;
- struct mips_opcode *insn, *first;
+ struct mips_opcode *first;
struct mips_operand_token *tokens;
forced_insn_length = 0;
}
/* Fall through. */
default:
- set_insn_error (0, _("Unrecognized opcode"));
+ set_insn_error (0, _("unrecognized opcode"));
return;
}
forced_insn_length = 2;
*end = 0;
- first = insn = (struct mips_opcode *) hash_find (mips16_op_hash, str);
+ first = (struct mips_opcode *) hash_find (mips16_op_hash, str);
*end = c;
- if (!insn)
+ if (!first)
{
- set_insn_error (0, _("Unrecognized opcode"));
+ set_insn_error (0, _("unrecognized opcode"));
return;
}
if (!tokens)
return;
- for (;;)
- {
- bfd_boolean ok;
- bfd_boolean more_alts;
-
- gas_assert (strcmp (insn->name, first->name) == 0);
+ if (!match_mips16_insns (insn, first, tokens))
+ set_insn_error (0, _("invalid operands"));
- ok = is_opcode_valid_16 (insn);
- more_alts = (insn + 1 < &mips16_opcodes[bfd_mips16_num_opcodes]
- && strcmp (insn[0].name, insn[1].name) == 0);
- if (! ok)
- {
- if (more_alts)
- {
- ++insn;
- continue;
- }
- else
- {
- set_insn_error_ss
- (0, _("Opcode not supported on this processor: %s (%s)"),
- mips_cpu_info_from_arch (mips_opts.arch)->name,
- mips_cpu_info_from_isa (mips_opts.isa)->name);
- break;
- }
- }
-
- if (match_mips16_insn (ip, insn, tokens))
- break;
-
- /* Args don't match. */
- set_insn_error (0, _("Illegal operands"));
- if (more_alts)
- {
- ++insn;
- continue;
- }
- break;
- }
obstack_free (&mips_operand_tokens, tokens);
}
mips_set_option_string (const char **string_ptr, const char *new_value)
{
if (*string_ptr != 0 && strcasecmp (*string_ptr, new_value) != 0)
- as_warn (_("A different %s was already specified, is now %s"),
+ as_warn (_("a different %s was already specified, is now %s"),
string_ptr == &mips_arch_string ? "-march" : "-mtune",
new_value);
case OPTION_64:
mips_abi = N64_ABI;
if (!support_64bit_objects())
- as_fatal (_("No compiled in support for 64 bit object file format"));
+ as_fatal (_("no compiled in support for 64 bit object file format"));
break;
case OPTION_GP32:
{
mips_abi = N64_ABI;
if (! support_64bit_objects())
- as_fatal (_("No compiled in support for 64 bit object file "
+ as_fatal (_("no compiled in support for 64 bit object file "
"format"));
}
else if (strcmp (arg, "eabi") == 0)
mips_flag_nan2008 = FALSE;
else
{
- as_fatal (_("Invalid NaN setting -mnan=%s"), arg);
+ as_fatal (_("invalid NaN setting -mnan=%s"), arg);
return 0;
}
break;
if (strncmp (TARGET_OS, "pe", 2) == 0)
{
if (g_switch_seen && g_switch_value != 0)
- as_bad (_("-G not supported in this configuration."));
+ as_bad (_("-G not supported in this configuration"));
g_switch_value = 0;
}
There's no harm in specifying both as long as the ISA levels
are the same. */
if (file_mips_isa != arch_info->isa)
- as_bad (_("-%s conflicts with the other architecture options, which imply -%s"),
+ as_bad (_("-%s conflicts with the other architecture options,"
+ " which imply -%s"),
mips_cpu_info_from_isa (file_mips_isa)->name,
mips_cpu_info_from_isa (arch_info->isa)->name);
}
/* We have no relocation type for PC relative MIPS16 instructions. */
if (fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) != now_seg)
as_bad_where (fixP->fx_file, fixP->fx_line,
- _("PC relative MIPS16 instruction references a different section"));
+ _("PC relative MIPS16 instruction references"
+ " a different section"));
return addr;
}
}
}
else
as_bad_where (fixP->fx_file, fixP->fx_line,
- _("Unsupported constant in relocation"));
+ _("unsupported constant in relocation"));
}
break;
case BFD_RELOC_16_PCREL_S2:
if ((*valP & 0x3) != 0)
as_bad_where (fixP->fx_file, fixP->fx_line,
- _("Branch to misaligned address (%lx)"), (long) *valP);
+ _("branch to misaligned address (%lx)"), (long) *valP);
/* We need to save the bits in the instruction since fixup_segment()
might be deleting the relocation entry (i.e., a branch within
and there's nothing we can do to fix this instruction
without turning it into a longer sequence. */
as_bad_where (fixP->fx_file, fixP->fx_line,
- _("Branch out of range"));
+ _("branch out of range"));
}
break;
temp = get_absolute_expression ();
if (temp > max_alignment)
- as_bad (_("Alignment too large: %d. assumed."), temp = max_alignment);
+ as_bad (_("alignment too large, %d assumed"), temp = max_alignment);
else if (temp < 0)
{
- as_warn (_("Alignment negative: 0 assumed."));
+ as_warn (_("alignment negative, 0 assumed"));
temp = 0;
}
if (*input_line_pointer == ',')
}
}
else
- as_warn (_("Unrecognized option \"%s\""), opt);
+ as_warn (_("unrecognized option \"%s\""), opt);
*input_line_pointer = c;
demand_empty_rest_of_line ();
char *s = name + 3;
if (!reg_lookup (&s, RTYPE_NUM | RTYPE_GP, &mips_opts.at))
- as_bad (_("Unrecognized register name `%s'"), s);
+ as_bad (_("unrecognized register name `%s'"), s);
}
else if (strcmp (name, "at") == 0)
{
}
else
{
- as_warn (_("Tried to set unrecognized symbol: %s\n"), name);
+ as_warn (_("tried to set unrecognized symbol: %s\n"), name);
}
mips_check_isa_supports_ases ();
*input_line_pointer = ch;
if (ex.X_op != O_symbol)
{
- as_bad (_("Unsupported use of %s"), dirstr);
+ as_bad (_("unsupported use of %s"), dirstr);
ignore_rest_of_line ();
}
if (ex.X_op != O_symbol || ex.X_add_number != 0)
{
- as_bad (_("Unsupported use of .gpword"));
+ as_bad (_("unsupported use of .gpword"));
ignore_rest_of_line ();
}
if (ex.X_op != O_symbol || ex.X_add_number != 0)
{
- as_bad (_("Unsupported use of .gpdword"));
+ as_bad (_("unsupported use of .gpdword"));
ignore_rest_of_line ();
}
if (ex.X_op != O_symbol || ex.X_add_number != 0)
{
- as_bad (_("Unsupported use of .ehword"));
+ as_bad (_("unsupported use of .ehword"));
ignore_rest_of_line ();
}
&& memcmp (input_line_pointer, str_legacy, i) == 0)
mips_flag_nan2008 = FALSE;
else
- as_bad (_("Bad .nan directive"));
+ as_bad (_("bad .nan directive"));
input_line_pointer += i;
demand_empty_rest_of_line ();
if (reloc->howto == NULL)
{
as_bad_where (fixp->fx_file, fixp->fx_line,
- _("Can not represent %s relocation in this object file format"),
+ _("cannot represent %s relocation in this object file"
+ " format"),
bfd_get_reloc_code_name (code));
retval[0] = NULL;
}
int i;
as_warn_where (fragp->fr_file, fragp->fr_line,
- _("Relaxed out-of-range branch into a jump"));
+ _("relaxed out-of-range branch into a jump"));
if (RELAX_BRANCH_UNCOND (fragp->fr_subtype))
goto uncond;
/* Relax 32-bit branches to a sequence of instructions. */
as_warn_where (fragp->fr_file, fragp->fr_line,
- _("Relaxed out-of-range branch into a jump"));
+ _("relaxed out-of-range branch into a jump"));
/* Set the short-delay-slot bit. */
short_ds = al && (insn & 0x02000000) != 0;
if (!cur_proc_ptr)
{
- as_warn (_(".end directive without a preceding .ent directive."));
+ as_warn (_(".end directive without a preceding .ent directive"));
demand_empty_rest_of_line ();
return;
}
{
gas_assert (S_GET_NAME (p));
if (strcmp (S_GET_NAME (p), S_GET_NAME (cur_proc_ptr->func_sym)))
- as_warn (_(".end symbol does not match .ent symbol."));
+ as_warn (_(".end symbol does not match .ent symbol"));
if (debug_type == DEBUG_STABS)
stabs_generate_asm_endfunc (S_GET_NAME (p),
get_number ();
if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) == 0)
- as_warn (_(".ent or .aent not in text section."));
+ as_warn (_(".ent or .aent not in text section"));
if (!aent && cur_proc_ptr)
as_warn (_("missing .end"));
if (*input_line_pointer++ != ','
|| get_absolute_expression_and_terminator (&val) != ',')
{
- as_warn (_("Bad .frame directive"));
+ as_warn (_("bad .frame directive"));
--input_line_pointer;
demand_empty_rest_of_line ();
return;
if (get_absolute_expression_and_terminator (&mask) != ',')
{
- as_warn (_("Bad .mask/.fmask directive"));
+ as_warn (_("bad .mask/.fmask directive"));
--input_line_pointer;
demand_empty_rest_of_line ();
return;
if (mips_matching_cpu_name_p (p->name, cpu_string))
return p;
- as_bad (_("Bad value (%s) for %s"), cpu_string, option);
+ as_bad (_("bad value (%s) for %s"), cpu_string, option);
return 0;
}