+2014-10-23 Sandra Loosemore <sandra@codesourcery.com>
+
+ * config/tc-nios2.c (nios2_insn_infoS): Add constant_bits field.
+ (nios2_arg_infoS, nios2_arg_hash, nios2_arg_lookup): Delete.
+ (nios2_control_register_arg_p): Delete.
+ (nios2_coproc_reg): Delete.
+ (nios2_relax_frag): Remove hard-coded instruction size.
+ (md_convert_frag): Use new insn accessor macros.
+ (nios2_diagnose_overflow): Remove hard-coded instruction size.
+ (md_apply_fix): Likewise.
+ (bad_opcode): New.
+ (nios2_parse_reg): New.
+ (nios2_assemble_expression): Remove prev_reloc parameter. Adjust
+ uses and callers.
+ (nios2_assemble_arg_c): New.
+ (nios2_assemble_arg_d): New.
+ (nios2_assemble_arg_s): New.
+ (nios2_assemble_arg_t): New.
+ (nios2_assemble_arg_i): New.
+ (nios2_assemble_arg_u): New.
+ (nios2_assemble_arg_o): New.
+ (nios2_assemble_arg_j): New.
+ (nios2_assemble_arg_l): New.
+ (nios2_assemble_arg_m): New.
+ (nios2_assemble_args): New.
+ (nios2_assemble_args_dst): Delete.
+ (nios2_assemble_args_tsi): Delete.
+ (nios2_assemble_args_tsu): Delete.
+ (nios2_assemble_args_sto): Delete.
+ (nios2_assemble_args_o): Delete.
+ (nios2_assemble_args_is): Delete.
+ (nios2_assemble_args_m): Delete.
+ (nios2_assemble_args_s): Delete.
+ (nios2_assemble_args_tis): Delete.
+ (nios2_assemble_args_dc): Delete.
+ (nios2_assemble_args_cs): Delete.
+ (nios2_assemble_args_ds): Delete.
+ (nios2_assemble_args_ldst): Delete.
+ (nios2_assemble_args_none): Delete.
+ (nios2_assemble_args_dsj): Delete.
+ (nios2_assemble_args_d): Delete.
+ (nios2_assemble_args_b): Delete.
+ (nios2_arg_info_structs): Delete.
+ (NIOS2_NUM_ARGS): Delete.
+ (nios2_consume_arg): Remove insn parameter. Use new macros.
+ Don't check register arguments here. Remove 'b' case.
+ (nios2_consume_separator): Move check for missing separators to...
+ (nios2_parse_args): ...here. Remove special case for optional
+ arguments.
+ (output_insn): Avoid using hard-coded insn size.
+ (output_ubranch): Likewise.
+ (output_cbranch): Likewise.
+ (output_call): Use new macros.
+ (output_addi): Likewise.
+ (output_ori): Likewise.
+ (output_xori): Likewise.
+ (output_movia): Likewise.
+ (md_begin): Remove nios2_arg_info_structs initialization.
+ (md_assemble): Initialize constant_bits field. Use
+ nios2_parse_args instead of looking up parse function in hash table.
+
2014-10-22 Matthew Fortune <matthew.fortune@imgtec.com>
* doc/as.texinfo: Update the MIPS FP ABI descriptions.
{
/* Assembled instruction. */
unsigned long insn_code;
+
+ /* Constant bits masked into insn_code for self-check mode. */
+ unsigned long constant_bits;
+
/* Pointer to the relevant bit of the opcode table. */
const struct nios2_opcode *insn_nios2_opcode;
/* After parsing ptrs to the tokens in the instruction fill this array
nios2_insn_relocS *insn_reloc;
} nios2_insn_infoS;
-/* This struct associates an argument assemble function with
- an argument syntax string. Used by the assembler to find out
- how to parse and assemble a set of instruction operands and
- return the instruction field values. */
-typedef struct nios2_arg_info
-{
- const char *args;
- void (*assemble_args_func) (nios2_insn_infoS *insn_info);
-} nios2_arg_infoS;
/* This struct is used to convert Nios II pseudo-ops into the
corresponding real op. */
#define nios2_reg_lookup(NAME) \
((struct nios2_reg *) hash_find (nios2_reg_hash, (NAME)))
-/* Parse args hash table. */
-static struct hash_control *nios2_arg_hash = NULL;
-#define nios2_arg_lookup(NAME) \
- ((nios2_arg_infoS *) hash_find (nios2_arg_hash, (NAME)))
/* Pseudo-op hash table. */
static struct hash_control *nios2_ps_hash = NULL;
#define strprefix(STR, PREFIX) \
(strncmp ((STR), PREFIX, strlen (PREFIX)) == 0)
-/* Return true if STR is prefixed with a control register name. */
-static int
-nios2_control_register_arg_p (const char *str)
-{
- return (strprefix (str, "ctl")
- || strprefix (str, "cpuid")
- || strprefix (str, "status")
- || strprefix (str, "estatus")
- || strprefix (str, "bstatus")
- || strprefix (str, "ienable")
- || strprefix (str, "ipending")
- || strprefix (str, "exception")
- || strprefix (str, "pteaddr")
- || strprefix (str, "tlbacc")
- || strprefix (str, "tlbmisc")
- || strprefix (str, "eccinj")
- || strprefix (str, "config")
- || strprefix (str, "mpubase")
- || strprefix (str, "mpuacc")
- || strprefix (str, "badaddr"));
-}
/* Return true if STR is prefixed with a special relocation operator. */
static int
|| strprefix (str, "%gotoff"));
}
-/* Checks whether the register name is a coprocessor
- register - returns TRUE if it is, FALSE otherwise. */
-static bfd_boolean
-nios2_coproc_reg (const char *reg_name)
-{
- gas_assert (reg_name != NULL);
-
- /* Check that we do have a valid register name and that it is a
- coprocessor register.
- It must begin with c, not be a control register, and be a valid
- register name. */
- if (strprefix (reg_name, "c")
- && !strprefix (reg_name, "ctl")
- && hash_find (nios2_reg_hash, reg_name) != NULL)
- return TRUE;
- else
- return FALSE;
-}
/* nop fill pattern for text section. */
static char const nop[4] = { 0x3a, 0x88, 0x01, 0x00 };
target = fragp->fr_next->fr_address + stretch;
}
- /* We subtract 4 because all pc relative branches are
- from the next instruction. */
- offset = target - fragp->fr_address - fragp->fr_fix - 4;
+ /* We subtract fr_var (4 for 32-bit insns) because all pc relative
+ branches are from the next instruction. */
+ offset = target - fragp->fr_address - fragp->fr_fix - fragp->fr_var;
if (offset >= -32768 && offset <= 32764)
/* Fits in PC-relative branch. */
n = 0;
if (IS_CBRANCH (subtype))
{
unsigned int br_opcode;
+ unsigned int old_op, new_op;
int nbytes;
/* Account for the nextpc and jmp in the pc-relative case, or the two
nbytes = 12;
br_opcode = md_chars_to_number (buffer, 4);
- switch (br_opcode & OP_MASK_OP)
+ old_op = GET_IW_R1_OP (br_opcode);
+ switch (old_op)
{
- case OP_MATCH_BEQ:
- br_opcode = (br_opcode & ~OP_MASK_OP) | OP_MATCH_BNE;
+ case R1_OP_BEQ:
+ new_op = R1_OP_BNE;
break;
- case OP_MATCH_BNE:
- br_opcode = (br_opcode & ~OP_MASK_OP) | OP_MATCH_BEQ ;
+ case R1_OP_BNE:
+ new_op = R1_OP_BEQ;
break;
- case OP_MATCH_BGE:
- br_opcode = (br_opcode & ~OP_MASK_OP) | OP_MATCH_BLT ;
+ case R1_OP_BGE:
+ new_op = R1_OP_BLT;
break;
- case OP_MATCH_BGEU:
- br_opcode = (br_opcode & ~OP_MASK_OP) | OP_MATCH_BLTU ;
+ case R1_OP_BGEU:
+ new_op = R1_OP_BLTU;
break;
- case OP_MATCH_BLT:
- br_opcode = (br_opcode & ~OP_MASK_OP) | OP_MATCH_BGE ;
+ case R1_OP_BLT:
+ new_op = R1_OP_BGE;
break;
- case OP_MATCH_BLTU:
- br_opcode = (br_opcode & ~OP_MASK_OP) | OP_MATCH_BGEU ;
+ case R1_OP_BLTU:
+ new_op = R1_OP_BGEU;
break;
default:
as_bad_where (fragp->fr_file, fragp->fr_line,
abort ();
}
- br_opcode = br_opcode | (nbytes << OP_SH_IMM16);
+ br_opcode = (br_opcode & ~IW_R1_OP_SHIFTED_MASK) | SET_IW_R1_OP (new_op);
+ br_opcode = br_opcode | SET_IW_I_IMM16 (nbytes);
md_number_to_chars (buffer, br_opcode, 4);
fragp->fr_fix += 4;
buffer += 4;
{
/* Insert the nextpc instruction. */
md_number_to_chars (buffer,
- OP_MATCH_NEXTPC | (AT_REGNUM << OP_SH_RRD), 4);
+ MATCH_R1_NEXTPC | SET_IW_R_C (AT_REGNUM), 4);
fragp->fr_fix += 4;
buffer += 4;
addend = 32767;
else
addend = -32768;
- addend_mask = (((unsigned int)addend) & 0xffff) << OP_SH_IMM16;
+ addend_mask = SET_IW_I_IMM16 ((unsigned int)addend);
/* Insert n-1 addi instructions. */
- addi_mask = (OP_MATCH_ADDI
- | (AT_REGNUM << OP_SH_IRD)
- | (AT_REGNUM << OP_SH_IRS));
+ addi_mask = (MATCH_R1_ADDI
+ | SET_IW_I_B (AT_REGNUM)
+ | SET_IW_I_A (AT_REGNUM));
for (i = 0; i < n - 1; i ++)
{
md_number_to_chars (buffer, addi_mask | addend_mask, 4);
/* Insert the last addi instruction to hold the remainder. */
remainder = offset - addend * (n - 1);
gas_assert (remainder >= -32768 && remainder <= 32767);
- addend_mask = (((unsigned int)remainder) & 0xffff) << OP_SH_IMM16;
+ addend_mask = SET_IW_I_IMM16 ((unsigned int)remainder);
md_number_to_chars (buffer, addi_mask | addend_mask, 4);
fragp->fr_fix += 4;
buffer += 4;
/* Load at for the absolute case. */
else
{
- md_number_to_chars (buffer, OP_MATCH_ORHI | 0x00400000, 4);
+ md_number_to_chars (buffer,
+ (MATCH_R1_ORHI | SET_IW_I_B (AT_REGNUM)
+ | SET_IW_I_A (0)),
+ 4);
fix_new (fragp, fragp->fr_fix, 4, fragp->fr_symbol, fragp->fr_offset,
0, BFD_RELOC_NIOS2_HI16);
fragp->fr_fix += 4;
buffer += 4;
- md_number_to_chars (buffer, OP_MATCH_ORI | 0x08400000, 4);
+ md_number_to_chars (buffer,
+ (MATCH_R1_ORI | SET_IW_I_B (AT_REGNUM)
+ | SET_IW_I_A (AT_REGNUM)),
+ 4);
fix_new (fragp, fragp->fr_fix, 4, fragp->fr_symbol, fragp->fr_offset,
0, BFD_RELOC_NIOS2_LO16);
fragp->fr_fix += 4;
}
/* Insert the jmp instruction. */
- md_number_to_chars (buffer, OP_MATCH_JMP | (AT_REGNUM << OP_SH_RRS), 4);
+ md_number_to_chars (buffer, MATCH_R1_JMP | SET_IW_R_A (AT_REGNUM), 4);
fragp->fr_fix += 4;
buffer += 4;
}
unsigned int range_min;
unsigned int range_max;
unsigned int address;
- gas_assert (fixP->fx_size == 4);
+
opcode = nios2_find_opcode_hash (value);
gas_assert (opcode);
+ gas_assert (fixP->fx_size == opcode->size);
overflow_msg_type = opcode->overflow_msg;
switch (overflow_msg_type)
{
FIXME : for some reason fixP->fx_pcrel isn't 1 when it should be
so I'm using the howto structure instead to determine this. */
if (howto->pc_relative == 1)
- fixup = fixup - (fixP->fx_frag->fr_address + fixP->fx_where + 4);
+ fixup = fixup - (fixP->fx_frag->fr_address + fixP->fx_where
+ + fixP->fx_size);
/* Get the instruction or data to be fixed up. */
buf = fixP->fx_frag->fr_literal + fixP->fx_where;
\f
/** Instruction parsing support. */
+/* General internal error routine. */
+
+static void
+bad_opcode (const struct nios2_opcode *op)
+{
+ fprintf (stderr, _("internal error: broken opcode descriptor for `%s %s'\n"),
+ op->name, op->args);
+ as_fatal (_("Broken assembler. No assembly attempted."));
+}
+
/* Special relocation directive strings. */
struct nios2_special_relocS
}
#endif
+/* Look up a register name and validate it for the given regtype.
+ Return the register mapping or NULL on failure. */
+static struct nios2_reg *
+nios2_parse_reg (const char *token, unsigned long regtype)
+{
+ struct nios2_reg *reg = nios2_reg_lookup (token);
+
+ if (reg == NULL)
+ {
+ as_bad (_("unknown register %s"), token);
+ return NULL;
+ }
+
+ /* Matched a register, but is it the wrong type? */
+ if (!(regtype & reg->regtype))
+ {
+ if (regtype & REG_CONTROL)
+ as_bad (_("expecting control register"));
+ else if (reg->regtype & REG_CONTROL)
+ as_bad (_("illegal use of control register"));
+ else if (reg->regtype & REG_COPROCESSOR)
+ as_bad (_("illegal use of coprocessor register"));
+ else
+ as_bad (_("invalid register %s"), token);
+ return NULL;
+ }
+
+ /* Warn for explicit use of special registers. */
+ if (reg->regtype & REG_NORMAL)
+ {
+ if (!nios2_as_options.noat && reg->index == 1)
+ as_warn (_("Register at (r1) can sometimes be corrupted by "
+ "assembler optimizations.\n"
+ "Use .set noat to turn off those optimizations "
+ "(and this warning)."));
+ if (!nios2_as_options.nobreak && reg->index == 25)
+ as_warn (_("The debugger will corrupt bt (r25).\n"
+ "If you don't need to debug this "
+ "code use .set nobreak to turn off this warning."));
+ if (!nios2_as_options.nobreak && reg->index == 30)
+ as_warn (_("The debugger will corrupt sstatus/ba (r30).\n"
+ "If you don't need to debug this "
+ "code use .set nobreak to turn off this warning."));
+ }
+
+ return reg;
+}
+
/* The various nios2_assemble_* functions call this
function to generate an expression from a string representing an expression.
It then tries to evaluate the expression, and if it can, returns its value.
static unsigned long
nios2_assemble_expression (const char *exprstr,
nios2_insn_infoS *insn,
- nios2_insn_relocS *prev_reloc,
bfd_reloc_code_real_type reloc_type,
unsigned int pcrel)
{
/* We potentially have a relocation. */
reloc = nios2_insn_reloc_new (reloc_type, pcrel);
- if (prev_reloc != NULL)
- prev_reloc->reloc_next = reloc;
- else
- insn->insn_reloc = reloc;
+ reloc->reloc_next = insn->insn_reloc;
+ insn->insn_reloc = reloc;
/* Parse the expression string. */
saved_line_ptr = input_line_pointer;
return (unsigned long) value;
}
-/* Argument assemble functions.
- All take an instruction argument string, and a pointer
- to an instruction opcode. Upon return the insn_opcode
- has the relevant fields filled in to represent the arg
- string. The return value is NULL if successful, or
- an error message if an error was detected.
-
- The naming conventions for these functions match the args template
- in the nios2_opcode structure, as documented in include/opcode/nios2.h.
- For example, nios2_assemble_args_dst is used for instructions with
- "d,s,t" args.
- See nios2_arg_info_structs below for the exact correspondence. */
-static void
-nios2_assemble_args_dst (nios2_insn_infoS *insn_info)
+/* Argument assemble functions. */
+static void
+nios2_assemble_arg_c (const char *token, nios2_insn_infoS *insn)
{
- if (insn_info->insn_tokens[1] != NULL
- && insn_info->insn_tokens[2] != NULL
- && insn_info->insn_tokens[3] != NULL)
- {
- struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]);
- struct nios2_reg *src1 = nios2_reg_lookup (insn_info->insn_tokens[2]);
- struct nios2_reg *src2 = nios2_reg_lookup (insn_info->insn_tokens[3]);
-
- if (dst == NULL)
- as_bad (_("unknown register %s"), insn_info->insn_tokens[1]);
- else
- SET_INSN_FIELD (RRD, insn_info->insn_code, dst->index);
+ struct nios2_reg *reg = nios2_parse_reg (token, REG_CONTROL);
+ const struct nios2_opcode *op = insn->insn_nios2_opcode;
- if (src1 == NULL)
- as_bad (_("unknown register %s"), insn_info->insn_tokens[2]);
- else
- SET_INSN_FIELD (RRS, insn_info->insn_code, src1->index);
-
- if (src2 == NULL)
- as_bad (_("unknown register %s"), insn_info->insn_tokens[3]);
- else
- SET_INSN_FIELD (RRT, insn_info->insn_code, src2->index);
+ if (reg == NULL)
+ return;
- nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[4]);
+ switch (op->format)
+ {
+ case iw_r_type:
+ insn->insn_code |= SET_IW_R_IMM5 (reg->index);
+ break;
+ default:
+ bad_opcode (op);
}
}
-static void
-nios2_assemble_args_tsi (nios2_insn_infoS *insn_info)
+static void
+nios2_assemble_arg_d (const char *token, nios2_insn_infoS *insn)
{
- if (insn_info->insn_tokens[1] != NULL &&
- insn_info->insn_tokens[2] != NULL && insn_info->insn_tokens[3] != NULL)
- {
- struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]);
- struct nios2_reg *src1 = nios2_reg_lookup (insn_info->insn_tokens[2]);
- unsigned int src2
- = nios2_assemble_expression (insn_info->insn_tokens[3], insn_info,
- insn_info->insn_reloc, BFD_RELOC_NIOS2_S16,
- 0);
-
- if (dst == NULL)
- as_bad (_("unknown register %s"), insn_info->insn_tokens[1]);
- else
- SET_INSN_FIELD (IRT, insn_info->insn_code, dst->index);
-
- if (src1 == NULL)
- as_bad (_("unknown register %s"), insn_info->insn_tokens[2]);
- else
- SET_INSN_FIELD (IRS, insn_info->insn_code, src1->index);
+ const struct nios2_opcode *op = insn->insn_nios2_opcode;
+ unsigned long regtype = REG_NORMAL;
+ struct nios2_reg *reg;
- SET_INSN_FIELD (IMM16, insn_info->insn_code, src2);
- nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[4]);
- SET_INSN_FIELD (IMM16, insn_info->insn_code, 0);
- }
-}
+ if (op->format == iw_custom_type)
+ regtype |= REG_COPROCESSOR;
+ reg = nios2_parse_reg (token, regtype);
+ if (reg == NULL)
+ return;
-static void
-nios2_assemble_args_tsu (nios2_insn_infoS *insn_info)
-{
- if (insn_info->insn_tokens[1] != NULL
- && insn_info->insn_tokens[2] != NULL
- && insn_info->insn_tokens[3] != NULL)
+ switch (op->format)
{
- struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]);
- struct nios2_reg *src1 = nios2_reg_lookup (insn_info->insn_tokens[2]);
- unsigned int src2
- = nios2_assemble_expression (insn_info->insn_tokens[3], insn_info,
- insn_info->insn_reloc, BFD_RELOC_NIOS2_U16,
- 0);
-
- if (dst == NULL)
- as_bad (_("unknown register %s"), insn_info->insn_tokens[1]);
- else
- SET_INSN_FIELD (IRT, insn_info->insn_code, dst->index);
-
- if (src1 == NULL)
- as_bad (_("unknown register %s"), insn_info->insn_tokens[2]);
+ case iw_r_type:
+ insn->insn_code |= SET_IW_R_C (reg->index);
+ break;
+ case iw_custom_type:
+ insn->insn_code |= SET_IW_CUSTOM_C (reg->index);
+ if (reg->regtype & REG_COPROCESSOR)
+ insn->insn_code |= SET_IW_CUSTOM_READC (0);
else
- SET_INSN_FIELD (IRS, insn_info->insn_code, src1->index);
-
- SET_INSN_FIELD (IMM16, insn_info->insn_code, src2);
- nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[4]);
- SET_INSN_FIELD (IMM16, insn_info->insn_code, 0);
+ insn->insn_code |= SET_IW_CUSTOM_READC (1);
+ break;
+ default:
+ bad_opcode (op);
}
}
-static void
-nios2_assemble_args_sto (nios2_insn_infoS *insn_info)
+static void
+nios2_assemble_arg_s (const char *token, nios2_insn_infoS *insn)
{
- if (insn_info->insn_tokens[1] != NULL
- && insn_info->insn_tokens[2] != NULL
- && insn_info->insn_tokens[3] != NULL)
- {
- struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]);
- struct nios2_reg *src1 = nios2_reg_lookup (insn_info->insn_tokens[2]);
- unsigned int src2
- = nios2_assemble_expression (insn_info->insn_tokens[3], insn_info,
- insn_info->insn_reloc, BFD_RELOC_16_PCREL,
- 1);
-
- if (dst == NULL)
- as_bad (_("unknown register %s"), insn_info->insn_tokens[1]);
- else
- SET_INSN_FIELD (IRS, insn_info->insn_code, dst->index);
+ const struct nios2_opcode *op = insn->insn_nios2_opcode;
+ unsigned long regtype = REG_NORMAL;
+ struct nios2_reg *reg;
- if (src1 == NULL)
- as_bad (_("unknown register %s"), insn_info->insn_tokens[2]);
- else
- SET_INSN_FIELD (IRT, insn_info->insn_code, src1->index);
+ if (op->format == iw_custom_type)
+ regtype |= REG_COPROCESSOR;
+ reg = nios2_parse_reg (token, regtype);
+ if (reg == NULL)
+ return;
- SET_INSN_FIELD (IMM16, insn_info->insn_code, src2);
- nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[4]);
- SET_INSN_FIELD (IMM16, insn_info->insn_code, 0);
- }
-}
-
-static void
-nios2_assemble_args_o (nios2_insn_infoS *insn_info)
-{
- if (insn_info->insn_tokens[1] != NULL)
+ switch (op->format)
{
- unsigned long immed
- = nios2_assemble_expression (insn_info->insn_tokens[1], insn_info,
- insn_info->insn_reloc, BFD_RELOC_16_PCREL,
- 1);
- SET_INSN_FIELD (IMM16, insn_info->insn_code, immed);
- nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[2]);
- SET_INSN_FIELD (IMM16, insn_info->insn_code, 0);
+ case iw_r_type:
+ insn->insn_code |= SET_IW_R_A (reg->index);
+ break;
+ case iw_i_type:
+ insn->insn_code |= SET_IW_I_A (reg->index);
+ break;
+ case iw_custom_type:
+ insn->insn_code |= SET_IW_CUSTOM_A (reg->index);
+ if (reg->regtype & REG_COPROCESSOR)
+ insn->insn_code |= SET_IW_CUSTOM_READA (0);
+ else
+ insn->insn_code |= SET_IW_CUSTOM_READA (1);
+ break;
+ default:
+ bad_opcode (op);
}
}
-static void
-nios2_assemble_args_is (nios2_insn_infoS *insn_info)
+static void
+nios2_assemble_arg_t (const char *token, nios2_insn_infoS *insn)
{
- if (insn_info->insn_tokens[1] != NULL && insn_info->insn_tokens[2] != NULL)
- {
- struct nios2_reg *addr_src = nios2_reg_lookup (insn_info->insn_tokens[2]);
- unsigned long immed
- = nios2_assemble_expression (insn_info->insn_tokens[1], insn_info,
- insn_info->insn_reloc, BFD_RELOC_NIOS2_S16,
- 0);
+ const struct nios2_opcode *op = insn->insn_nios2_opcode;
+ unsigned long regtype = REG_NORMAL;
+ struct nios2_reg *reg;
- SET_INSN_FIELD (IMM16, insn_info->insn_code, immed);
+ if (op->format == iw_custom_type)
+ regtype |= REG_COPROCESSOR;
+ reg = nios2_parse_reg (token, regtype);
+ if (reg == NULL)
+ return;
- if (addr_src == NULL)
- as_bad (_("unknown base register %s"), insn_info->insn_tokens[2]);
+ switch (op->format)
+ {
+ case iw_r_type:
+ insn->insn_code |= SET_IW_R_B (reg->index);
+ break;
+ case iw_i_type:
+ insn->insn_code |= SET_IW_I_B (reg->index);
+ break;
+ case iw_custom_type:
+ insn->insn_code |= SET_IW_CUSTOM_B (reg->index);
+ if (reg->regtype & REG_COPROCESSOR)
+ insn->insn_code |= SET_IW_CUSTOM_READB (0);
else
- SET_INSN_FIELD (RRS, insn_info->insn_code, addr_src->index);
-
- nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[3]);
- SET_INSN_FIELD (IMM16, insn_info->insn_code, 0);
+ insn->insn_code |= SET_IW_CUSTOM_READB (1);
+ break;
+ default:
+ bad_opcode (op);
}
}
-static void
-nios2_assemble_args_m (nios2_insn_infoS *insn_info)
+static void
+nios2_assemble_arg_i (const char *token, nios2_insn_infoS *insn)
{
- if (insn_info->insn_tokens[1] != NULL)
- {
- unsigned long immed
- = nios2_assemble_expression (insn_info->insn_tokens[1], insn_info,
- insn_info->insn_reloc,
- (nios2_as_options.noat
- ? BFD_RELOC_NIOS2_CALL26_NOAT
- : BFD_RELOC_NIOS2_CALL26),
- 0);
-
- SET_INSN_FIELD (IMM26, insn_info->insn_code, immed);
- nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[2]);
- SET_INSN_FIELD (IMM26, insn_info->insn_code, 0);
- }
-}
+ const struct nios2_opcode *op = insn->insn_nios2_opcode;
+ unsigned int val;
-static void
-nios2_assemble_args_s (nios2_insn_infoS *insn_info)
-{
- if (insn_info->insn_tokens[1] != NULL)
+ switch (op->format)
{
- struct nios2_reg *src = nios2_reg_lookup (insn_info->insn_tokens[1]);
- if (src == NULL)
- as_bad (_("unknown register %s"), insn_info->insn_tokens[1]);
- else
- SET_INSN_FIELD (RRS, insn_info->insn_code, src->index);
-
- nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[2]);
+ case iw_i_type:
+ val = nios2_assemble_expression (token, insn,
+ BFD_RELOC_NIOS2_S16, 0);
+ insn->constant_bits |= SET_IW_I_IMM16 (val);
+ break;
+ default:
+ bad_opcode (op);
}
}
-static void
-nios2_assemble_args_tis (nios2_insn_infoS *insn_info)
+static void
+nios2_assemble_arg_u (const char *token, nios2_insn_infoS *insn)
{
- if (insn_info->insn_tokens[1] != NULL
- && insn_info->insn_tokens[2] != NULL
- && insn_info->insn_tokens[3] != NULL)
- {
- struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]);
- struct nios2_reg *addr_src = nios2_reg_lookup (insn_info->insn_tokens[3]);
- unsigned long immed
- = nios2_assemble_expression (insn_info->insn_tokens[2], insn_info,
- insn_info->insn_reloc, BFD_RELOC_NIOS2_S16,
- 0);
-
- if (addr_src == NULL)
- as_bad (_("unknown register %s"), insn_info->insn_tokens[3]);
- else
- SET_INSN_FIELD (RRS, insn_info->insn_code, addr_src->index);
-
- if (dst == NULL)
- as_bad (_("unknown register %s"), insn_info->insn_tokens[1]);
- else
- SET_INSN_FIELD (RRT, insn_info->insn_code, dst->index);
+ const struct nios2_opcode *op = insn->insn_nios2_opcode;
+ unsigned int val;
- SET_INSN_FIELD (IMM16, insn_info->insn_code, immed);
- nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[4]);
- SET_INSN_FIELD (IMM16, insn_info->insn_code, 0);
- }
-}
-
-static void
-nios2_assemble_args_dc (nios2_insn_infoS *insn_info)
-{
- if (insn_info->insn_tokens[1] != NULL && insn_info->insn_tokens[2] != NULL)
+ switch (op->format)
{
- struct nios2_reg *ctl = nios2_reg_lookup (insn_info->insn_tokens[2]);
- struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]);
-
- if (ctl == NULL)
- as_bad (_("unknown register %s"), insn_info->insn_tokens[1]);
- else
- SET_INSN_FIELD (RCTL, insn_info->insn_code, ctl->index);
-
- if (dst == NULL)
- as_bad (_("unknown register %s"), insn_info->insn_tokens[2]);
- else
- SET_INSN_FIELD (RRD, insn_info->insn_code, dst->index);
-
- nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[3]);
+ case iw_i_type:
+ val = nios2_assemble_expression (token, insn,
+ BFD_RELOC_NIOS2_U16, 0);
+ insn->constant_bits |= SET_IW_I_IMM16 (val);
+ break;
+ default:
+ bad_opcode (op);
}
}
-static void
-nios2_assemble_args_cs (nios2_insn_infoS *insn_info)
+static void
+nios2_assemble_arg_o (const char *token, nios2_insn_infoS *insn)
{
- if (insn_info->insn_tokens[1] != NULL && insn_info->insn_tokens[2] != NULL)
- {
- struct nios2_reg *ctl = nios2_reg_lookup (insn_info->insn_tokens[1]);
- struct nios2_reg *src = nios2_reg_lookup (insn_info->insn_tokens[2]);
-
- if (ctl == NULL)
- as_bad (_("unknown register %s"), insn_info->insn_tokens[1]);
- else if (ctl->index == 4)
- as_bad (_("ipending control register (ctl4) is read-only\n"));
- else
- SET_INSN_FIELD (RCTL, insn_info->insn_code, ctl->index);
+ const struct nios2_opcode *op = insn->insn_nios2_opcode;
+ unsigned int val;
- if (src == NULL)
- as_bad (_("unknown register %s"), insn_info->insn_tokens[2]);
- else
- SET_INSN_FIELD (RRS, insn_info->insn_code, src->index);
-
- nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[3]);
+ switch (op->format)
+ {
+ case iw_i_type:
+ val = nios2_assemble_expression (token, insn,
+ BFD_RELOC_16_PCREL, 1);
+ insn->constant_bits |= SET_IW_I_IMM16 (val);
+ break;
+ default:
+ bad_opcode (op);
}
}
-static void
-nios2_assemble_args_ds (nios2_insn_infoS * insn_info)
+static void
+nios2_assemble_arg_j (const char *token, nios2_insn_infoS *insn)
{
- if (insn_info->insn_tokens[1] != NULL && insn_info->insn_tokens[2] != NULL)
- {
- struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]);
- struct nios2_reg *src = nios2_reg_lookup (insn_info->insn_tokens[2]);
-
- if (dst == NULL)
- as_bad (_("unknown register %s"), insn_info->insn_tokens[1]);
- else
- SET_INSN_FIELD (RRD, insn_info->insn_code, dst->index);
-
- if (src == NULL)
- as_bad (_("unknown register %s"), insn_info->insn_tokens[2]);
- else
- SET_INSN_FIELD (RRS, insn_info->insn_code, src->index);
+ const struct nios2_opcode *op = insn->insn_nios2_opcode;
+ unsigned int val;
- nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[3]);
+ switch (op->format)
+ {
+ case iw_r_type:
+ val = nios2_assemble_expression (token, insn,
+ BFD_RELOC_NIOS2_IMM5, 0);
+ insn->constant_bits |= SET_IW_R_IMM5 (val);
+ break;
+ default:
+ bad_opcode (op);
}
}
-static void
-nios2_assemble_args_ldst (nios2_insn_infoS *insn_info)
+static void
+nios2_assemble_arg_l (const char *token, nios2_insn_infoS *insn)
{
- if (insn_info->insn_tokens[1] != NULL
- && insn_info->insn_tokens[2] != NULL
- && insn_info->insn_tokens[3] != NULL
- && insn_info->insn_tokens[4] != NULL)
- {
- unsigned long custom_n
- = nios2_assemble_expression (insn_info->insn_tokens[1], insn_info,
- insn_info->insn_reloc,
- BFD_RELOC_NIOS2_IMM8, 0);
-
- struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[2]);
- struct nios2_reg *src1 = nios2_reg_lookup (insn_info->insn_tokens[3]);
- struct nios2_reg *src2 = nios2_reg_lookup (insn_info->insn_tokens[4]);
+ const struct nios2_opcode *op = insn->insn_nios2_opcode;
+ unsigned int val;
- SET_INSN_FIELD (CUSTOM_N, insn_info->insn_code, custom_n);
-
- if (dst == NULL)
- as_bad (_("unknown register %s"), insn_info->insn_tokens[2]);
- else
- SET_INSN_FIELD (RRD, insn_info->insn_code, dst->index);
-
- if (src1 == NULL)
- as_bad (_("unknown register %s"), insn_info->insn_tokens[3]);
- else
- SET_INSN_FIELD (RRS, insn_info->insn_code, src1->index);
-
- if (src2 == NULL)
- as_bad (_("unknown register %s"), insn_info->insn_tokens[4]);
- else
- SET_INSN_FIELD (RRT, insn_info->insn_code, src2->index);
-
- /* Set or clear the bits to indicate whether coprocessor registers are
- used. */
- if (nios2_coproc_reg (insn_info->insn_tokens[2]))
- SET_INSN_FIELD (CUSTOM_C, insn_info->insn_code, 0);
- else
- SET_INSN_FIELD (CUSTOM_C, insn_info->insn_code, 1);
-
- if (nios2_coproc_reg (insn_info->insn_tokens[3]))
- SET_INSN_FIELD (CUSTOM_A, insn_info->insn_code, 0);
- else
- SET_INSN_FIELD (CUSTOM_A, insn_info->insn_code, 1);
-
- if (nios2_coproc_reg (insn_info->insn_tokens[4]))
- SET_INSN_FIELD (CUSTOM_B, insn_info->insn_code, 0);
- else
- SET_INSN_FIELD (CUSTOM_B, insn_info->insn_code, 1);
-
- nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[5]);
+ switch (op->format)
+ {
+ case iw_custom_type:
+ val = nios2_assemble_expression (token, insn,
+ BFD_RELOC_NIOS2_IMM8, 0);
+ insn->constant_bits |= SET_IW_CUSTOM_N (val);
+ break;
+ default:
+ bad_opcode (op);
}
}
-static void
-nios2_assemble_args_none (nios2_insn_infoS *insn_info ATTRIBUTE_UNUSED)
+static void
+nios2_assemble_arg_m (const char *token, nios2_insn_infoS *insn)
{
- /* Nothing to do. */
-}
+ const struct nios2_opcode *op = insn->insn_nios2_opcode;
+ unsigned int val;
-static void
-nios2_assemble_args_dsj (nios2_insn_infoS *insn_info)
-{
- if (insn_info->insn_tokens[1] != NULL
- && insn_info->insn_tokens[2] != NULL
- && insn_info->insn_tokens[3] != NULL)
+ switch (op->format)
{
- struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]);
- struct nios2_reg *src1 = nios2_reg_lookup (insn_info->insn_tokens[2]);
-
- /* A 5-bit constant expression. */
- unsigned int src2 =
- nios2_assemble_expression (insn_info->insn_tokens[3], insn_info,
- insn_info->insn_reloc,
- BFD_RELOC_NIOS2_IMM5, 0);
-
- if (dst == NULL)
- as_bad (_("unknown register %s"), insn_info->insn_tokens[1]);
- else
- SET_INSN_FIELD (RRD, insn_info->insn_code, dst->index);
-
- if (src1 == NULL)
- as_bad (_("unknown register %s"), insn_info->insn_tokens[2]);
- else
- SET_INSN_FIELD (RRS, insn_info->insn_code, src1->index);
-
- SET_INSN_FIELD (IMM5, insn_info->insn_code, src2);
- nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[4]);
- SET_INSN_FIELD (IMM5, insn_info->insn_code, 0);
+ case iw_j_type:
+ val = nios2_assemble_expression (token, insn,
+ (nios2_as_options.noat
+ ? BFD_RELOC_NIOS2_CALL26_NOAT
+ : BFD_RELOC_NIOS2_CALL26),
+ 0);
+ insn->constant_bits |= SET_IW_J_IMM26 (val);
+ break;
+ default:
+ bad_opcode (op);
}
}
static void
-nios2_assemble_args_d (nios2_insn_infoS *insn_info)
+nios2_assemble_args (nios2_insn_infoS *insn)
{
- if (insn_info->insn_tokens[1] != NULL)
- {
- struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]);
-
- if (dst == NULL)
- as_bad (_("unknown register %s"), insn_info->insn_tokens[1]);
- else
- SET_INSN_FIELD (RRD, insn_info->insn_code, dst->index);
+ const struct nios2_opcode *op = insn->insn_nios2_opcode;
+ const char *argptr;
+ unsigned int tokidx, ntok;
- nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[2]);
- }
-}
+ /* Make sure there are enough arguments. */
+ ntok = (op->pinfo & NIOS2_INSN_OPTARG) ? op->num_args - 1 : op->num_args;
+ for (tokidx = 1; tokidx <= ntok; tokidx++)
+ if (insn->insn_tokens[tokidx] == NULL)
+ {
+ as_bad ("missing argument");
+ return;
+ }
-static void
-nios2_assemble_args_b (nios2_insn_infoS *insn_info)
-{
- unsigned int imm5 = 0;
+ for (argptr = op->args, tokidx = 1;
+ *argptr && insn->insn_tokens[tokidx];
+ argptr++)
+ switch (*argptr)
+ {
+ case ',':
+ case '(':
+ case ')':
+ break;
- if (insn_info->insn_tokens[1] != NULL)
- {
- /* A 5-bit constant expression. */
- imm5 = nios2_assemble_expression (insn_info->insn_tokens[1],
- insn_info, insn_info->insn_reloc,
- BFD_RELOC_NIOS2_IMM5, 0);
- SET_INSN_FIELD (TRAP_IMM5, insn_info->insn_code, imm5);
- nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[2]);
- }
+ case 'c':
+ nios2_assemble_arg_c (insn->insn_tokens[tokidx++], insn);
+ break;
+
+ case 'd':
+ nios2_assemble_arg_d (insn->insn_tokens[tokidx++], insn);
+ break;
+
+ case 's':
+ nios2_assemble_arg_s (insn->insn_tokens[tokidx++], insn);
+ break;
+
+ case 't':
+ nios2_assemble_arg_t (insn->insn_tokens[tokidx++], insn);
+ break;
+
+ case 'i':
+ nios2_assemble_arg_i (insn->insn_tokens[tokidx++], insn);
+ break;
+
+ case 'u':
+ nios2_assemble_arg_u (insn->insn_tokens[tokidx++], insn);
+ break;
+
+ case 'o':
+ nios2_assemble_arg_o (insn->insn_tokens[tokidx++], insn);
+ break;
+
+ case 'j':
+ nios2_assemble_arg_j (insn->insn_tokens[tokidx++], insn);
+ break;
+
+ case 'l':
+ nios2_assemble_arg_l (insn->insn_tokens[tokidx++], insn);
+ break;
+
+ case 'm':
+ nios2_assemble_arg_m (insn->insn_tokens[tokidx++], insn);
+ break;
+
+ default:
+ bad_opcode (op);
+ break;
+ }
- SET_INSN_FIELD (TRAP_IMM5, insn_info->insn_code, imm5);
-
- nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[2]);
-}
-
-/* This table associates pointers to functions that parse the arguments to an
- instruction and fill in the relevant fields of the instruction. */
-const nios2_arg_infoS nios2_arg_info_structs[] = {
- /* args, assemble_args_func */
- {"d,s,t", nios2_assemble_args_dst},
- {"d,s,t,E", nios2_assemble_args_dst},
- {"t,s,i", nios2_assemble_args_tsi},
- {"t,s,i,E", nios2_assemble_args_tsi},
- {"t,s,u", nios2_assemble_args_tsu},
- {"t,s,u,E", nios2_assemble_args_tsu},
- {"s,t,o", nios2_assemble_args_sto},
- {"s,t,o,E", nios2_assemble_args_sto},
- {"o", nios2_assemble_args_o},
- {"o,E", nios2_assemble_args_o},
- {"s", nios2_assemble_args_s},
- {"s,E", nios2_assemble_args_s},
- {"", nios2_assemble_args_none},
- {"E", nios2_assemble_args_none},
- {"i(s)", nios2_assemble_args_is},
- {"i(s)E", nios2_assemble_args_is},
- {"m", nios2_assemble_args_m},
- {"m,E", nios2_assemble_args_m},
- {"t,i(s)", nios2_assemble_args_tis},
- {"t,i(s)E", nios2_assemble_args_tis},
- {"d,c", nios2_assemble_args_dc},
- {"d,c,E", nios2_assemble_args_dc},
- {"c,s", nios2_assemble_args_cs},
- {"c,s,E", nios2_assemble_args_cs},
- {"d,s", nios2_assemble_args_ds},
- {"d,s,E", nios2_assemble_args_ds},
- {"l,d,s,t", nios2_assemble_args_ldst},
- {"l,d,s,t,E", nios2_assemble_args_ldst},
- {"d,s,j", nios2_assemble_args_dsj},
- {"d,s,j,E", nios2_assemble_args_dsj},
- {"d", nios2_assemble_args_d},
- {"d,E", nios2_assemble_args_d},
- {"b", nios2_assemble_args_b},
- {"b,E", nios2_assemble_args_b}
-};
+ /* Perform argument checking. */
+ nios2_check_assembly (insn->insn_code | insn->constant_bits,
+ insn->insn_tokens[tokidx]);
+}
-#define NIOS2_NUM_ARGS \
- ((sizeof(nios2_arg_info_structs)/sizeof(nios2_arg_info_structs[0])))
-const int nios2_num_arg_info_structs = NIOS2_NUM_ARGS;
/* The function consume_arg takes a pointer into a string
of instruction tokens (args) and a pointer into a string
expected type, throwing an error if it is not, and returns
the pointer argstr. */
static char *
-nios2_consume_arg (nios2_insn_infoS *insn, char *argstr, const char *parsestr)
+nios2_consume_arg (char *argstr, const char *parsestr)
{
char *temp;
- int regno = -1;
switch (*parsestr)
{
case 'c':
- if (!nios2_control_register_arg_p (argstr))
- as_bad (_("expecting control register"));
- break;
case 'd':
case 's':
case 't':
-
- /* We check to make sure we don't have a control register. */
- if (nios2_control_register_arg_p (argstr))
- as_bad (_("illegal use of control register"));
-
- /* And whether coprocessor registers are valid here. */
- if (nios2_coproc_reg (argstr)
- && insn->insn_nios2_opcode->match != OP_MATCH_CUSTOM)
- as_bad (_("illegal use of coprocessor register\n"));
-
- /* Extract a register number if the register is of the
- form r[0-9]+, if it is a normal register, set
- regno to its number (0-31), else set regno to -1. */
- if (argstr[0] == 'r' && ISDIGIT (argstr[1]))
- {
- char *p = argstr;
-
- ++p;
- regno = 0;
- do
- {
- regno *= 10;
- regno += *p - '0';
- ++p;
- }
- while (ISDIGIT (*p));
- }
- else
- regno = -1;
-
- /* And whether we are using at. */
- if (!nios2_as_options.noat
- && (regno == 1 || strprefix (argstr, "at")))
- as_warn (_("Register at (r1) can sometimes be corrupted by assembler "
- "optimizations.\n"
- "Use .set noat to turn off those optimizations (and this "
- "warning)."));
-
- /* And whether we are using oci registers. */
- if (!nios2_as_options.nobreak
- && (regno == 25 || strprefix (argstr, "bt")))
- as_warn (_("The debugger will corrupt bt (r25).\n"
- "If you don't need to debug this "
- "code use .set nobreak to turn off this warning."));
-
- if (!nios2_as_options.nobreak
- && (regno == 30
- || strprefix (argstr, "ba")
- || strprefix (argstr, "sstatus")))
- as_warn (_("The debugger will corrupt sstatus/ba (r30).\n"
- "If you don't need to debug this "
- "code use .set nobreak to turn off this warning."));
break;
+
case 'i':
case 'u':
if (*argstr == '%')
case 'm':
case 'j':
case 'l':
- case 'b':
/* We can't have %hi, %lo or %hiadj here. */
if (*argstr == '%')
as_bad (_("badly formed expression near %s"), argstr);
if (p != NULL)
*p++ = 0;
- else
- as_bad (_("expecting %c near %s"), *separator, argstr);
return p;
}
while (p != NULL && !terminate && i < NIOS2_MAX_INSN_TOKENS)
{
- parsed_args[i] = nios2_consume_arg (insn, p, parsestr);
+ parsed_args[i] = nios2_consume_arg (p, parsestr);
++parsestr;
- if (*parsestr != '\0')
+ while (*parsestr == '(' || *parsestr == ')' || *parsestr == ',')
{
+ char *context = p;
p = nios2_consume_separator (p, parsestr);
+ /* Check for missing separators. */
+ if (!p && !(insn->insn_nios2_opcode->pinfo & NIOS2_INSN_OPTARG))
+ {
+ as_bad (_("expecting %c near %s"), *parsestr, context);
+ break;
+ }
++parsestr;
}
- else
+
+ if (*parsestr == '\0')
{
/* Check that the argument string has no trailing arguments. */
- /* If we've got a %lo etc relocation, we've zapped the parens with
- spaces. */
- if (nios2_special_relocation_p (p))
- end = strpbrk (p, ",");
- else
- end = strpbrk (p, " ,");
-
+ end = strpbrk (p, ",");
if (end != NULL)
as_bad (_("too many arguments"));
}
}
parsed_args[i] = NULL;
-
- /* The argument to break and trap instructions is optional; complain
- for other cases of missing arguments. */
- if (*parsestr != '\0'
- && insn->insn_nios2_opcode->match != OP_MATCH_BREAK
- && insn->insn_nios2_opcode->match != OP_MATCH_TRAP)
- as_bad (_("missing argument"));
}
output_insn (nios2_insn_infoS *insn)
{
char *f;
- nios2_insn_relocS *reloc;
-
- f = frag_more (4);
+ nios2_insn_relocS *reloc;
+ f = frag_more (insn->insn_nios2_opcode->size);
/* This allocates enough space for the instruction
and puts it in the current frag. */
- md_number_to_chars (f, insn->insn_code, 4);
+ md_number_to_chars (f, insn->insn_code, insn->insn_nios2_opcode->size);
/* Emit debug info. */
- dwarf2_emit_insn (4);
+ dwarf2_emit_insn (insn->insn_nios2_opcode->size);
/* Create any fixups to be acted on later. */
+
for (reloc = insn->insn_reloc; reloc != NULL; reloc = reloc->reloc_next)
- fix_new_exp (frag_now, f - frag_now->fr_literal, 4,
+ fix_new_exp (frag_now, f - frag_now->fr_literal,
+ insn->insn_nios2_opcode->size,
&reloc->reloc_expression, reloc->reloc_pcrel,
reloc->reloc_type);
}
to accommodate the largest possible instruction sequence
this may generate. */
f = frag_var (rs_machine_dependent,
- UBRANCH_MAX_SIZE, 4, UBRANCH_SUBTYPE (0),
- symp, offset, NULL);
+ UBRANCH_MAX_SIZE, insn->insn_nios2_opcode->size,
+ UBRANCH_SUBTYPE (0), symp, offset, NULL);
- md_number_to_chars (f, insn->insn_code, 4);
+ md_number_to_chars (f, insn->insn_code, insn->insn_nios2_opcode->size);
/* We leave fixup generation to md_convert_frag. */
}
to accommodate the largest possible instruction sequence
this may generate. */
f = frag_var (rs_machine_dependent,
- CBRANCH_MAX_SIZE, 4, CBRANCH_SUBTYPE (0),
- symp, offset, NULL);
+ CBRANCH_MAX_SIZE, insn->insn_nios2_opcode->size,
+ CBRANCH_SUBTYPE (0), symp, offset, NULL);
- md_number_to_chars (f, insn->insn_code, 4);
+ md_number_to_chars (f, insn->insn_code, insn->insn_nios2_opcode->size);
/* We leave fixup generation to md_convert_frag. */
}
char *f = frag_more (12);
nios2_insn_relocS *reloc = insn->insn_reloc;
- md_number_to_chars (f, OP_MATCH_ORHI | 0x00400000, 4);
+ md_number_to_chars (f,
+ (MATCH_R1_ORHI | SET_IW_I_B (AT_REGNUM)
+ | SET_IW_I_A (0)),
+ 4);
dwarf2_emit_insn (4);
fix_new_exp (frag_now, f - frag_now->fr_literal, 4,
&reloc->reloc_expression, 0, BFD_RELOC_NIOS2_HI16);
- md_number_to_chars (f + 4, OP_MATCH_ORI | 0x08400000, 4);
+ md_number_to_chars (f + 4,
+ (MATCH_R1_ORI | SET_IW_I_B (AT_REGNUM)
+ | SET_IW_I_A (AT_REGNUM)),
+ 4);
dwarf2_emit_insn (4);
fix_new_exp (frag_now, f - frag_now->fr_literal + 4, 4,
&reloc->reloc_expression, 0, BFD_RELOC_NIOS2_LO16);
- md_number_to_chars (f + 8, OP_MATCH_CALLR | 0x08000000, 4);
+ md_number_to_chars (f + 8, MATCH_R1_CALLR | SET_IW_R_A (AT_REGNUM), 4);
dwarf2_emit_insn (4);
}
if (can_evaluate_expr (insn))
{
int expr_val = get_expr_value (insn);
- if (GET_INSN_FIELD (RRS, insn->insn_code) == 0
+ unsigned int rega = GET_IW_I_A (insn->insn_code);
+ unsigned int regb = GET_IW_I_B (insn->insn_code);
+
+ if (rega == 0
&& (expr_val & 0xffff) == 0
&& expr_val != 0)
{
/* We really want a movhi (orhi) here. */
- insn->insn_code = (insn->insn_code & ~OP_MATCH_ADDI) | OP_MATCH_ORHI;
- insn->insn_reloc->reloc_expression.X_add_number =
- (insn->insn_reloc->reloc_expression.X_add_number >> 16) & 0xffff;
+ insn->insn_code
+ = MATCH_R1_ORHI | SET_IW_I_A (rega) | SET_IW_I_B (regb);
+ insn->insn_reloc->reloc_expression.X_add_number
+ = (expr_val >> 16) & 0xffff;
insn->insn_reloc->reloc_type = BFD_RELOC_NIOS2_U16;
}
}
int expr_val = get_expr_value (insn);
if (expr_val != 0 && (expr_val & 0xffff) == 0)
{
- /* We really want a movhi (orhi) here. */
- insn->insn_code = (insn->insn_code & ~OP_MATCH_ANDI) | OP_MATCH_ANDHI;
- insn->insn_reloc->reloc_expression.X_add_number =
- (insn->insn_reloc->reloc_expression.X_add_number >> 16) & 0xffff;
+ unsigned int rega = GET_IW_I_A (insn->insn_code);
+ unsigned int regb = GET_IW_I_B (insn->insn_code);
+
+ /* We really want an andhi here. */
+ insn->insn_code
+ = MATCH_R1_ANDHI | SET_IW_I_A (rega) | SET_IW_I_B (regb);
+ insn->insn_reloc->reloc_expression.X_add_number
+ = (expr_val >> 16) & 0xffff;
insn->insn_reloc->reloc_type = BFD_RELOC_NIOS2_U16;
}
}
int expr_val = get_expr_value (insn);
if (expr_val != 0 && (expr_val & 0xffff) == 0)
{
+ unsigned int rega = GET_IW_I_A (insn->insn_code);
+ unsigned int regb = GET_IW_I_B (insn->insn_code);
+
/* We really want a movhi (orhi) here. */
- insn->insn_code = (insn->insn_code & ~OP_MATCH_ORI) | OP_MATCH_ORHI;
- insn->insn_reloc->reloc_expression.X_add_number =
- (insn->insn_reloc->reloc_expression.X_add_number >> 16) & 0xffff;
+ insn->insn_code
+ = MATCH_R1_ORHI | SET_IW_I_A (rega) | SET_IW_I_B (regb);
+ insn->insn_reloc->reloc_expression.X_add_number
+ = (expr_val >> 16) & 0xffff;
insn->insn_reloc->reloc_type = BFD_RELOC_NIOS2_U16;
}
}
int expr_val = get_expr_value (insn);
if (expr_val != 0 && (expr_val & 0xffff) == 0)
{
- /* We really want a movhi (orhi) here. */
- insn->insn_code = (insn->insn_code & ~OP_MATCH_XORI) | OP_MATCH_XORHI;
- insn->insn_reloc->reloc_expression.X_add_number =
- (insn->insn_reloc->reloc_expression.X_add_number >> 16) & 0xffff;
+ unsigned int rega = GET_IW_I_A (insn->insn_code);
+ unsigned int regb = GET_IW_I_B (insn->insn_code);
+
+ /* We really want an xorhi here. */
+ insn->insn_code
+ = MATCH_R1_XORHI | SET_IW_I_A (rega) | SET_IW_I_B (regb);
+ insn->insn_reloc->reloc_expression.X_add_number
+ = (expr_val >> 16) & 0xffff;
insn->insn_reloc->reloc_type = BFD_RELOC_NIOS2_U16;
}
}
and puts it in the current frag. */
char *f = frag_more (8);
nios2_insn_relocS *reloc = insn->insn_reloc;
- unsigned long reg_index = GET_INSN_FIELD (IRT, insn->insn_code);
+ unsigned long reg_index = GET_IW_I_B (insn->insn_code);
/* If the reloc is NULL, there was an error assembling the movia. */
if (reloc != NULL)
{
md_number_to_chars (f, insn->insn_code, 4);
dwarf2_emit_insn (4);
- md_number_to_chars (f + 4,
- (OP_MATCH_ADDI | (reg_index << OP_SH_IRT)
- | (reg_index << OP_SH_IRS)),
- 4);
- dwarf2_emit_insn (4);
fix_new (frag_now, f - frag_now->fr_literal, 4,
reloc->reloc_expression.X_add_symbol,
reloc->reloc_expression.X_add_number, 0,
BFD_RELOC_NIOS2_HIADJ16);
+ md_number_to_chars (f + 4,
+ (MATCH_R1_ADDI | SET_IW_I_A (reg_index)
+ | SET_IW_I_B (reg_index)),
+ 4);
+ dwarf2_emit_insn (4);
fix_new (frag_now, f + 4 - frag_now->fr_literal, 4,
reloc->reloc_expression.X_add_symbol,
reloc->reloc_expression.X_add_number, 0, BFD_RELOC_NIOS2_LO16);
arguments. */
nios2_opcode_hash = hash_new ();
nios2_reg_hash = hash_new ();
- nios2_arg_hash = hash_new ();
nios2_ps_hash = hash_new ();
- for (i = 0; i < NUMOPCODES; ++i)
+ for (i = 0; i < nios2_num_opcodes; ++i)
{
inserted
= hash_insert (nios2_opcode_hash, nios2_opcodes[i].name,
}
- for (i = 0; i < nios2_num_arg_info_structs; ++i)
- {
- inserted
- = hash_insert (nios2_arg_hash, nios2_arg_info_structs[i].args,
- (PTR) & nios2_arg_info_structs[i]);
- if (inserted != NULL)
- {
- fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
- nios2_arg_info_structs[i].args, inserted);
- /* Probably a memory allocation problem? Give up now. */
- as_fatal (_("Broken assembler. No assembly attempted."));
- }
- }
-
for (i = 0; i < nios2_num_ps_insn_info_structs; ++i)
{
inserted
{
char *argstr;
char *op_strdup = NULL;
- nios2_arg_infoS *arg_info;
unsigned long saved_pinfo = 0;
nios2_insn_infoS thisinsn;
nios2_insn_infoS *insn = &thisinsn;
nios2_ps_insn_infoS *ps_insn = NULL;
/* Set the opcode for the instruction. */
insn->insn_code = insn->insn_nios2_opcode->match;
+ insn->constant_bits = 0;
/* Parse the arguments pointed to by argstr. */
if (nios2_mode == NIOS2_MODE_ASSEMBLE)
== NIOS2_INSN_MACRO)
ps_insn = nios2_translate_pseudo_insn (insn);
- /* Find the assemble function, and call it. */
- arg_info = nios2_arg_lookup (insn->insn_nios2_opcode->args);
- if (arg_info != NULL)
- {
- arg_info->assemble_args_func (insn);
-
- if (nios2_as_options.relax != relax_none
- && !nios2_as_options.noat
- && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_UBRANCH)
- output_ubranch (insn);
- else if (nios2_as_options.relax != relax_none
- && !nios2_as_options.noat
- && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_CBRANCH)
- output_cbranch (insn);
- else if (nios2_as_options.relax == relax_all
- && !nios2_as_options.noat
- && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_CALL
- && insn->insn_reloc
- && ((insn->insn_reloc->reloc_type
- == BFD_RELOC_NIOS2_CALL26)
- || (insn->insn_reloc->reloc_type
- == BFD_RELOC_NIOS2_CALL26_NOAT)))
- output_call (insn);
- else if (insn->insn_nios2_opcode->pinfo & NIOS2_INSN_ANDI)
- output_andi (insn);
- else if (insn->insn_nios2_opcode->pinfo & NIOS2_INSN_ORI)
- output_ori (insn);
- else if (insn->insn_nios2_opcode->pinfo & NIOS2_INSN_XORI)
- output_xori (insn);
- else if (insn->insn_nios2_opcode->pinfo & NIOS2_INSN_ADDI)
- output_addi (insn);
- else if (saved_pinfo == NIOS2_INSN_MACRO_MOVIA)
- output_movia (insn);
- else
- output_insn (insn);
- if (ps_insn)
- nios2_cleanup_pseudo_insn (insn, ps_insn);
- }
+ /* Assemble the parsed arguments into the instruction word. */
+ nios2_assemble_args (insn);
+
+ /* Handle relaxation and other transformations. */
+ if (nios2_as_options.relax != relax_none
+ && !nios2_as_options.noat
+ && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_UBRANCH)
+ output_ubranch (insn);
+ else if (nios2_as_options.relax != relax_none
+ && !nios2_as_options.noat
+ && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_CBRANCH)
+ output_cbranch (insn);
+ else if (nios2_as_options.relax == relax_all
+ && !nios2_as_options.noat
+ && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_CALL
+ && insn->insn_reloc
+ && ((insn->insn_reloc->reloc_type
+ == BFD_RELOC_NIOS2_CALL26)
+ || (insn->insn_reloc->reloc_type
+ == BFD_RELOC_NIOS2_CALL26_NOAT)))
+ output_call (insn);
+ else if (insn->insn_nios2_opcode->pinfo & NIOS2_INSN_ANDI)
+ output_andi (insn);
+ else if (insn->insn_nios2_opcode->pinfo & NIOS2_INSN_ORI)
+ output_ori (insn);
+ else if (insn->insn_nios2_opcode->pinfo & NIOS2_INSN_XORI)
+ output_xori (insn);
+ else if (insn->insn_nios2_opcode->pinfo & NIOS2_INSN_ADDI)
+ output_addi (insn);
+ else if (saved_pinfo == NIOS2_INSN_MACRO_MOVIA)
+ output_movia (insn);
else
- {
- /* The assembler is broken. */
- fprintf (stderr,
- _("internal error: %s is not a valid argument syntax\n"),
- insn->insn_nios2_opcode->args);
- /* Probably a memory allocation problem. Give up now. */
- as_fatal (_("Broken assembler. No assembly attempted."));
- }
+ output_insn (insn);
+ if (ps_insn)
+ nios2_cleanup_pseudo_insn (insn, ps_insn);
}
else
/* Unrecognised instruction - error. */
+2014-10-23 Sandra Loosemore <sandra@codesourcery.com>
+
+ * nios2-tdep.c (nios2_analyze_prologue): Use new instruction field
+ accessors and constants from nios2 opcodes update.
+ (nios2_get_next_pc): Likewise.
+
2014-10-19 Doug Evans <xdje42@gmail.com>
* gdbthread.h (set_running): Fix comment.
/* The following instructions can appear in the prologue. */
- if ((insn & 0x0001ffff) == 0x0001883a)
+ if ((insn & MASK_R1_ADD) == MATCH_R1_ADD)
{
/* ADD rc, ra, rb (also used for MOV) */
- int ra = GET_IW_A (insn);
- int rb = GET_IW_B (insn);
- int rc = GET_IW_C (insn);
+ int ra = GET_IW_R_A (insn);
+ int rb = GET_IW_R_B (insn);
+ int rc = GET_IW_R_C (insn);
if (rc == NIOS2_SP_REGNUM
&& rb == 0
prologue_insn = 1;
}
- else if ((insn & 0x0001ffff) == 0x0001983a)
+ else if ((insn & MASK_R1_SUB) == MATCH_R1_SUB)
{
/* SUB rc, ra, rb */
- int ra = GET_IW_A (insn);
- int rb = GET_IW_B (insn);
- int rc = GET_IW_C (insn);
+ int ra = GET_IW_R_A (insn);
+ int rb = GET_IW_R_B (insn);
+ int rc = GET_IW_R_C (insn);
if (rc != 0)
{
}
}
- else if ((insn & 0x0000003f) == 0x00000004)
+ else if ((insn & MASK_R1_ADDI) == MATCH_R1_ADDI)
{
/* ADDI rb, ra, immed (also used for MOVI) */
- short immed = GET_IW_IMM16 (insn);
- int ra = GET_IW_A (insn);
- int rb = GET_IW_B (insn);
+ short immed = GET_IW_I_IMM16 (insn);
+ int ra = GET_IW_I_A (insn);
+ int rb = GET_IW_I_B (insn);
/* The first stack adjustment is part of the prologue.
Any subsequent stack adjustments are either down to
prologue_insn = 1;
}
- else if ((insn & 0x0000003f) == 0x00000034)
+ else if ((insn & MASK_R1_ORHI) == MATCH_R1_ORHI)
{
/* ORHI rb, ra, immed (also used for MOVHI) */
- unsigned int immed = GET_IW_IMM16 (insn);
- int ra = GET_IW_A (insn);
- int rb = GET_IW_B (insn);
+ unsigned int immed = GET_IW_I_IMM16 (insn);
+ int ra = GET_IW_I_A (insn);
+ int rb = GET_IW_I_B (insn);
if (rb != 0)
{
}
}
- else if ((insn & IW_OP_MASK) == OP_STW
- || (insn & IW_OP_MASK) == OP_STWIO)
+ else if ((insn & MASK_R1_STW) == MATCH_R1_STW
+ || (insn & MASK_R1_STWIO) == MATCH_R1_STWIO)
{
/* STW rb, immediate(ra) */
- short immed16 = GET_IW_IMM16 (insn);
- int ra = GET_IW_A (insn);
- int rb = GET_IW_B (insn);
+ short immed16 = GET_IW_I_IMM16 (insn);
+ int ra = GET_IW_I_A (insn);
+ int rb = GET_IW_I_B (insn);
/* Are we storing the original value of a register?
For exception handlers the value of EA-4 (return
{
/* Save off callee saved registers. */
cache->reg_saved[orig].basereg = value[ra].reg;
- cache->reg_saved[orig].addr
- = value[ra].offset + GET_IW_IMM16 (insn);
+ cache->reg_saved[orig].addr = value[ra].offset + immed16;
}
prologue_insn = 1;
within_prologue = 0;
}
- else if ((insn & 0xffc1f83f) == 0x0001303a)
+ else if ((insn & MASK_R1_RDCTL) == MATCH_R1_RDCTL)
{
/* RDCTL rC, ctlN */
- int rc = GET_IW_C (insn);
- int n = GET_IW_CONTROL_REGNUM (insn);
+ int rc = GET_IW_R_C (insn);
+ int n = GET_IW_R_A (insn);
if (rc != 0)
{
prologue_insn = 1;
}
- else if ((insn & 0x0000003f) == 0
+ else if ((insn & MASK_R1_CALL) == MATCH_R1_CALL
&& value[8].reg == NIOS2_RA_REGNUM
&& value[8].offset == 0
&& value[NIOS2_SP_REGNUM].reg == NIOS2_SP_REGNUM
adjustment as terminating the prologue (see above). */
else
{
- switch (GET_IW_OP (insn))
+ switch (GET_IW_R1_OP (insn))
{
- case OP_BEQ:
- case OP_BGE:
- case OP_BGEU:
- case OP_BLT:
- case OP_BLTU:
- case OP_BNE:
- case OP_BR:
- case OP_CALL:
+ case R1_OP_BEQ:
+ case R1_OP_BGE:
+ case R1_OP_BGEU:
+ case R1_OP_BLT:
+ case R1_OP_BLTU:
+ case R1_OP_BNE:
+ case R1_OP_BR:
+ case R1_OP_CALL:
within_prologue = 0;
break;
- case OP_OPX:
- if (GET_IW_OPX (insn) == OPX_RET
- || GET_IW_OPX (insn) == OPX_ERET
- || GET_IW_OPX (insn) == OPX_BRET
- || GET_IW_OPX (insn) == OPX_CALLR
- || GET_IW_OPX (insn) == OPX_JMP)
+ case R1_OP_OPX:
+ if (GET_IW_R_OPX (insn) == R1_OPX_RET
+ || GET_IW_R_OPX (insn) == R1_OPX_ERET
+ || GET_IW_R_OPX (insn) == R1_OPX_BRET
+ || GET_IW_R_OPX (insn) == R1_OPX_CALLR
+ || GET_IW_R_OPX (insn) == R1_OPX_JMP)
within_prologue = 0;
break;
default:
inst = nios2_fetch_instruction (gdbarch, pc);
pc += NIOS2_OPCODE_SIZE;
- imm16 = (short) GET_IW_IMM16 (inst);
- ra = GET_IW_A (inst);
- rb = GET_IW_B (inst);
+ imm16 = (short) GET_IW_I_IMM16 (inst);
+ ra = GET_IW_I_A (inst);
+ rb = GET_IW_I_B (inst);
ras = get_frame_register_signed (frame, ra);
rbs = get_frame_register_signed (frame, rb);
rau = get_frame_register_unsigned (frame, ra);
rbu = get_frame_register_unsigned (frame, rb);
- switch (GET_IW_OP (inst))
+ switch (GET_IW_R1_OP (inst))
{
- case OP_BEQ:
+ case R1_OP_BEQ:
if (ras == rbs)
pc += imm16;
break;
- case OP_BGE:
+ case R1_OP_BGE:
if (ras >= rbs)
pc += imm16;
break;
- case OP_BGEU:
+ case R1_OP_BGEU:
if (rau >= rbu)
pc += imm16;
break;
- case OP_BLT:
+ case R1_OP_BLT:
if (ras < rbs)
pc += imm16;
break;
- case OP_BLTU:
+ case R1_OP_BLTU:
if (rau < rbu)
pc += imm16;
break;
- case OP_BNE:
+ case R1_OP_BNE:
if (ras != rbs)
pc += imm16;
break;
- case OP_BR:
+ case R1_OP_BR:
pc += imm16;
break;
- case OP_JMPI:
- case OP_CALL:
- pc = (pc & 0xf0000000) | (GET_IW_IMM26 (inst) << 2);
+ case R1_OP_JMPI:
+ case R1_OP_CALL:
+ pc = (pc & 0xf0000000) | (GET_IW_J_IMM26 (inst) << 2);
break;
- case OP_OPX:
- switch (GET_IW_OPX (inst))
+ case R1_OP_OPX:
+ switch (GET_IW_R_OPX (inst))
{
- case OPX_JMP:
- case OPX_CALLR:
- case OPX_RET:
+ case R1_OPX_JMP:
+ case R1_OPX_CALLR:
+ case R1_OPX_RET:
pc = ras;
break;
- case OPX_TRAP:
+ case R1_OPX_TRAP:
if (tdep->syscall_next_pc != NULL)
return tdep->syscall_next_pc (frame);
+2014-10-23 Sandra Loosemore <sandra@codesourcery.com>
+
+ * nios2.h (enum iw_format_type): New.
+ (struct nios2_opcode): Update comments. Add size and format fields.
+ (NIOS2_INSN_OPTARG): New.
+ (REG_NORMAL, REG_CONTROL, REG_COPROCESSOR): New.
+ (struct nios2_reg): Add regtype field.
+ (GET_INSN_FIELD, SET_INSN_FIELD): Delete.
+ (IW_A_LSB, IW_A_MSB, IW_A_SZ, IW_A_MASK): Delete.
+ (IW_B_LSB, IW_B_MSB, IW_B_SZ, IW_B_MASK): Delete.
+ (IW_C_LSB, IW_C_MSB, IW_C_SZ, IW_C_MASK): Delete.
+ (IW_IMM16_LSB, IW_IMM16_MSB, IW_IMM16_SZ, IW_IMM16_MASK): Delete.
+ (IW_IMM26_LSB, IW_IMM26_MSB, IW_IMM26_SZ, IW_IMM26_MASK): Delete.
+ (IW_OP_LSB, IW_OP_MSB, IW_OP_SZ, IW_OP_MASK): Delete.
+ (IW_OPX_LSB, IW_OPX_MSB, IW_OPX_SZ, IW_OPX_MASK): Delete.
+ (IW_SHIFT_IMM5_LSB, IW_SHIFT_IMM5_MSB): Delete.
+ (IW_SHIFT_IMM5_SZ, IW_SHIFT_IMM5_MASK): Delete.
+ (IW_CONTROL_REGNUM_LSB, IW_CONTROL_REGNUM_MSB): Delete.
+ (IW_CONTROL_REGNUM_SZ, IW_CONTROL_REGNUM_MASK): Delete.
+ (OP_MASK_OP, OP_SH_OP): Delete.
+ (OP_MASK_IOP, OP_SH_IOP): Delete.
+ (OP_MASK_IRD, OP_SH_IRD): Delete.
+ (OP_MASK_IRT, OP_SH_IRT): Delete.
+ (OP_MASK_IRS, OP_SH_IRS): Delete.
+ (OP_MASK_ROP, OP_SH_ROP): Delete.
+ (OP_MASK_RRD, OP_SH_RRD): Delete.
+ (OP_MASK_RRT, OP_SH_RRT): Delete.
+ (OP_MASK_RRS, OP_SH_RRS): Delete.
+ (OP_MASK_JOP, OP_SH_JOP): Delete.
+ (OP_MASK_IMM26, OP_SH_IMM26): Delete.
+ (OP_MASK_RCTL, OP_SH_RCTL): Delete.
+ (OP_MASK_IMM5, OP_SH_IMM5): Delete.
+ (OP_MASK_CACHE_OPX, OP_SH_CACHE_OPX): Delete.
+ (OP_MASK_CACHE_RRS, OP_SH_CACHE_RRS): Delete.
+ (OP_MASK_CUSTOM_A, OP_SH_CUSTOM_A): Delete.
+ (OP_MASK_CUSTOM_B, OP_SH_CUSTOM_B): Delete.
+ (OP_MASK_CUSTOM_C, OP_SH_CUSTOM_C): Delete.
+ (OP_MASK_CUSTOM_N, OP_SH_CUSTOM_N): Delete.
+ (OP_<insn>, OPX_<insn>, OP_MATCH_<insn>, OPX_MATCH_<insn>): Delete.
+ (OP_MASK_<insn>, OP_MASK): Delete.
+ (GET_IW_A, GET_IW_B, GET_IW_C, GET_IW_CONTROL_REGNUM): Delete.
+ (GET_IW_IMM16, GET_IW_IMM26, GET_IW_OP, GET_IW_OPX): Delete.
+ Include nios2r1.h to define new instruction opcode constants
+ and accessors.
+ (nios2_builtin_opcodes): Rename to nios2_r1_opcodes.
+ (bfd_nios2_num_builtin_opcodes): Rename to nios2_num_r1_opcodes.
+ (bfd_nios2_num_opcodes): Rename to nios2_num_opcodes.
+ (NUMOPCODES, NUMREGISTERS): Delete.
+ * nios2r1.h: New file.
+
2014-10-17 Jose E. Marchesi <jose.marchesi@oracle.com>
* sparc.h (HWCAP2_VIS3B): Documentation improved.
* access various opcode fields.
****************************************************************************/
+/* Instruction encoding formats. */
+enum iw_format_type {
+ /* R1 formats */
+ iw_i_type,
+ iw_r_type,
+ iw_j_type,
+ iw_custom_type
+};
+
/* Identify different overflow situations for error messages. */
enum overflow_type
{
u - a 16-bit unsigned immediate
o - a 16-bit signed program counter relative offset
j - a 5-bit unsigned immediate
- b - a 5-bit break instruction constant
l - a 8-bit custom instruction constant
m - a 26-bit unsigned immediate
Literal ',', '(', and ')' characters may also appear in the args as
delimiters.
+ Note that the args describe the semantics and assembly-language syntax
+ of the operands, not their encoding into the instruction word.
+
The pinfo field is INSN_MACRO for a macro. Otherwise, it is a collection
of bits describing the instruction, notably any relevant hazard
information.
the expected opcode. */
unsigned long num_args; /* The number of arguments the instruction
takes. */
+ unsigned size; /* Size in bytes of the instruction. */
+ enum iw_format_type format; /* Instruction format. */
unsigned long match; /* The basic opcode for the instruction. */
unsigned long mask; /* Mask for the opcode field of the
instruction. */
#define NIOS2_INSN_ORI 0x00000200
#define NIOS2_INSN_XORI 0x00000400
+#define NIOS2_INSN_OPTARG 0x00000800
+
+/* Register attributes. */
+#define REG_NORMAL (1<<0) /* Normal registers. */
+#define REG_CONTROL (1<<1) /* Control registers. */
+#define REG_COPROCESSOR (1<<2) /* For custom instructions. */
-/* Associates a register name ($6) with a 5-bit index (eg 6). */
struct nios2_reg
{
const char *name;
const int index;
+ unsigned long regtype;
};
+/* Pull in the instruction field accessors, opcodes, and masks. */
+#include "nios2r1.h"
-/* These are bit masks and shift counts for accessing the various
- fields of a Nios II instruction. */
-
-/* Macros for getting and setting an instruction field. */
-#define GET_INSN_FIELD(X, i) \
- (((i) & OP_MASK_##X) >> OP_SH_##X)
-#define SET_INSN_FIELD(X, i, j) \
- ((i) = (((i) & ~OP_MASK_##X) | (((j) << OP_SH_##X) & OP_MASK_##X)))
-
-/* Instruction field definitions. */
-#define IW_A_LSB 27
-#define IW_A_MSB 31
-#define IW_A_SZ 5
-#define IW_A_MASK 0x1f
-
-#define IW_B_LSB 22
-#define IW_B_MSB 26
-#define IW_B_SZ 5
-#define IW_B_MASK 0x1f
-
-#define IW_C_LSB 17
-#define IW_C_MSB 21
-#define IW_C_SZ 5
-#define IW_C_MASK 0x1f
-
-#define IW_IMM16_LSB 6
-#define IW_IMM16_MSB 21
-#define IW_IMM16_SZ 16
-#define IW_IMM16_MASK 0xffff
-
-#define IW_IMM26_LSB 6
-#define IW_IMM26_MSB 31
-#define IW_IMM26_SZ 26
-#define IW_IMM26_MASK 0x3ffffff
-
-#define IW_OP_LSB 0
-#define IW_OP_MSB 5
-#define IW_OP_SZ 6
-#define IW_OP_MASK 0x3f
-
-#define IW_OPX_LSB 11
-#define IW_OPX_MSB 16
-#define IW_OPX_SZ 6
-#define IW_OPX_MASK 0x3f
-
-#define IW_SHIFT_IMM5_LSB 6
-#define IW_SHIFT_IMM5_MSB 10
-#define IW_SHIFT_IMM5_SZ 5
-#define IW_SHIFT_IMM5_MASK 0x1f
-
-#define IW_CONTROL_REGNUM_LSB 6
-#define IW_CONTROL_REGNUM_MSB 9
-#define IW_CONTROL_REGNUM_SZ 4
-#define IW_CONTROL_REGNUM_MASK 0xf
-
-/* Operator mask and shift. */
-#define OP_MASK_OP (IW_OP_MASK << IW_OP_LSB)
-#define OP_SH_OP IW_OP_LSB
-
-/* Masks and shifts for I-type instructions. */
-#define OP_MASK_IOP (IW_OP_MASK << IW_OP_LSB)
-#define OP_SH_IOP IW_OP_LSB
-
-#define OP_MASK_IMM16 (IW_IMM16_MASK << IW_IMM16_LSB)
-#define OP_SH_IMM16 IW_IMM16_LSB
-
-#define OP_MASK_IRD (IW_B_MASK << IW_B_LSB)
-#define OP_SH_IRD IW_B_LSB /* The same as T for I-type. */
-
-#define OP_MASK_IRT (IW_B_MASK << IW_B_LSB)
-#define OP_SH_IRT IW_B_LSB
-
-#define OP_MASK_IRS (IW_A_MASK << IW_A_LSB)
-#define OP_SH_IRS IW_A_LSB
-
-/* Masks and shifts for R-type instructions. */
-#define OP_MASK_ROP (IW_OP_MASK << IW_OP_LSB)
-#define OP_SH_ROP IW_OP_LSB
-
-#define OP_MASK_ROPX (IW_OPX_MASK << IW_OPX_LSB)
-#define OP_SH_ROPX IW_OPX_LSB
-
-#define OP_MASK_RRD (IW_C_MASK << IW_C_LSB)
-#define OP_SH_RRD IW_C_LSB
-
-#define OP_MASK_RRT (IW_B_MASK << IW_B_LSB)
-#define OP_SH_RRT IW_B_LSB
-
-#define OP_MASK_RRS (IW_A_MASK << IW_A_LSB)
-#define OP_SH_RRS IW_A_LSB
-
-/* Masks and shifts for J-type instructions. */
-#define OP_MASK_JOP (IW_OP_MASK << IW_OP_LSB)
-#define OP_SH_JOP IW_OP_LSB
-
-#define OP_MASK_IMM26 (IW_IMM26_MASK << IW_IMM26_LSB)
-#define OP_SH_IMM26 IW_IMM26_LSB
-
-/* Masks and shifts for CTL instructions. */
-#define OP_MASK_RCTL 0x000007c0
-#define OP_SH_RCTL 6
-
-/* Break instruction imm5 field. */
-#define OP_MASK_TRAP_IMM5 0x000007c0
-#define OP_SH_TRAP_IMM5 6
-
-/* Instruction imm5 field. */
-#define OP_MASK_IMM5 (IW_SHIFT_IMM5_MASK << IW_SHIFT_IMM5_LSB)
-#define OP_SH_IMM5 IW_SHIFT_IMM5_LSB
-
-/* Cache operation fields (type j,i(s)). */
-#define OP_MASK_CACHE_OPX (IW_B_MASK << IW_B_LSB)
-#define OP_SH_CACHE_OPX IW_B_LSB
-#define OP_MASK_CACHE_RRS (IW_A_MASK << IW_A_LSB)
-#define OP_SH_CACHE_RRS IW_A_LSB
-
-/* Custom instruction masks. */
-#define OP_MASK_CUSTOM_A 0x00010000
-#define OP_SH_CUSTOM_A 16
-
-#define OP_MASK_CUSTOM_B 0x00008000
-#define OP_SH_CUSTOM_B 15
-
-#define OP_MASK_CUSTOM_C 0x00004000
-#define OP_SH_CUSTOM_C 14
-
-#define OP_MASK_CUSTOM_N 0x00003fc0
-#define OP_SH_CUSTOM_N 6
-#define OP_MAX_CUSTOM_N 255
-
-/* OP instruction values. */
-#define OP_ADDI 4
-#define OP_ANDHI 44
-#define OP_ANDI 12
-#define OP_BEQ 38
-#define OP_BGE 14
-#define OP_BGEU 46
-#define OP_BLT 22
-#define OP_BLTU 54
-#define OP_BNE 30
-#define OP_BR 6
-#define OP_CALL 0
-#define OP_CMPEQI 32
-#define OP_CMPGEI 8
-#define OP_CMPGEUI 40
-#define OP_CMPLTI 16
-#define OP_CMPLTUI 48
-#define OP_CMPNEI 24
-#define OP_CUSTOM 50
-#define OP_FLUSHD 59
-#define OP_FLUSHDA 27
-#define OP_INITD 51
-#define OP_INITDA 19
-#define OP_JMPI 1
-#define OP_LDB 7
-#define OP_LDBIO 39
-#define OP_LDBU 3
-#define OP_LDBUIO 35
-#define OP_LDH 15
-#define OP_LDHIO 47
-#define OP_LDHU 11
-#define OP_LDHUIO 43
-#define OP_LDL 31
-#define OP_LDW 23
-#define OP_LDWIO 55
-#define OP_MULI 36
-#define OP_OPX 58
-#define OP_ORHI 52
-#define OP_ORI 20
-#define OP_RDPRS 56
-#define OP_STB 5
-#define OP_STBIO 37
-#define OP_STC 29
-#define OP_STH 13
-#define OP_STHIO 45
-#define OP_STW 21
-#define OP_STWIO 53
-#define OP_XORHI 60
-#define OP_XORI 28
-
-/* OPX instruction values. */
-#define OPX_ADD 49
-#define OPX_AND 14
-#define OPX_BREAK 52
-#define OPX_BRET 9
-#define OPX_CALLR 29
-#define OPX_CMPEQ 32
-#define OPX_CMPGE 8
-#define OPX_CMPGEU 40
-#define OPX_CMPLT 16
-#define OPX_CMPLTU 48
-#define OPX_CMPNE 24
-#define OPX_CRST 62
-#define OPX_DIV 37
-#define OPX_DIVU 36
-#define OPX_ERET 1
-#define OPX_FLUSHI 12
-#define OPX_FLUSHP 4
-#define OPX_HBREAK 53
-#define OPX_INITI 41
-#define OPX_INTR 61
-#define OPX_JMP 13
-#define OPX_MUL 39
-#define OPX_MULXSS 31
-#define OPX_MULXSU 23
-#define OPX_MULXUU 7
-#define OPX_NEXTPC 28
-#define OPX_NOR 6
-#define OPX_OR 22
-#define OPX_RDCTL 38
-#define OPX_RET 5
-#define OPX_ROL 3
-#define OPX_ROLI 2
-#define OPX_ROR 11
-#define OPX_SLL 19
-#define OPX_SLLI 18
-#define OPX_SRA 59
-#define OPX_SRAI 58
-#define OPX_SRL 27
-#define OPX_SRLI 26
-#define OPX_SUB 57
-#define OPX_SYNC 54
-#define OPX_TRAP 45
-#define OPX_WRCTL 46
-#define OPX_WRPRS 20
-#define OPX_XOR 30
-
-/* The following macros define the opcode matches for each
- instruction code & OP_MASK_INST == OP_MATCH_INST. */
-
-/* OP instruction matches. */
-#define OP_MATCH_ADDI OP_ADDI
-#define OP_MATCH_ANDHI OP_ANDHI
-#define OP_MATCH_ANDI OP_ANDI
-#define OP_MATCH_BEQ OP_BEQ
-#define OP_MATCH_BGE OP_BGE
-#define OP_MATCH_BGEU OP_BGEU
-#define OP_MATCH_BLT OP_BLT
-#define OP_MATCH_BLTU OP_BLTU
-#define OP_MATCH_BNE OP_BNE
-#define OP_MATCH_BR OP_BR
-#define OP_MATCH_FLUSHD OP_FLUSHD
-#define OP_MATCH_FLUSHDA OP_FLUSHDA
-#define OP_MATCH_INITD OP_INITD
-#define OP_MATCH_INITDA OP_INITDA
-#define OP_MATCH_CALL OP_CALL
-#define OP_MATCH_CMPEQI OP_CMPEQI
-#define OP_MATCH_CMPGEI OP_CMPGEI
-#define OP_MATCH_CMPGEUI OP_CMPGEUI
-#define OP_MATCH_CMPLTI OP_CMPLTI
-#define OP_MATCH_CMPLTUI OP_CMPLTUI
-#define OP_MATCH_CMPNEI OP_CMPNEI
-#define OP_MATCH_JMPI OP_JMPI
-#define OP_MATCH_LDB OP_LDB
-#define OP_MATCH_LDBIO OP_LDBIO
-#define OP_MATCH_LDBU OP_LDBU
-#define OP_MATCH_LDBUIO OP_LDBUIO
-#define OP_MATCH_LDH OP_LDH
-#define OP_MATCH_LDHIO OP_LDHIO
-#define OP_MATCH_LDHU OP_LDHU
-#define OP_MATCH_LDHUIO OP_LDHUIO
-#define OP_MATCH_LDL OP_LDL
-#define OP_MATCH_LDW OP_LDW
-#define OP_MATCH_LDWIO OP_LDWIO
-#define OP_MATCH_MULI OP_MULI
-#define OP_MATCH_OPX OP_OPX
-#define OP_MATCH_ORHI OP_ORHI
-#define OP_MATCH_ORI OP_ORI
-#define OP_MATCH_RDPRS OP_RDPRS
-#define OP_MATCH_STB OP_STB
-#define OP_MATCH_STBIO OP_STBIO
-#define OP_MATCH_STC OP_STC
-#define OP_MATCH_STH OP_STH
-#define OP_MATCH_STHIO OP_STHIO
-#define OP_MATCH_STW OP_STW
-#define OP_MATCH_STWIO OP_STWIO
-#define OP_MATCH_CUSTOM OP_CUSTOM
-#define OP_MATCH_XORHI OP_XORHI
-#define OP_MATCH_XORI OP_XORI
-#define OP_MATCH_OPX OP_OPX
-
-/* OPX instruction values. */
-#define OPX_MATCH(code) ((code << IW_OPX_LSB) | OP_OPX)
-
-#define OP_MATCH_ADD OPX_MATCH (OPX_ADD)
-#define OP_MATCH_AND OPX_MATCH (OPX_AND)
-#define OP_MATCH_BREAK ((0x1e << 17) | OPX_MATCH (OPX_BREAK))
-#define OP_MATCH_BRET (0xf0000000 | OPX_MATCH (OPX_BRET))
-#define OP_MATCH_CALLR ((0x1f << 17) | OPX_MATCH (OPX_CALLR))
-#define OP_MATCH_CMPEQ OPX_MATCH (OPX_CMPEQ)
-#define OP_MATCH_CMPGE OPX_MATCH (OPX_CMPGE)
-#define OP_MATCH_CMPGEU OPX_MATCH (OPX_CMPGEU)
-#define OP_MATCH_CMPLT OPX_MATCH (OPX_CMPLT)
-#define OP_MATCH_CMPLTU OPX_MATCH (OPX_CMPLTU)
-#define OP_MATCH_CMPNE OPX_MATCH (OPX_CMPNE)
-#define OP_MATCH_DIV OPX_MATCH (OPX_DIV)
-#define OP_MATCH_DIVU OPX_MATCH (OPX_DIVU)
-#define OP_MATCH_JMP OPX_MATCH (OPX_JMP)
-#define OP_MATCH_MUL OPX_MATCH (OPX_MUL)
-#define OP_MATCH_MULXSS OPX_MATCH (OPX_MULXSS)
-#define OP_MATCH_MULXSU OPX_MATCH (OPX_MULXSU)
-#define OP_MATCH_MULXUU OPX_MATCH (OPX_MULXUU)
-#define OP_MATCH_NEXTPC OPX_MATCH (OPX_NEXTPC)
-#define OP_MATCH_NOR OPX_MATCH (OPX_NOR)
-#define OP_MATCH_OR OPX_MATCH (OPX_OR)
-#define OP_MATCH_RDCTL OPX_MATCH (OPX_RDCTL)
-#define OP_MATCH_RET (0xf8000000 | OPX_MATCH (OPX_RET))
-#define OP_MATCH_ROL OPX_MATCH (OPX_ROL)
-#define OP_MATCH_ROLI OPX_MATCH (OPX_ROLI)
-#define OP_MATCH_ROR OPX_MATCH (OPX_ROR)
-#define OP_MATCH_SLL OPX_MATCH (OPX_SLL)
-#define OP_MATCH_SLLI OPX_MATCH (OPX_SLLI)
-#define OP_MATCH_SRA OPX_MATCH (OPX_SRA)
-#define OP_MATCH_SRAI OPX_MATCH (OPX_SRAI)
-#define OP_MATCH_SRL OPX_MATCH (OPX_SRL)
-#define OP_MATCH_SRLI OPX_MATCH (OPX_SRLI)
-#define OP_MATCH_SUB OPX_MATCH (OPX_SUB)
-#define OP_MATCH_SYNC OPX_MATCH (OPX_SYNC)
-#define OP_MATCH_TRAP ((0x1d << 17) | OPX_MATCH (OPX_TRAP))
-#define OP_MATCH_ERET (0xef800000 | OPX_MATCH (OPX_ERET))
-#define OP_MATCH_WRCTL OPX_MATCH (OPX_WRCTL)
-#define OP_MATCH_WRPRS OPX_MATCH (OPX_WRPRS)
-#define OP_MATCH_XOR OPX_MATCH (OPX_XOR)
-#define OP_MATCH_FLUSHI OPX_MATCH (OPX_FLUSHI)
-#define OP_MATCH_FLUSHP OPX_MATCH (OPX_FLUSHP)
-#define OP_MATCH_INITI OPX_MATCH (OPX_INITI)
-
-/* Some unusual op masks. */
-#define OP_MASK_BREAK ((OP_MASK_RRS | OP_MASK_RRT | OP_MASK_RRD \
- | OP_MASK_ROPX | OP_MASK_OP) \
- & 0xfffff03f)
-#define OP_MASK_CALLR ((OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX \
- | OP_MASK_OP))
-#define OP_MASK_JMP ((OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX \
- | OP_MASK_OP))
-#define OP_MASK_SYNC ((OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX \
- | OP_MASK_OP))
-#define OP_MASK_TRAP ((OP_MASK_RRS | OP_MASK_RRT | OP_MASK_RRD \
- | OP_MASK_ROPX | OP_MASK_OP) \
- & 0xfffff83f)
-#define OP_MASK_WRCTL ((OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX \
- | OP_MASK_OP)) /*& 0xfffff83f */
-#define OP_MASK_NEXTPC ((OP_MASK_RRS | OP_MASK_RRT | OP_MASK_ROPX \
- | OP_MASK_OP))
-#define OP_MASK_FLUSHI ((OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX \
- | OP_MASK_OP))
-#define OP_MASK_INITI ((OP_MASK_RRT | OP_MASK_RRD | OP_MASK_ROPX \
- | OP_MASK_OP))
-
-#define OP_MASK_ROLI ((OP_MASK_RRT | OP_MASK_ROPX | OP_MASK_OP))
-#define OP_MASK_SLLI ((OP_MASK_RRT | OP_MASK_ROPX | OP_MASK_OP))
-#define OP_MASK_SRAI ((OP_MASK_RRT | OP_MASK_ROPX | OP_MASK_OP))
-#define OP_MASK_SRLI ((OP_MASK_RRT | OP_MASK_ROPX | OP_MASK_OP))
-#define OP_MASK_RDCTL ((OP_MASK_RRS | OP_MASK_RRT | OP_MASK_ROPX \
- | OP_MASK_OP)) /*& 0xfffff83f */
-
-#ifndef OP_MASK
-#define OP_MASK 0xffffffff
-#endif
-
-/* These convenience macros to extract instruction fields are used by GDB. */
-#define GET_IW_A(Iw) \
- (((Iw) >> IW_A_LSB) & IW_A_MASK)
-#define GET_IW_B(Iw) \
- (((Iw) >> IW_B_LSB) & IW_B_MASK)
-#define GET_IW_C(Iw) \
- (((Iw) >> IW_C_LSB) & IW_C_MASK)
-#define GET_IW_CONTROL_REGNUM(Iw) \
- (((Iw) >> IW_CONTROL_REGNUM_LSB) & IW_CONTROL_REGNUM_MASK)
-#define GET_IW_IMM16(Iw) \
- (((Iw) >> IW_IMM16_LSB) & IW_IMM16_MASK)
-#define GET_IW_IMM26(Iw) \
- (((Iw) >> IW_IMM26_LSB) & IW_IMM26_MASK)
-#define GET_IW_OP(Iw) \
- (((Iw) >> IW_OP_LSB) & IW_OP_MASK)
-#define GET_IW_OPX(Iw) \
- (((Iw) >> IW_OPX_LSB) & IW_OPX_MASK)
-
-/* These are the data structures we use to hold the instruction information. */
-extern const struct nios2_opcode nios2_builtin_opcodes[];
-extern const int bfd_nios2_num_builtin_opcodes;
+/* These are the data structures used to hold the instruction information. */
+extern const struct nios2_opcode nios2_r1_opcodes[];
+extern const int nios2_num_r1_opcodes;
extern struct nios2_opcode *nios2_opcodes;
-extern int bfd_nios2_num_opcodes;
+extern int nios2_num_opcodes;
/* These are the data structures used to hold the register information. */
extern const struct nios2_reg nios2_builtin_regs[];
extern const int nios2_num_builtin_regs;
extern int nios2_num_regs;
-/* Machine-independent macro for number of opcodes. */
-#define NUMOPCODES bfd_nios2_num_opcodes
-#define NUMREGISTERS nios2_num_regs;
-
/* This is made extern so that the assembler can use it to find out
what instruction caused an error. */
extern const struct nios2_opcode *nios2_find_opcode_hash (unsigned long);
--- /dev/null
+/* Nios II R1 opcode list for GAS, the GNU assembler.
+ Copyright (C) 2013-2014 Free Software Foundation, Inc.
+ Contributed by Mentor Graphics, Inc.
+
+ This file is part of GAS, the GNU Assembler, and GDB, the GNU disassembler.
+
+ GAS/GDB is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GAS/GDB is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS or GDB; see the file COPYING3. If not, write to
+ the Free Software Foundation, 51 Franklin Street - Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+#ifndef _NIOS2R1_H_
+#define _NIOS2R1_H_
+
+/* R1 fields. */
+#define IW_R1_OP_LSB 0
+#define IW_R1_OP_SIZE 6
+#define IW_R1_OP_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_R1_OP_SIZE))
+#define IW_R1_OP_SHIFTED_MASK (IW_R1_OP_UNSHIFTED_MASK << IW_R1_OP_LSB)
+#define GET_IW_R1_OP(W) (((W) >> IW_R1_OP_LSB) & IW_R1_OP_UNSHIFTED_MASK)
+#define SET_IW_R1_OP(V) (((V) & IW_R1_OP_UNSHIFTED_MASK) << IW_R1_OP_LSB)
+
+#define IW_I_A_LSB 27
+#define IW_I_A_SIZE 5
+#define IW_I_A_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_I_A_SIZE))
+#define IW_I_A_SHIFTED_MASK (IW_I_A_UNSHIFTED_MASK << IW_I_A_LSB)
+#define GET_IW_I_A(W) (((W) >> IW_I_A_LSB) & IW_I_A_UNSHIFTED_MASK)
+#define SET_IW_I_A(V) (((V) & IW_I_A_UNSHIFTED_MASK) << IW_I_A_LSB)
+
+#define IW_I_B_LSB 22
+#define IW_I_B_SIZE 5
+#define IW_I_B_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_I_B_SIZE))
+#define IW_I_B_SHIFTED_MASK (IW_I_B_UNSHIFTED_MASK << IW_I_B_LSB)
+#define GET_IW_I_B(W) (((W) >> IW_I_B_LSB) & IW_I_B_UNSHIFTED_MASK)
+#define SET_IW_I_B(V) (((V) & IW_I_B_UNSHIFTED_MASK) << IW_I_B_LSB)
+
+#define IW_I_IMM16_LSB 6
+#define IW_I_IMM16_SIZE 16
+#define IW_I_IMM16_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_I_IMM16_SIZE))
+#define IW_I_IMM16_SHIFTED_MASK (IW_I_IMM16_UNSHIFTED_MASK << IW_I_IMM16_LSB)
+#define GET_IW_I_IMM16(W) (((W) >> IW_I_IMM16_LSB) & IW_I_IMM16_UNSHIFTED_MASK)
+#define SET_IW_I_IMM16(V) (((V) & IW_I_IMM16_UNSHIFTED_MASK) << IW_I_IMM16_LSB)
+
+#define IW_R_A_LSB 27
+#define IW_R_A_SIZE 5
+#define IW_R_A_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_R_A_SIZE))
+#define IW_R_A_SHIFTED_MASK (IW_R_A_UNSHIFTED_MASK << IW_R_A_LSB)
+#define GET_IW_R_A(W) (((W) >> IW_R_A_LSB) & IW_R_A_UNSHIFTED_MASK)
+#define SET_IW_R_A(V) (((V) & IW_R_A_UNSHIFTED_MASK) << IW_R_A_LSB)
+
+#define IW_R_B_LSB 22
+#define IW_R_B_SIZE 5
+#define IW_R_B_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_R_B_SIZE))
+#define IW_R_B_SHIFTED_MASK (IW_R_B_UNSHIFTED_MASK << IW_R_B_LSB)
+#define GET_IW_R_B(W) (((W) >> IW_R_B_LSB) & IW_R_B_UNSHIFTED_MASK)
+#define SET_IW_R_B(V) (((V) & IW_R_B_UNSHIFTED_MASK) << IW_R_B_LSB)
+
+#define IW_R_C_LSB 17
+#define IW_R_C_SIZE 5
+#define IW_R_C_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_R_C_SIZE))
+#define IW_R_C_SHIFTED_MASK (IW_R_C_UNSHIFTED_MASK << IW_R_C_LSB)
+#define GET_IW_R_C(W) (((W) >> IW_R_C_LSB) & IW_R_C_UNSHIFTED_MASK)
+#define SET_IW_R_C(V) (((V) & IW_R_C_UNSHIFTED_MASK) << IW_R_C_LSB)
+
+#define IW_R_OPX_LSB 11
+#define IW_R_OPX_SIZE 6
+#define IW_R_OPX_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_R_OPX_SIZE))
+#define IW_R_OPX_SHIFTED_MASK (IW_R_OPX_UNSHIFTED_MASK << IW_R_OPX_LSB)
+#define GET_IW_R_OPX(W) (((W) >> IW_R_OPX_LSB) & IW_R_OPX_UNSHIFTED_MASK)
+#define SET_IW_R_OPX(V) (((V) & IW_R_OPX_UNSHIFTED_MASK) << IW_R_OPX_LSB)
+
+#define IW_R_IMM5_LSB 6
+#define IW_R_IMM5_SIZE 5
+#define IW_R_IMM5_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_R_IMM5_SIZE))
+#define IW_R_IMM5_SHIFTED_MASK (IW_R_IMM5_UNSHIFTED_MASK << IW_R_IMM5_LSB)
+#define GET_IW_R_IMM5(W) (((W) >> IW_R_IMM5_LSB) & IW_R_IMM5_UNSHIFTED_MASK)
+#define SET_IW_R_IMM5(V) (((V) & IW_R_IMM5_UNSHIFTED_MASK) << IW_R_IMM5_LSB)
+
+#define IW_J_IMM26_LSB 6
+#define IW_J_IMM26_SIZE 26
+#define IW_J_IMM26_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_J_IMM26_SIZE))
+#define IW_J_IMM26_SHIFTED_MASK (IW_J_IMM26_UNSHIFTED_MASK << IW_J_IMM26_LSB)
+#define GET_IW_J_IMM26(W) (((W) >> IW_J_IMM26_LSB) & IW_J_IMM26_UNSHIFTED_MASK)
+#define SET_IW_J_IMM26(V) (((V) & IW_J_IMM26_UNSHIFTED_MASK) << IW_J_IMM26_LSB)
+
+#define IW_CUSTOM_A_LSB 27
+#define IW_CUSTOM_A_SIZE 5
+#define IW_CUSTOM_A_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_CUSTOM_A_SIZE))
+#define IW_CUSTOM_A_SHIFTED_MASK (IW_CUSTOM_A_UNSHIFTED_MASK << IW_CUSTOM_A_LSB)
+#define GET_IW_CUSTOM_A(W) (((W) >> IW_CUSTOM_A_LSB) & IW_CUSTOM_A_UNSHIFTED_MASK)
+#define SET_IW_CUSTOM_A(V) (((V) & IW_CUSTOM_A_UNSHIFTED_MASK) << IW_CUSTOM_A_LSB)
+
+#define IW_CUSTOM_B_LSB 22
+#define IW_CUSTOM_B_SIZE 5
+#define IW_CUSTOM_B_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_CUSTOM_B_SIZE))
+#define IW_CUSTOM_B_SHIFTED_MASK (IW_CUSTOM_B_UNSHIFTED_MASK << IW_CUSTOM_B_LSB)
+#define GET_IW_CUSTOM_B(W) (((W) >> IW_CUSTOM_B_LSB) & IW_CUSTOM_B_UNSHIFTED_MASK)
+#define SET_IW_CUSTOM_B(V) (((V) & IW_CUSTOM_B_UNSHIFTED_MASK) << IW_CUSTOM_B_LSB)
+
+#define IW_CUSTOM_C_LSB 17
+#define IW_CUSTOM_C_SIZE 5
+#define IW_CUSTOM_C_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_CUSTOM_C_SIZE))
+#define IW_CUSTOM_C_SHIFTED_MASK (IW_CUSTOM_C_UNSHIFTED_MASK << IW_CUSTOM_C_LSB)
+#define GET_IW_CUSTOM_C(W) (((W) >> IW_CUSTOM_C_LSB) & IW_CUSTOM_C_UNSHIFTED_MASK)
+#define SET_IW_CUSTOM_C(V) (((V) & IW_CUSTOM_C_UNSHIFTED_MASK) << IW_CUSTOM_C_LSB)
+
+#define IW_CUSTOM_READA_LSB 16
+#define IW_CUSTOM_READA_SIZE 1
+#define IW_CUSTOM_READA_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_CUSTOM_READA_SIZE))
+#define IW_CUSTOM_READA_SHIFTED_MASK (IW_CUSTOM_READA_UNSHIFTED_MASK << IW_CUSTOM_READA_LSB)
+#define GET_IW_CUSTOM_READA(W) (((W) >> IW_CUSTOM_READA_LSB) & IW_CUSTOM_READA_UNSHIFTED_MASK)
+#define SET_IW_CUSTOM_READA(V) (((V) & IW_CUSTOM_READA_UNSHIFTED_MASK) << IW_CUSTOM_READA_LSB)
+
+#define IW_CUSTOM_READB_LSB 15
+#define IW_CUSTOM_READB_SIZE 1
+#define IW_CUSTOM_READB_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_CUSTOM_READB_SIZE))
+#define IW_CUSTOM_READB_SHIFTED_MASK (IW_CUSTOM_READB_UNSHIFTED_MASK << IW_CUSTOM_READB_LSB)
+#define GET_IW_CUSTOM_READB(W) (((W) >> IW_CUSTOM_READB_LSB) & IW_CUSTOM_READB_UNSHIFTED_MASK)
+#define SET_IW_CUSTOM_READB(V) (((V) & IW_CUSTOM_READB_UNSHIFTED_MASK) << IW_CUSTOM_READB_LSB)
+
+#define IW_CUSTOM_READC_LSB 14
+#define IW_CUSTOM_READC_SIZE 1
+#define IW_CUSTOM_READC_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_CUSTOM_READC_SIZE))
+#define IW_CUSTOM_READC_SHIFTED_MASK (IW_CUSTOM_READC_UNSHIFTED_MASK << IW_CUSTOM_READC_LSB)
+#define GET_IW_CUSTOM_READC(W) (((W) >> IW_CUSTOM_READC_LSB) & IW_CUSTOM_READC_UNSHIFTED_MASK)
+#define SET_IW_CUSTOM_READC(V) (((V) & IW_CUSTOM_READC_UNSHIFTED_MASK) << IW_CUSTOM_READC_LSB)
+
+#define IW_CUSTOM_N_LSB 6
+#define IW_CUSTOM_N_SIZE 8
+#define IW_CUSTOM_N_UNSHIFTED_MASK (0xffffffffu >> (32 - IW_CUSTOM_N_SIZE))
+#define IW_CUSTOM_N_SHIFTED_MASK (IW_CUSTOM_N_UNSHIFTED_MASK << IW_CUSTOM_N_LSB)
+#define GET_IW_CUSTOM_N(W) (((W) >> IW_CUSTOM_N_LSB) & IW_CUSTOM_N_UNSHIFTED_MASK)
+#define SET_IW_CUSTOM_N(V) (((V) & IW_CUSTOM_N_UNSHIFTED_MASK) << IW_CUSTOM_N_LSB)
+
+/* R1 opcodes. */
+#define R1_OP_CALL 0
+#define R1_OP_JMPI 1
+#define R1_OP_LDBU 3
+#define R1_OP_ADDI 4
+#define R1_OP_STB 5
+#define R1_OP_BR 6
+#define R1_OP_LDB 7
+#define R1_OP_CMPGEI 8
+#define R1_OP_LDHU 11
+#define R1_OP_ANDI 12
+#define R1_OP_STH 13
+#define R1_OP_BGE 14
+#define R1_OP_LDH 15
+#define R1_OP_CMPLTI 16
+#define R1_OP_INITDA 19
+#define R1_OP_ORI 20
+#define R1_OP_STW 21
+#define R1_OP_BLT 22
+#define R1_OP_LDW 23
+#define R1_OP_CMPNEI 24
+#define R1_OP_FLUSHDA 27
+#define R1_OP_XORI 28
+#define R1_OP_BNE 30
+#define R1_OP_CMPEQI 32
+#define R1_OP_LDBUIO 35
+#define R1_OP_MULI 36
+#define R1_OP_STBIO 37
+#define R1_OP_BEQ 38
+#define R1_OP_LDBIO 39
+#define R1_OP_CMPGEUI 40
+#define R1_OP_LDHUIO 43
+#define R1_OP_ANDHI 44
+#define R1_OP_STHIO 45
+#define R1_OP_BGEU 46
+#define R1_OP_LDHIO 47
+#define R1_OP_CMPLTUI 48
+#define R1_OP_CUSTOM 50
+#define R1_OP_INITD 51
+#define R1_OP_ORHI 52
+#define R1_OP_STWIO 53
+#define R1_OP_BLTU 54
+#define R1_OP_LDWIO 55
+#define R1_OP_RDPRS 56
+#define R1_OP_OPX 58
+#define R1_OP_FLUSHD 59
+#define R1_OP_XORHI 60
+
+#define R1_OPX_ERET 1
+#define R1_OPX_ROLI 2
+#define R1_OPX_ROL 3
+#define R1_OPX_FLUSHP 4
+#define R1_OPX_RET 5
+#define R1_OPX_NOR 6
+#define R1_OPX_MULXUU 7
+#define R1_OPX_CMPGE 8
+#define R1_OPX_BRET 9
+#define R1_OPX_ROR 11
+#define R1_OPX_FLUSHI 12
+#define R1_OPX_JMP 13
+#define R1_OPX_AND 14
+#define R1_OPX_CMPLT 16
+#define R1_OPX_SLLI 18
+#define R1_OPX_SLL 19
+#define R1_OPX_WRPRS 20
+#define R1_OPX_OR 22
+#define R1_OPX_MULXSU 23
+#define R1_OPX_CMPNE 24
+#define R1_OPX_SRLI 26
+#define R1_OPX_SRL 27
+#define R1_OPX_NEXTPC 28
+#define R1_OPX_CALLR 29
+#define R1_OPX_XOR 30
+#define R1_OPX_MULXSS 31
+#define R1_OPX_CMPEQ 32
+#define R1_OPX_DIVU 36
+#define R1_OPX_DIV 37
+#define R1_OPX_RDCTL 38
+#define R1_OPX_MUL 39
+#define R1_OPX_CMPGEU 40
+#define R1_OPX_INITI 41
+#define R1_OPX_TRAP 45
+#define R1_OPX_WRCTL 46
+#define R1_OPX_CMPLTU 48
+#define R1_OPX_ADD 49
+#define R1_OPX_BREAK 52
+#define R1_OPX_SYNC 54
+#define R1_OPX_SUB 57
+#define R1_OPX_SRAI 58
+#define R1_OPX_SRA 59
+
+/* Some convenience macros for R1 encodings, for use in instruction tables.
+ MATCH_R1_OPX0(NAME) and MASK_R1_OPX0 are used for R-type instructions
+ with 3 register operands and constant 0 in the immediate field.
+ The general forms are MATCH_R1_OPX(NAME, A, B, C) where the arguments specify
+ constant values and MASK_R1_OPX(A, B, C, N) where the arguments are booleans
+ that are true if the field should be included in the mask.
+ */
+#define MATCH_R1_OP(NAME) \
+ (SET_IW_R1_OP (R1_OP_##NAME))
+#define MASK_R1_OP \
+ IW_R1_OP_SHIFTED_MASK
+
+#define MATCH_R1_OPX0(NAME) \
+ (SET_IW_R1_OP (R1_OP_OPX) | SET_IW_R_OPX (R1_OPX_##NAME))
+#define MASK_R1_OPX0 \
+ (IW_R1_OP_SHIFTED_MASK | IW_R_OPX_SHIFTED_MASK | IW_R_IMM5_SHIFTED_MASK)
+
+#define MATCH_R1_OPX(NAME, A, B, C) \
+ (MATCH_R1_OPX0 (NAME) | SET_IW_R_A (A) | SET_IW_R_B (B) | SET_IW_R_C (C))
+#define MASK_R1_OPX(A, B, C, N) \
+ (IW_R1_OP_SHIFTED_MASK | IW_R_OPX_SHIFTED_MASK \
+ | (A ? IW_R_A_SHIFTED_MASK : 0) \
+ | (B ? IW_R_B_SHIFTED_MASK : 0) \
+ | (C ? IW_R_C_SHIFTED_MASK : 0) \
+ | (N ? IW_R_IMM5_SHIFTED_MASK : 0))
+
+/* And here's the match/mask macros for the R1 instruction set. */
+#define MATCH_R1_ADD MATCH_R1_OPX0 (ADD)
+#define MASK_R1_ADD MASK_R1_OPX0
+#define MATCH_R1_ADDI MATCH_R1_OP (ADDI)
+#define MASK_R1_ADDI MASK_R1_OP
+#define MATCH_R1_AND MATCH_R1_OPX0 (AND)
+#define MASK_R1_AND MASK_R1_OPX0
+#define MATCH_R1_ANDHI MATCH_R1_OP (ANDHI)
+#define MASK_R1_ANDHI MASK_R1_OP
+#define MATCH_R1_ANDI MATCH_R1_OP (ANDI)
+#define MASK_R1_ANDI MASK_R1_OP
+#define MATCH_R1_BEQ MATCH_R1_OP (BEQ)
+#define MASK_R1_BEQ MASK_R1_OP
+#define MATCH_R1_BGE MATCH_R1_OP (BGE)
+#define MASK_R1_BGE MASK_R1_OP
+#define MATCH_R1_BGEU MATCH_R1_OP (BGEU)
+#define MASK_R1_BGEU MASK_R1_OP
+#define MATCH_R1_BGT MATCH_R1_OP (BLT)
+#define MASK_R1_BGT MASK_R1_OP
+#define MATCH_R1_BGTU MATCH_R1_OP (BLTU)
+#define MASK_R1_BGTU MASK_R1_OP
+#define MATCH_R1_BLE MATCH_R1_OP (BGE)
+#define MASK_R1_BLE MASK_R1_OP
+#define MATCH_R1_BLEU MATCH_R1_OP (BGEU)
+#define MASK_R1_BLEU MASK_R1_OP
+#define MATCH_R1_BLT MATCH_R1_OP (BLT)
+#define MASK_R1_BLT MASK_R1_OP
+#define MATCH_R1_BLTU MATCH_R1_OP (BLTU)
+#define MASK_R1_BLTU MASK_R1_OP
+#define MATCH_R1_BNE MATCH_R1_OP (BNE)
+#define MASK_R1_BNE MASK_R1_OP
+#define MATCH_R1_BR MATCH_R1_OP (BR)
+#define MASK_R1_BR MASK_R1_OP | IW_I_A_SHIFTED_MASK | IW_I_B_SHIFTED_MASK
+#define MATCH_R1_BREAK MATCH_R1_OPX (BREAK, 0, 0, 0x1e)
+#define MASK_R1_BREAK MASK_R1_OPX (1, 1, 1, 0)
+#define MATCH_R1_BRET MATCH_R1_OPX (BRET, 0x1e, 0, 0)
+#define MASK_R1_BRET MASK_R1_OPX (1, 1, 1, 1)
+#define MATCH_R1_CALL MATCH_R1_OP (CALL)
+#define MASK_R1_CALL MASK_R1_OP
+#define MATCH_R1_CALLR MATCH_R1_OPX (CALLR, 0, 0, 0x1f)
+#define MASK_R1_CALLR MASK_R1_OPX (0, 1, 1, 1)
+#define MATCH_R1_CMPEQ MATCH_R1_OPX0 (CMPEQ)
+#define MASK_R1_CMPEQ MASK_R1_OPX0
+#define MATCH_R1_CMPEQI MATCH_R1_OP (CMPEQI)
+#define MASK_R1_CMPEQI MASK_R1_OP
+#define MATCH_R1_CMPGE MATCH_R1_OPX0 (CMPGE)
+#define MASK_R1_CMPGE MASK_R1_OPX0
+#define MATCH_R1_CMPGEI MATCH_R1_OP (CMPGEI)
+#define MASK_R1_CMPGEI MASK_R1_OP
+#define MATCH_R1_CMPGEU MATCH_R1_OPX0 (CMPGEU)
+#define MASK_R1_CMPGEU MASK_R1_OPX0
+#define MATCH_R1_CMPGEUI MATCH_R1_OP (CMPGEUI)
+#define MASK_R1_CMPGEUI MASK_R1_OP
+#define MATCH_R1_CMPGT MATCH_R1_OPX0 (CMPLT)
+#define MASK_R1_CMPGT MASK_R1_OPX0
+#define MATCH_R1_CMPGTI MATCH_R1_OP (CMPGEI)
+#define MASK_R1_CMPGTI MASK_R1_OP
+#define MATCH_R1_CMPGTU MATCH_R1_OPX0 (CMPLTU)
+#define MASK_R1_CMPGTU MASK_R1_OPX0
+#define MATCH_R1_CMPGTUI MATCH_R1_OP (CMPGEUI)
+#define MASK_R1_CMPGTUI MASK_R1_OP
+#define MATCH_R1_CMPLE MATCH_R1_OPX0 (CMPGE)
+#define MASK_R1_CMPLE MASK_R1_OPX0
+#define MATCH_R1_CMPLEI MATCH_R1_OP (CMPLTI)
+#define MASK_R1_CMPLEI MASK_R1_OP
+#define MATCH_R1_CMPLEU MATCH_R1_OPX0 (CMPGEU)
+#define MASK_R1_CMPLEU MASK_R1_OPX0
+#define MATCH_R1_CMPLEUI MATCH_R1_OP (CMPLTUI)
+#define MASK_R1_CMPLEUI MASK_R1_OP
+#define MATCH_R1_CMPLT MATCH_R1_OPX0 (CMPLT)
+#define MASK_R1_CMPLT MASK_R1_OPX0
+#define MATCH_R1_CMPLTI MATCH_R1_OP (CMPLTI)
+#define MASK_R1_CMPLTI MASK_R1_OP
+#define MATCH_R1_CMPLTU MATCH_R1_OPX0 (CMPLTU)
+#define MASK_R1_CMPLTU MASK_R1_OPX0
+#define MATCH_R1_CMPLTUI MATCH_R1_OP (CMPLTUI)
+#define MASK_R1_CMPLTUI MASK_R1_OP
+#define MATCH_R1_CMPNE MATCH_R1_OPX0 (CMPNE)
+#define MASK_R1_CMPNE MASK_R1_OPX0
+#define MATCH_R1_CMPNEI MATCH_R1_OP (CMPNEI)
+#define MASK_R1_CMPNEI MASK_R1_OP
+#define MATCH_R1_CUSTOM MATCH_R1_OP (CUSTOM)
+#define MASK_R1_CUSTOM MASK_R1_OP
+#define MATCH_R1_DIV MATCH_R1_OPX0 (DIV)
+#define MASK_R1_DIV MASK_R1_OPX0
+#define MATCH_R1_DIVU MATCH_R1_OPX0 (DIVU)
+#define MASK_R1_DIVU MASK_R1_OPX0
+#define MATCH_R1_ERET MATCH_R1_OPX (ERET, 0x1d, 0x1e, 0)
+#define MASK_R1_ERET MASK_R1_OPX (1, 1, 1, 1)
+#define MATCH_R1_FLUSHD MATCH_R1_OP (FLUSHD) | SET_IW_I_B (0)
+#define MASK_R1_FLUSHD MASK_R1_OP | IW_I_B_SHIFTED_MASK
+#define MATCH_R1_FLUSHDA MATCH_R1_OP (FLUSHDA) | SET_IW_I_B (0)
+#define MASK_R1_FLUSHDA MASK_R1_OP | IW_I_B_SHIFTED_MASK
+#define MATCH_R1_FLUSHI MATCH_R1_OPX (FLUSHI, 0, 0, 0)
+#define MASK_R1_FLUSHI MASK_R1_OPX (0, 1, 1, 1)
+#define MATCH_R1_FLUSHP MATCH_R1_OPX (FLUSHP, 0, 0, 0)
+#define MASK_R1_FLUSHP MASK_R1_OPX (1, 1, 1, 1)
+#define MATCH_R1_INITD MATCH_R1_OP (INITD) | SET_IW_I_B (0)
+#define MASK_R1_INITD MASK_R1_OP | IW_I_B_SHIFTED_MASK
+#define MATCH_R1_INITDA MATCH_R1_OP (INITDA) | SET_IW_I_B (0)
+#define MASK_R1_INITDA MASK_R1_OP | IW_I_B_SHIFTED_MASK
+#define MATCH_R1_INITI MATCH_R1_OPX (INITI, 0, 0, 0)
+#define MASK_R1_INITI MASK_R1_OPX (0, 1, 1, 1)
+#define MATCH_R1_JMP MATCH_R1_OPX (JMP, 0, 0, 0)
+#define MASK_R1_JMP MASK_R1_OPX (0, 1, 1, 1)
+#define MATCH_R1_JMPI MATCH_R1_OP (JMPI)
+#define MASK_R1_JMPI MASK_R1_OP
+#define MATCH_R1_LDB MATCH_R1_OP (LDB)
+#define MASK_R1_LDB MASK_R1_OP
+#define MATCH_R1_LDBIO MATCH_R1_OP (LDBIO)
+#define MASK_R1_LDBIO MASK_R1_OP
+#define MATCH_R1_LDBU MATCH_R1_OP (LDBU)
+#define MASK_R1_LDBU MASK_R1_OP
+#define MATCH_R1_LDBUIO MATCH_R1_OP (LDBUIO)
+#define MASK_R1_LDBUIO MASK_R1_OP
+#define MATCH_R1_LDH MATCH_R1_OP (LDH)
+#define MASK_R1_LDH MASK_R1_OP
+#define MATCH_R1_LDHIO MATCH_R1_OP (LDHIO)
+#define MASK_R1_LDHIO MASK_R1_OP
+#define MATCH_R1_LDHU MATCH_R1_OP (LDHU)
+#define MASK_R1_LDHU MASK_R1_OP
+#define MATCH_R1_LDHUIO MATCH_R1_OP (LDHUIO)
+#define MASK_R1_LDHUIO MASK_R1_OP
+#define MATCH_R1_LDW MATCH_R1_OP (LDW)
+#define MASK_R1_LDW MASK_R1_OP
+#define MATCH_R1_LDWIO MATCH_R1_OP (LDWIO)
+#define MASK_R1_LDWIO MASK_R1_OP
+#define MATCH_R1_MOV MATCH_R1_OPX (ADD, 0, 0, 0)
+#define MASK_R1_MOV MASK_R1_OPX (0, 1, 0, 1)
+#define MATCH_R1_MOVHI MATCH_R1_OP (ORHI) | SET_IW_I_A (0)
+#define MASK_R1_MOVHI MASK_R1_OP | IW_I_A_SHIFTED_MASK
+#define MATCH_R1_MOVI MATCH_R1_OP (ADDI) | SET_IW_I_A (0)
+#define MASK_R1_MOVI MASK_R1_OP | IW_I_A_SHIFTED_MASK
+#define MATCH_R1_MOVUI MATCH_R1_OP (ORI) | SET_IW_I_A (0)
+#define MASK_R1_MOVUI MASK_R1_OP | IW_I_A_SHIFTED_MASK
+#define MATCH_R1_MUL MATCH_R1_OPX0 (MUL)
+#define MASK_R1_MUL MASK_R1_OPX0
+#define MATCH_R1_MULI MATCH_R1_OP (MULI)
+#define MASK_R1_MULI MASK_R1_OP
+#define MATCH_R1_MULXSS MATCH_R1_OPX0 (MULXSS)
+#define MASK_R1_MULXSS MASK_R1_OPX0
+#define MATCH_R1_MULXSU MATCH_R1_OPX0 (MULXSU)
+#define MASK_R1_MULXSU MASK_R1_OPX0
+#define MATCH_R1_MULXUU MATCH_R1_OPX0 (MULXUU)
+#define MASK_R1_MULXUU MASK_R1_OPX0
+#define MATCH_R1_NEXTPC MATCH_R1_OPX (NEXTPC, 0, 0, 0)
+#define MASK_R1_NEXTPC MASK_R1_OPX (1, 1, 0, 1)
+#define MATCH_R1_NOP MATCH_R1_OPX (ADD, 0, 0, 0)
+#define MASK_R1_NOP MASK_R1_OPX (1, 1, 1, 1)
+#define MATCH_R1_NOR MATCH_R1_OPX0 (NOR)
+#define MASK_R1_NOR MASK_R1_OPX0
+#define MATCH_R1_OR MATCH_R1_OPX0 (OR)
+#define MASK_R1_OR MASK_R1_OPX0
+#define MATCH_R1_ORHI MATCH_R1_OP (ORHI)
+#define MASK_R1_ORHI MASK_R1_OP
+#define MATCH_R1_ORI MATCH_R1_OP (ORI)
+#define MASK_R1_ORI MASK_R1_OP
+#define MATCH_R1_RDCTL MATCH_R1_OPX (RDCTL, 0, 0, 0)
+#define MASK_R1_RDCTL MASK_R1_OPX (1, 1, 0, 0)
+#define MATCH_R1_RDPRS MATCH_R1_OP (RDPRS)
+#define MASK_R1_RDPRS MASK_R1_OP
+#define MATCH_R1_RET MATCH_R1_OPX (RET, 0x1f, 0, 0)
+#define MASK_R1_RET MASK_R1_OPX (1, 1, 1, 1)
+#define MATCH_R1_ROL MATCH_R1_OPX0 (ROL)
+#define MASK_R1_ROL MASK_R1_OPX0
+#define MATCH_R1_ROLI MATCH_R1_OPX (ROLI, 0, 0, 0)
+#define MASK_R1_ROLI MASK_R1_OPX (0, 1, 0, 0)
+#define MATCH_R1_ROR MATCH_R1_OPX0 (ROR)
+#define MASK_R1_ROR MASK_R1_OPX0
+#define MATCH_R1_SLL MATCH_R1_OPX0 (SLL)
+#define MASK_R1_SLL MASK_R1_OPX0
+#define MATCH_R1_SLLI MATCH_R1_OPX (SLLI, 0, 0, 0)
+#define MASK_R1_SLLI MASK_R1_OPX (0, 1, 0, 0)
+#define MATCH_R1_SRA MATCH_R1_OPX0 (SRA)
+#define MASK_R1_SRA MASK_R1_OPX0
+#define MATCH_R1_SRAI MATCH_R1_OPX (SRAI, 0, 0, 0)
+#define MASK_R1_SRAI MASK_R1_OPX (0, 1, 0, 0)
+#define MATCH_R1_SRL MATCH_R1_OPX0 (SRL)
+#define MASK_R1_SRL MASK_R1_OPX0
+#define MATCH_R1_SRLI MATCH_R1_OPX (SRLI, 0, 0, 0)
+#define MASK_R1_SRLI MASK_R1_OPX (0, 1, 0, 0)
+#define MATCH_R1_STB MATCH_R1_OP (STB)
+#define MASK_R1_STB MASK_R1_OP
+#define MATCH_R1_STBIO MATCH_R1_OP (STBIO)
+#define MASK_R1_STBIO MASK_R1_OP
+#define MATCH_R1_STH MATCH_R1_OP (STH)
+#define MASK_R1_STH MASK_R1_OP
+#define MATCH_R1_STHIO MATCH_R1_OP (STHIO)
+#define MASK_R1_STHIO MASK_R1_OP
+#define MATCH_R1_STW MATCH_R1_OP (STW)
+#define MASK_R1_STW MASK_R1_OP
+#define MATCH_R1_STWIO MATCH_R1_OP (STWIO)
+#define MASK_R1_STWIO MASK_R1_OP
+#define MATCH_R1_SUB MATCH_R1_OPX0 (SUB)
+#define MASK_R1_SUB MASK_R1_OPX0
+#define MATCH_R1_SUBI MATCH_R1_OP (ADDI)
+#define MASK_R1_SUBI MASK_R1_OP
+#define MATCH_R1_SYNC MATCH_R1_OPX (SYNC, 0, 0, 0)
+#define MASK_R1_SYNC MASK_R1_OPX (1, 1, 1, 1)
+#define MATCH_R1_TRAP MATCH_R1_OPX (TRAP, 0, 0, 0x1d)
+#define MASK_R1_TRAP MASK_R1_OPX (1, 1, 1, 0)
+#define MATCH_R1_WRCTL MATCH_R1_OPX (WRCTL, 0, 0, 0)
+#define MASK_R1_WRCTL MASK_R1_OPX (0, 1, 1, 0)
+#define MATCH_R1_WRPRS MATCH_R1_OPX (WRPRS, 0, 0, 0)
+#define MASK_R1_WRPRS MASK_R1_OPX (0, 1, 0, 1)
+#define MATCH_R1_XOR MATCH_R1_OPX0 (XOR)
+#define MASK_R1_XOR MASK_R1_OPX0
+#define MATCH_R1_XORHI MATCH_R1_OP (XORHI)
+#define MASK_R1_XORHI MASK_R1_OP
+#define MATCH_R1_XORI MATCH_R1_OP (XORI)
+#define MASK_R1_XORI MASK_R1_OP
+
+#endif /* _NIOS2R1_H */
+2014-10-23 Sandra Loosemore <sandra@codesourcery.com>
+
+ * nios2-opc.c (nios2_builtin_regs): Add regtype field initializers.
+ (nios2_builtin_opcodes): Rename to nios2_r1_opcodes. Use new
+ MATCH_R1_<insn> and MASK_R1_<insn> macros in initializers. Add
+ size and format initializers. Merge 'b' arguments into 'j'.
+ (NIOS2_NUM_OPCODES): Adjust definition.
+ (bfd_nios2_num_builtin_opcodes): Rename to nios2_num_r1_opcodes.
+ (nios2_opcodes): Adjust.
+ (bfd_nios2_num_opcodes): Rename to nios2_num_opcodes.
+ * nios2-dis.c (INSNLEN): Update comment.
+ (nios2_hash_init, nios2_hash): Delete.
+ (OPCODE_HASH_SIZE): New.
+ (nios2_r1_extract_opcode): New.
+ (nios2_disassembler_state): New.
+ (nios2_r1_disassembler_state): New.
+ (nios2_init_opcode_hash): Add state parameter. Adjust to use it.
+ (nios2_find_opcode_hash): Use state object.
+ (bad_opcode): New.
+ (nios2_print_insn_arg): Add op parameter. Use it to access
+ format. Remove 'b' case.
+ (nios2_disassemble): Remove special case for nop. Remove
+ hard-coded instruction size.
+
2014-10-21 Jan Beulich <jbeulich@suse.com>
* ppc-opc.c (powerpc_opcodes): Enable msgclr and msgsnd on Power8.
#include "elf/nios2.h"
#endif
-/* Length of Nios II instruction in bytes. */
+/* Default length of Nios II instruction in bytes. */
#define INSNLEN 4
/* Data structures used by the opcode hash table. */
struct _nios2_opcode_hash *next;
} nios2_opcode_hash;
-static bfd_boolean nios2_hash_init = 0;
-static nios2_opcode_hash *nios2_hash[(OP_MASK_OP) + 1];
+/* Hash table size. */
+#define OPCODE_HASH_SIZE (IW_R1_OP_UNSHIFTED_MASK + 1)
-/* Separate hash table for pseudo-ops. */
-static nios2_opcode_hash *nios2_ps_hash[(OP_MASK_OP) + 1];
+/* Extract the opcode from an instruction word. */
+static unsigned int
+nios2_r1_extract_opcode (unsigned int x)
+{
+ return GET_IW_R1_OP (x);
+}
+
+/* Pseudo-ops are stored in a different table than regular instructions. */
+
+typedef struct _nios2_disassembler_state
+{
+ const struct nios2_opcode *opcodes;
+ const int *num_opcodes;
+ unsigned int (*extract_opcode) (unsigned int);
+ nios2_opcode_hash *hash[OPCODE_HASH_SIZE];
+ nios2_opcode_hash *ps_hash[OPCODE_HASH_SIZE];
+ const struct nios2_opcode *nop;
+ bfd_boolean init;
+} nios2_disassembler_state;
+
+static nios2_disassembler_state
+nios2_r1_disassembler_state = {
+ nios2_r1_opcodes,
+ &nios2_num_r1_opcodes,
+ nios2_r1_extract_opcode,
+ {},
+ {},
+ NULL,
+ 0
+};
/* Function to initialize the opcode hash table. */
static void
-nios2_init_opcode_hash (void)
+nios2_init_opcode_hash (nios2_disassembler_state *state)
{
unsigned int i;
register const struct nios2_opcode *op;
- for (i = 0; i <= OP_MASK_OP; ++i)
- nios2_hash[0] = NULL;
- for (i = 0; i <= OP_MASK_OP; i++)
- for (op = nios2_opcodes; op < &nios2_opcodes[NUMOPCODES]; op++)
+ for (i = 0; i < OPCODE_HASH_SIZE; i++)
+ for (op = state->opcodes; op < &state->opcodes[*(state->num_opcodes)]; op++)
{
nios2_opcode_hash *new_hash;
nios2_opcode_hash **bucket = NULL;
if ((op->pinfo & NIOS2_INSN_MACRO) == NIOS2_INSN_MACRO)
{
- if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP)
+ if (i == state->extract_opcode (op->match)
&& (op->pinfo & (NIOS2_INSN_MACRO_MOV | NIOS2_INSN_MACRO_MOVI)
& 0x7fffffff))
- bucket = &(nios2_ps_hash[i]);
+ {
+ bucket = &(state->ps_hash[i]);
+ if (strcmp (op->name, "nop") == 0)
+ state->nop = op;
+ }
}
- else if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
- bucket = &(nios2_hash[i]);
+ else if (i == state->extract_opcode (op->match))
+ bucket = &(state->hash[i]);
if (bucket)
{
*bucket = new_hash;
}
}
- nios2_hash_init = 1;
+ state->init = 1;
+
#ifdef DEBUG_HASHTABLE
- for (i = 0; i <= OP_MASK_OP; ++i)
+ for (i = 0; i < OPCODE_HASH_SIZE; ++i)
{
- nios2_opcode_hash *tmp_hash = nios2_hash[i];
+ nios2_opcode_hash *tmp_hash = state->hash[i];
printf ("index: 0x%02X ops: ", i);
while (tmp_hash != NULL)
{
printf ("\n");
}
- for (i = 0; i <= OP_MASK_OP; ++i)
+ for (i = 0; i < OPCODE_HASH_SIZE; ++i)
{
- nios2_opcode_hash *tmp_hash = nios2_ps_hash[i];
+ nios2_opcode_hash *tmp_hash = state->ps_hash[i];
printf ("index: 0x%02X ops: ", i);
while (tmp_hash != NULL)
{
nios2_find_opcode_hash (unsigned long opcode)
{
nios2_opcode_hash *entry;
+ nios2_disassembler_state *state;
+
+ state = &nios2_r1_disassembler_state;
/* Build a hash table to shorten the search time. */
- if (!nios2_hash_init)
- nios2_init_opcode_hash ();
+ if (!state->init)
+ nios2_init_opcode_hash (state);
+
+ /* Check for NOP first. Both NOP and MOV are macros that expand into
+ an ADD instruction, and we always want to give priority to NOP. */
+ if (state->nop->match == (opcode & state->nop->mask))
+ return state->nop;
/* First look in the pseudo-op hashtable. */
- for (entry = nios2_ps_hash[(opcode >> OP_SH_OP) & OP_MASK_OP];
+ for (entry = state->ps_hash[state->extract_opcode (opcode)];
entry; entry = entry->next)
if (entry->opcode->match == (opcode & entry->opcode->mask))
return entry->opcode;
/* Otherwise look in the main hashtable. */
- for (entry = nios2_hash[(opcode >> OP_SH_OP) & OP_MASK_OP];
+ for (entry = state->hash[state->extract_opcode (opcode)];
entry; entry = entry->next)
if (entry->opcode->match == (opcode & entry->opcode->mask))
return entry->opcode;
return cached;
}
+/* Helper routine to report internal errors. */
+static void
+bad_opcode (const struct nios2_opcode *op)
+{
+ fprintf (stderr, "Internal error: broken opcode descriptor for `%s %s'\n",
+ op->name, op->args);
+ abort ();
+}
+
/* The function nios2_print_insn_arg uses the character pointed
to by ARGPTR to determine how it print the next token or separator
character in the arguments to an instruction. */
static int
nios2_print_insn_arg (const char *argptr,
unsigned long opcode, bfd_vma address,
- disassemble_info *info)
+ disassemble_info *info,
+ const struct nios2_opcode *op)
{
unsigned long i = 0;
struct nios2_reg *reg_base;
case ')':
(*info->fprintf_func) (info->stream, "%c", *argptr);
break;
- case 'd':
- i = GET_INSN_FIELD (RRD, opcode);
-
- if (GET_INSN_FIELD (OP, opcode) == OP_MATCH_CUSTOM
- && GET_INSN_FIELD (CUSTOM_C, opcode) == 0)
- reg_base = nios2_coprocessor_regs ();
- else
- reg_base = nios2_regs;
+ case 'd':
+ switch (op->format)
+ {
+ case iw_r_type:
+ i = GET_IW_R_C (opcode);
+ reg_base = nios2_regs;
+ break;
+ case iw_custom_type:
+ i = GET_IW_CUSTOM_C (opcode);
+ if (GET_IW_CUSTOM_READC (opcode) == 0)
+ reg_base = nios2_coprocessor_regs ();
+ else
+ reg_base = nios2_regs;
+ break;
+ default:
+ bad_opcode (op);
+ }
if (i < NUMREGNAMES)
(*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
else
(*info->fprintf_func) (info->stream, "unknown");
break;
- case 's':
- i = GET_INSN_FIELD (RRS, opcode);
-
- if (GET_INSN_FIELD (OP, opcode) == OP_MATCH_CUSTOM
- && GET_INSN_FIELD (CUSTOM_A, opcode) == 0)
- reg_base = nios2_coprocessor_regs ();
- else
- reg_base = nios2_regs;
+ case 's':
+ switch (op->format)
+ {
+ case iw_r_type:
+ i = GET_IW_R_A (opcode);
+ reg_base = nios2_regs;
+ break;
+ case iw_i_type:
+ i = GET_IW_I_A (opcode);
+ reg_base = nios2_regs;
+ break;
+ case iw_custom_type:
+ i = GET_IW_CUSTOM_A (opcode);
+ if (GET_IW_CUSTOM_READA (opcode) == 0)
+ reg_base = nios2_coprocessor_regs ();
+ else
+ reg_base = nios2_regs;
+ break;
+ default:
+ bad_opcode (op);
+ }
if (i < NUMREGNAMES)
(*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
else
(*info->fprintf_func) (info->stream, "unknown");
break;
- case 't':
- i = GET_INSN_FIELD (RRT, opcode);
-
- if (GET_INSN_FIELD (OP, opcode) == OP_MATCH_CUSTOM
- && GET_INSN_FIELD (CUSTOM_B, opcode) == 0)
- reg_base = nios2_coprocessor_regs ();
- else
- reg_base = nios2_regs;
+ case 't':
+ switch (op->format)
+ {
+ case iw_r_type:
+ i = GET_IW_R_B (opcode);
+ reg_base = nios2_regs;
+ break;
+ case iw_i_type:
+ i = GET_IW_I_B (opcode);
+ reg_base = nios2_regs;
+ break;
+ case iw_custom_type:
+ i = GET_IW_CUSTOM_B (opcode);
+ if (GET_IW_CUSTOM_READB (opcode) == 0)
+ reg_base = nios2_coprocessor_regs ();
+ else
+ reg_base = nios2_regs;
+ break;
+ default:
+ bad_opcode (op);
+ }
if (i < NUMREGNAMES)
(*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
else
(*info->fprintf_func) (info->stream, "unknown");
break;
+
case 'i':
/* 16-bit signed immediate. */
- i = (signed) (GET_INSN_FIELD (IMM16, opcode) << 16) >> 16;
+ switch (op->format)
+ {
+ case iw_i_type:
+ i = (signed) (GET_IW_I_IMM16 (opcode) << 16) >> 16;
+ break;
+ default:
+ bad_opcode (op);
+ }
(*info->fprintf_func) (info->stream, "%ld", i);
break;
+
case 'u':
/* 16-bit unsigned immediate. */
- i = GET_INSN_FIELD (IMM16, opcode);
+ switch (op->format)
+ {
+ case iw_i_type:
+ i = GET_IW_I_IMM16 (opcode);
+ break;
+ default:
+ bad_opcode (op);
+ }
(*info->fprintf_func) (info->stream, "%ld", i);
break;
+
case 'o':
/* 16-bit signed immediate address offset. */
- i = (signed) (GET_INSN_FIELD (IMM16, opcode) << 16) >> 16;
+ switch (op->format)
+ {
+ case iw_i_type:
+ i = (signed) (GET_IW_I_IMM16 (opcode) << 16) >> 16;
+ break;
+ default:
+ bad_opcode (op);
+ }
address = address + 4 + i;
(*info->print_address_func) (address, info);
break;
- case 'p':
- /* 5-bit unsigned immediate. */
- i = GET_INSN_FIELD (CACHE_OPX, opcode);
- (*info->fprintf_func) (info->stream, "%ld", i);
- break;
+
case 'j':
/* 5-bit unsigned immediate. */
- i = GET_INSN_FIELD (IMM5, opcode);
+ switch (op->format)
+ {
+ case iw_r_type:
+ i = GET_IW_R_IMM5 (opcode);
+ break;
+ default:
+ bad_opcode (op);
+ }
(*info->fprintf_func) (info->stream, "%ld", i);
break;
+
case 'l':
/* 8-bit unsigned immediate. */
- /* FIXME - not yet implemented */
- i = GET_INSN_FIELD (CUSTOM_N, opcode);
+ switch (op->format)
+ {
+ case iw_custom_type:
+ i = GET_IW_CUSTOM_N (opcode);
+ break;
+ default:
+ bad_opcode (op);
+ }
(*info->fprintf_func) (info->stream, "%lu", i);
break;
+
case 'm':
/* 26-bit unsigned immediate. */
- i = GET_INSN_FIELD (IMM26, opcode);
+ switch (op->format)
+ {
+ case iw_j_type:
+ i = GET_IW_J_IMM26 (opcode);
+ break;
+ default:
+ bad_opcode (op);
+ }
/* This translates to an address because it's only used in call
instructions. */
address = (address & 0xf0000000) | (i << 2);
(*info->print_address_func) (address, info);
break;
+
case 'c':
/* Control register index. */
- i = GET_INSN_FIELD (IMM5, opcode);
+ switch (op->format)
+ {
+ case iw_r_type:
+ i = GET_IW_R_IMM5 (opcode);
+ break;
+ default:
+ bad_opcode (op);
+ }
reg_base = nios2_control_regs ();
(*info->fprintf_func) (info->stream, "%s", reg_base[i].name);
break;
- case 'b':
- i = GET_INSN_FIELD (IMM5, opcode);
- (*info->fprintf_func) (info->stream, "%ld", i);
- break;
+
default:
(*info->fprintf_func) (info->stream, "unknown");
break;
if (op != NULL)
{
- bfd_boolean is_nop = FALSE;
- if (op->pinfo == NIOS2_INSN_MACRO_MOV)
- {
- /* Check for mov r0, r0 and change to nop. */
- int dst, src;
- dst = GET_INSN_FIELD (RRD, opcode);
- src = GET_INSN_FIELD (RRS, opcode);
- if (dst == 0 && src == 0)
- {
- (*info->fprintf_func) (info->stream, "nop");
- is_nop = TRUE;
- }
- else
- (*info->fprintf_func) (info->stream, "%s", op->name);
- }
- else
- (*info->fprintf_func) (info->stream, "%s", op->name);
-
- if (!is_nop)
+ const char *argstr = op->args;
+ (*info->fprintf_func) (info->stream, "%s", op->name);
+ if (argstr != NULL && *argstr != '\0')
{
- const char *argstr = op->args;
- if (argstr != NULL && *argstr != '\0')
+ (*info->fprintf_func) (info->stream, "\t");
+ while (*argstr != '\0')
{
- (*info->fprintf_func) (info->stream, "\t");
- while (*argstr != '\0')
- {
- nios2_print_insn_arg (argstr, opcode, address, info);
- ++argstr;
- }
+ nios2_print_insn_arg (argstr, opcode, address, info, op);
+ ++argstr;
}
}
+ /* Tell the caller how far to advance the program counter. */
+ info->bytes_per_chunk = op->size;
+ return op->size;
}
else
{
/* Handle undefined instructions. */
info->insn_type = dis_noninsn;
(*info->fprintf_func) (info->stream, "0x%lx", opcode);
+ return INSNLEN;
}
- /* Tell the caller how far to advance the program counter. */
- return INSNLEN;
}
const struct nios2_reg nios2_builtin_regs[] = {
/* Standard register names. */
- {"zero", 0},
- {"at", 1}, /* assembler temporary */
- {"r2", 2},
- {"r3", 3},
- {"r4", 4},
- {"r5", 5},
- {"r6", 6},
- {"r7", 7},
- {"r8", 8},
- {"r9", 9},
- {"r10", 10},
- {"r11", 11},
- {"r12", 12},
- {"r13", 13},
- {"r14", 14},
- {"r15", 15},
- {"r16", 16},
- {"r17", 17},
- {"r18", 18},
- {"r19", 19},
- {"r20", 20},
- {"r21", 21},
- {"r22", 22},
- {"r23", 23},
- {"et", 24},
- {"bt", 25},
- {"gp", 26}, /* global pointer */
- {"sp", 27}, /* stack pointer */
- {"fp", 28}, /* frame pointer */
- {"ea", 29}, /* exception return address */
- {"sstatus", 30}, /* saved processor status */
- {"ra", 31}, /* return address */
+ {"zero", 0, REG_NORMAL},
+ {"at", 1, REG_NORMAL}, /* assembler temporary */
+ {"r2", 2, REG_NORMAL},
+ {"r3", 3, REG_NORMAL},
+ {"r4", 4, REG_NORMAL},
+ {"r5", 5, REG_NORMAL},
+ {"r6", 6, REG_NORMAL},
+ {"r7", 7, REG_NORMAL},
+ {"r8", 8, REG_NORMAL},
+ {"r9", 9, REG_NORMAL},
+ {"r10", 10, REG_NORMAL},
+ {"r11", 11, REG_NORMAL},
+ {"r12", 12, REG_NORMAL},
+ {"r13", 13, REG_NORMAL},
+ {"r14", 14, REG_NORMAL},
+ {"r15", 15, REG_NORMAL},
+ {"r16", 16, REG_NORMAL},
+ {"r17", 17, REG_NORMAL},
+ {"r18", 18, REG_NORMAL},
+ {"r19", 19, REG_NORMAL},
+ {"r20", 20, REG_NORMAL},
+ {"r21", 21, REG_NORMAL},
+ {"r22", 22, REG_NORMAL},
+ {"r23", 23, REG_NORMAL},
+ {"et", 24, REG_NORMAL},
+ {"bt", 25, REG_NORMAL},
+ {"gp", 26, REG_NORMAL}, /* global pointer */
+ {"sp", 27, REG_NORMAL}, /* stack pointer */
+ {"fp", 28, REG_NORMAL}, /* frame pointer */
+ {"ea", 29, REG_NORMAL}, /* exception return address */
+ {"sstatus", 30, REG_NORMAL}, /* saved processor status */
+ {"ra", 31, REG_NORMAL}, /* return address */
/* Alternative names for special registers. */
- {"r0", 0},
- {"r1", 1},
- {"r24", 24},
- {"r25", 25},
- {"r26", 26},
- {"r27", 27},
- {"r28", 28},
- {"r29", 29},
- {"r30", 30},
- {"ba", 30}, /* breakpoint return address */
- {"r31", 31},
+ {"r0", 0, REG_NORMAL},
+ {"r1", 1, REG_NORMAL},
+ {"r24", 24, REG_NORMAL},
+ {"r25", 25, REG_NORMAL},
+ {"r26", 26, REG_NORMAL},
+ {"r27", 27, REG_NORMAL},
+ {"r28", 28, REG_NORMAL},
+ {"r29", 29, REG_NORMAL},
+ {"r30", 30, REG_NORMAL},
+ {"ba", 30, REG_NORMAL}, /* breakpoint return address */
+ {"r31", 31, REG_NORMAL},
/* Control register names. */
- {"status", 0},
- {"estatus", 1},
- {"bstatus", 2},
- {"ienable", 3},
- {"ipending", 4},
- {"cpuid", 5},
- {"ctl6", 6},
- {"exception", 7},
- {"pteaddr", 8},
- {"tlbacc", 9},
- {"tlbmisc", 10},
- {"eccinj", 11},
- {"badaddr", 12},
- {"config", 13},
- {"mpubase", 14},
- {"mpuacc", 15},
- {"ctl16", 16},
- {"ctl17", 17},
- {"ctl18", 18},
- {"ctl19", 19},
- {"ctl20", 20},
- {"ctl21", 21},
- {"ctl22", 22},
- {"ctl23", 23},
- {"ctl24", 24},
- {"ctl25", 25},
- {"ctl26", 26},
- {"ctl27", 27},
- {"ctl28", 28},
- {"ctl29", 29},
- {"ctl30", 30},
- {"ctl31", 31},
+ {"status", 0, REG_CONTROL},
+ {"estatus", 1, REG_CONTROL},
+ {"bstatus", 2, REG_CONTROL},
+ {"ienable", 3, REG_CONTROL},
+ {"ipending", 4, REG_CONTROL},
+ {"cpuid", 5, REG_CONTROL},
+ {"ctl6", 6, REG_CONTROL},
+ {"exception", 7, REG_CONTROL},
+ {"pteaddr", 8, REG_CONTROL},
+ {"tlbacc", 9, REG_CONTROL},
+ {"tlbmisc", 10, REG_CONTROL},
+ {"eccinj", 11, REG_CONTROL},
+ {"badaddr", 12, REG_CONTROL},
+ {"config", 13, REG_CONTROL},
+ {"mpubase", 14, REG_CONTROL},
+ {"mpuacc", 15, REG_CONTROL},
+ {"ctl16", 16, REG_CONTROL},
+ {"ctl17", 17, REG_CONTROL},
+ {"ctl18", 18, REG_CONTROL},
+ {"ctl19", 19, REG_CONTROL},
+ {"ctl20", 20, REG_CONTROL},
+ {"ctl21", 21, REG_CONTROL},
+ {"ctl22", 22, REG_CONTROL},
+ {"ctl23", 23, REG_CONTROL},
+ {"ctl24", 24, REG_CONTROL},
+ {"ctl25", 25, REG_CONTROL},
+ {"ctl26", 26, REG_CONTROL},
+ {"ctl27", 27, REG_CONTROL},
+ {"ctl28", 28, REG_CONTROL},
+ {"ctl29", 29, REG_CONTROL},
+ {"ctl30", 30, REG_CONTROL},
+ {"ctl31", 31, REG_CONTROL},
/* Alternative names for special control registers. */
- {"ctl0", 0},
- {"ctl1", 1},
- {"ctl2", 2},
- {"ctl3", 3},
- {"ctl4", 4},
- {"ctl5", 5},
- {"ctl7", 7},
- {"ctl8", 8},
- {"ctl9", 9},
- {"ctl10", 10},
- {"ctl11", 11},
- {"ctl12", 12},
- {"ctl13", 13},
- {"ctl14", 14},
- {"ctl15", 15},
+ {"ctl0", 0, REG_CONTROL},
+ {"ctl1", 1, REG_CONTROL},
+ {"ctl2", 2, REG_CONTROL},
+ {"ctl3", 3, REG_CONTROL},
+ {"ctl4", 4, REG_CONTROL},
+ {"ctl5", 5, REG_CONTROL},
+ {"ctl7", 7, REG_CONTROL},
+ {"ctl8", 8, REG_CONTROL},
+ {"ctl9", 9, REG_CONTROL},
+ {"ctl10", 10, REG_CONTROL},
+ {"ctl11", 11, REG_CONTROL},
+ {"ctl12", 12, REG_CONTROL},
+ {"ctl13", 13, REG_CONTROL},
+ {"ctl14", 14, REG_CONTROL},
+ {"ctl15", 15, REG_CONTROL},
/* Coprocessor register names. */
- {"c0", 0},
- {"c1", 1},
- {"c2", 2},
- {"c3", 3},
- {"c4", 4},
- {"c5", 5},
- {"c6", 6},
- {"c7", 7},
- {"c8", 8},
- {"c9", 9},
- {"c10", 10},
- {"c11", 11},
- {"c12", 12},
- {"c13", 13},
- {"c14", 14},
- {"c15", 15},
- {"c16", 16},
- {"c17", 17},
- {"c18", 18},
- {"c19", 19},
- {"c20", 20},
- {"c21", 21},
- {"c22", 22},
- {"c23", 23},
- {"c24", 24},
- {"c25", 25},
- {"c26", 26},
- {"c27", 27},
- {"c28", 28},
- {"c29", 29},
- {"c30", 30},
- {"c31", 31},
+ {"c0", 0, REG_COPROCESSOR},
+ {"c1", 1, REG_COPROCESSOR},
+ {"c2", 2, REG_COPROCESSOR},
+ {"c3", 3, REG_COPROCESSOR},
+ {"c4", 4, REG_COPROCESSOR},
+ {"c5", 5, REG_COPROCESSOR},
+ {"c6", 6, REG_COPROCESSOR},
+ {"c7", 7, REG_COPROCESSOR},
+ {"c8", 8, REG_COPROCESSOR},
+ {"c9", 9, REG_COPROCESSOR},
+ {"c10", 10, REG_COPROCESSOR},
+ {"c11", 11, REG_COPROCESSOR},
+ {"c12", 12, REG_COPROCESSOR},
+ {"c13", 13, REG_COPROCESSOR},
+ {"c14", 14, REG_COPROCESSOR},
+ {"c15", 15, REG_COPROCESSOR},
+ {"c16", 16, REG_COPROCESSOR},
+ {"c17", 17, REG_COPROCESSOR},
+ {"c18", 18, REG_COPROCESSOR},
+ {"c19", 19, REG_COPROCESSOR},
+ {"c20", 20, REG_COPROCESSOR},
+ {"c21", 21, REG_COPROCESSOR},
+ {"c22", 22, REG_COPROCESSOR},
+ {"c23", 23, REG_COPROCESSOR},
+ {"c24", 24, REG_COPROCESSOR},
+ {"c25", 25, REG_COPROCESSOR},
+ {"c26", 26, REG_COPROCESSOR},
+ {"c27", 27, REG_COPROCESSOR},
+ {"c28", 28, REG_COPROCESSOR},
+ {"c29", 29, REG_COPROCESSOR},
+ {"c30", 30, REG_COPROCESSOR},
+ {"c31", 31, REG_COPROCESSOR},
};
#define NIOS2_NUM_REGS \
/* This is the opcode table used by the Nios II GNU as, disassembler
and GDB. */
-const struct nios2_opcode nios2_builtin_opcodes[] =
+const struct nios2_opcode nios2_r1_opcodes[] =
{
- /* { name, args, args_test, num_args,
- match, mask, pinfo, overflow_msg } */
- {"add", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_ADD, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
- {"addi", "t,s,i", "t,s,i,E", 3,
- OP_MATCH_ADDI, OP_MASK_IOP, NIOS2_INSN_ADDI, signed_immed16_overflow},
- {"subi", "t,s,i", "t,s,i,E", 3,
- OP_MATCH_ADDI, OP_MASK_IOP, NIOS2_INSN_MACRO, signed_immed16_overflow},
- {"and", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_AND, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
- {"andhi", "t,s,u", "t,s,u,E", 3,
- OP_MATCH_ANDHI, OP_MASK_IOP, 0, unsigned_immed16_overflow},
- {"andi", "t,s,u", "t,s,u,E", 3,
- OP_MATCH_ANDI, OP_MASK_IOP, NIOS2_INSN_ANDI, unsigned_immed16_overflow},
- {"beq", "s,t,o", "s,t,o,E", 3,
- OP_MATCH_BEQ, OP_MASK_IOP, NIOS2_INSN_CBRANCH, branch_target_overflow},
- {"bge", "s,t,o", "s,t,o,E", 3,
- OP_MATCH_BGE, OP_MASK_IOP, NIOS2_INSN_CBRANCH, branch_target_overflow},
- {"bgeu", "s,t,o", "s,t,o,E", 3,
- OP_MATCH_BGEU, OP_MASK_IOP, NIOS2_INSN_CBRANCH, branch_target_overflow},
- {"bgt", "s,t,o", "s,t,o,E", 3,
- OP_MATCH_BLT, OP_MASK_IOP, NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH,
- branch_target_overflow},
- {"bgtu", "s,t,o", "s,t,o,E", 3,
- OP_MATCH_BLTU, OP_MASK_IOP, NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH,
- branch_target_overflow},
- {"ble", "s,t,o", "s,t,o,E", 3,
- OP_MATCH_BGE, OP_MASK_IOP, NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH,
- branch_target_overflow},
- {"bleu", "s,t,o", "s,t,o,E", 3,
- OP_MATCH_BGEU, OP_MASK_IOP, NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH,
- branch_target_overflow},
- {"blt", "s,t,o", "s,t,o,E", 3,
- OP_MATCH_BLT, OP_MASK_IOP, NIOS2_INSN_CBRANCH, branch_target_overflow},
- {"bltu", "s,t,o", "s,t,o,E", 3,
- OP_MATCH_BLTU, OP_MASK_IOP, NIOS2_INSN_CBRANCH, branch_target_overflow},
- {"bne", "s,t,o", "s,t,o,E", 3,
- OP_MATCH_BNE, OP_MASK_IOP, NIOS2_INSN_CBRANCH, branch_target_overflow},
- {"br", "o", "o,E", 1,
- OP_MATCH_BR, OP_MASK_IOP, NIOS2_INSN_UBRANCH, branch_target_overflow},
- {"break", "b", "b,E", 1,
- OP_MATCH_BREAK, OP_MASK_BREAK, 0, no_overflow},
- {"bret", "", "E", 0,
- OP_MATCH_BRET, OP_MASK, 0, no_overflow},
- {"flushd", "i(s)", "i(s)E", 2,
- OP_MATCH_FLUSHD, OP_MASK_IOP, 0, signed_immed16_overflow},
- {"flushda", "i(s)", "i(s)E", 2,
- OP_MATCH_FLUSHDA, OP_MASK_IOP, 0, signed_immed16_overflow},
- {"flushi", "s", "s,E", 1,
- OP_MATCH_FLUSHI, OP_MASK_FLUSHI, 0, no_overflow},
- {"flushp", "", "E", 0,
- OP_MATCH_FLUSHP, OP_MASK, 0, no_overflow},
- {"initd", "i(s)", "i(s)E", 2,
- OP_MATCH_INITD, OP_MASK_IOP, 0, signed_immed16_overflow},
- {"initda", "i(s)", "i(s)E", 2,
- OP_MATCH_INITDA, OP_MASK_IOP, 0, signed_immed16_overflow},
- {"initi", "s", "s,E", 1,
- OP_MATCH_INITI, OP_MASK_INITI, 0, no_overflow},
- {"call", "m", "m,E", 1,
- OP_MATCH_CALL, OP_MASK_IOP, NIOS2_INSN_CALL, call_target_overflow},
- {"callr", "s", "s,E", 1,
- OP_MATCH_CALLR, OP_MASK_CALLR, 0, no_overflow},
- {"cmpeq", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_CMPEQ, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
- {"cmpeqi", "t,s,i", "t,s,i,E", 3,
- OP_MATCH_CMPEQI, OP_MASK_IOP, 0, signed_immed16_overflow},
- {"cmpge", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_CMPGE, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
- {"cmpgei", "t,s,i", "t,s,i,E", 3,
- OP_MATCH_CMPGEI, OP_MASK_IOP, 0, signed_immed16_overflow},
- {"cmpgeu", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_CMPGEU, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
- {"cmpgeui", "t,s,u", "t,s,u,E", 3,
- OP_MATCH_CMPGEUI, OP_MASK_IOP, 0, unsigned_immed16_overflow},
- {"cmpgt", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_CMPLT, OP_MASK_ROPX | OP_MASK_ROP, NIOS2_INSN_MACRO, no_overflow},
- {"cmpgti", "t,s,i", "t,s,i,E", 3,
- OP_MATCH_CMPGEI, OP_MASK_IOP, NIOS2_INSN_MACRO, signed_immed16_overflow},
- {"cmpgtu", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_CMPLTU, OP_MASK_ROPX | OP_MASK_ROP, NIOS2_INSN_MACRO, no_overflow},
- {"cmpgtui", "t,s,u", "t,s,u,E", 3,
- OP_MATCH_CMPGEUI, OP_MASK_IOP, NIOS2_INSN_MACRO, unsigned_immed16_overflow},
- {"cmple", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_CMPGE, OP_MASK_ROPX | OP_MASK_ROP, NIOS2_INSN_MACRO, no_overflow},
- {"cmplei", "t,s,i", "t,s,i,E", 3,
- OP_MATCH_CMPLTI, OP_MASK_IOP, NIOS2_INSN_MACRO, signed_immed16_overflow},
- {"cmpleu", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_CMPGEU, OP_MASK_ROPX | OP_MASK_ROP, NIOS2_INSN_MACRO, no_overflow},
- {"cmpleui", "t,s,u", "t,s,u,E", 3,
- OP_MATCH_CMPLTUI, OP_MASK_IOP, NIOS2_INSN_MACRO, unsigned_immed16_overflow},
- {"cmplt", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_CMPLT, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
- {"cmplti", "t,s,i", "t,s,i,E", 3,
- OP_MATCH_CMPLTI, OP_MASK_IOP, 0, signed_immed16_overflow},
- {"cmpltu", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_CMPLTU, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
- {"cmpltui", "t,s,u", "t,s,u,E", 3,
- OP_MATCH_CMPLTUI, OP_MASK_IOP, 0, unsigned_immed16_overflow},
- {"cmpne", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_CMPNE, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
- {"cmpnei", "t,s,i", "t,s,i,E", 3,
- OP_MATCH_CMPNEI, OP_MASK_IOP, 0, signed_immed16_overflow},
- {"div", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_DIV, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
- {"divu", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_DIVU, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
- {"jmp", "s", "s,E", 1,
- OP_MATCH_JMP, OP_MASK_JMP, 0, no_overflow},
- {"jmpi", "m", "m,E", 1,
- OP_MATCH_JMPI, OP_MASK_IOP, 0, no_overflow},
- {"ldb", "t,i(s)", "t,i(s)E", 3,
- OP_MATCH_LDB, OP_MASK_IOP, 0, address_offset_overflow},
- {"ldbio", "t,i(s)", "t,i(s)E", 3,
- OP_MATCH_LDBIO, OP_MASK_IOP, 0, address_offset_overflow},
- {"ldbu", "t,i(s)", "t,i(s)E", 3,
- OP_MATCH_LDBU, OP_MASK_IOP, 0, address_offset_overflow},
- {"ldbuio", "t,i(s)", "t,i(s)E", 3,
- OP_MATCH_LDBUIO, OP_MASK_IOP, 0, address_offset_overflow},
- {"ldh", "t,i(s)", "t,i(s)E", 3,
- OP_MATCH_LDH, OP_MASK_IOP, 0, address_offset_overflow},
- {"ldhio", "t,i(s)", "t,i(s)E", 3,
- OP_MATCH_LDHIO, OP_MASK_IOP, 0, address_offset_overflow},
- {"ldhu", "t,i(s)", "t,i(s)E", 3,
- OP_MATCH_LDHU, OP_MASK_IOP, 0, address_offset_overflow},
- {"ldhuio", "t,i(s)", "t,i(s)E", 3,
- OP_MATCH_LDHUIO, OP_MASK_IOP, 0, address_offset_overflow},
- {"ldl", "t,i(s)", "t,i(s)E", 3,
- OP_MATCH_LDL, OP_MASK_IOP, 0, address_offset_overflow},
- {"ldw", "t,i(s)", "t,i(s)E", 3,
- OP_MATCH_LDW, OP_MASK_IOP, 0, address_offset_overflow},
- {"ldwio", "t,i(s)", "t,i(s)E", 3,
- OP_MATCH_LDWIO, OP_MASK_IOP, 0, address_offset_overflow},
- {"mov", "d,s", "d,s,E", 2,
- OP_MATCH_ADD, OP_MASK_RRT|OP_MASK_ROPX|OP_MASK_ROP, NIOS2_INSN_MACRO_MOV,
- no_overflow},
- {"movhi", "t,u", "t,u,E", 2,
- OP_MATCH_ORHI, OP_MASK_IRS|OP_MASK_IOP, NIOS2_INSN_MACRO_MOVI,
- unsigned_immed16_overflow},
- {"movui", "t,u", "t,u,E", 2,
- OP_MATCH_ORI, OP_MASK_IRS|OP_MASK_IOP, NIOS2_INSN_MACRO_MOVI,
- unsigned_immed16_overflow},
- {"movi", "t,i", "t,i,E", 2,
- OP_MATCH_ADDI, OP_MASK_IRS|OP_MASK_IOP, NIOS2_INSN_MACRO_MOVI,
- signed_immed16_overflow},
- /* movia expands to two instructions so there is no mask or match */
- {"movia", "t,o", "t,o,E", 2,
- OP_MATCH_ORHI, OP_MASK_IOP, NIOS2_INSN_MACRO_MOVIA, no_overflow},
- {"mul", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_MUL, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
- {"muli", "t,s,i", "t,s,i,E", 3,
- OP_MATCH_MULI, OP_MASK_IOP, 0, signed_immed16_overflow},
- {"mulxss", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_MULXSS, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
- {"mulxsu", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_MULXSU, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
- {"mulxuu", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_MULXUU, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
- {"nextpc", "d", "d,E", 1,
- OP_MATCH_NEXTPC, OP_MASK_NEXTPC, 0, no_overflow},
- {"nop", "", "E", 0,
- OP_MATCH_ADD, OP_MASK, NIOS2_INSN_MACRO_MOV, no_overflow},
- {"nor", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_NOR, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
- {"or", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_OR, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
- {"orhi", "t,s,u", "t,s,u,E", 3,
- OP_MATCH_ORHI, OP_MASK_IOP, 0, unsigned_immed16_overflow},
- {"ori", "t,s,u", "t,s,u,E", 3,
- OP_MATCH_ORI, OP_MASK_IOP, NIOS2_INSN_ORI, unsigned_immed16_overflow},
- {"rdctl", "d,c", "d,c,E", 2,
- OP_MATCH_RDCTL, OP_MASK_RDCTL, 0, no_overflow},
- {"rdprs", "t,s,i", "t,s,i,E", 3,
- OP_MATCH_RDPRS, OP_MASK_IOP, 0, unsigned_immed16_overflow},
- {"ret", "", "E", 0,
- OP_MATCH_RET, OP_MASK, 0, no_overflow},
- {"rol", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_ROL, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
- {"roli", "d,s,j", "d,s,j,E", 3,
- OP_MATCH_ROLI, OP_MASK_ROLI, 0, unsigned_immed5_overflow},
- {"ror", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_ROR, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
- {"sll", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_SLL, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
- {"slli", "d,s,j", "d,s,j,E", 3,
- OP_MATCH_SLLI, OP_MASK_SLLI, 0, unsigned_immed5_overflow},
- {"sra", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_SRA, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
- {"srai", "d,s,j", "d,s,j,E", 3,
- OP_MATCH_SRAI, OP_MASK_SRAI, 0, unsigned_immed5_overflow},
- {"srl", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_SRL, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
- {"srli", "d,s,j", "d,s,j,E", 3,
- OP_MATCH_SRLI, OP_MASK_SRLI, 0, unsigned_immed5_overflow},
- {"stb", "t,i(s)", "t,i(s)E", 3,
- OP_MATCH_STB, OP_MASK_IOP, 0, address_offset_overflow},
- {"stbio", "t,i(s)", "t,i(s)E", 3,
- OP_MATCH_STBIO, OP_MASK_IOP, 0, address_offset_overflow},
- {"stc", "t,i(s)", "t,i(s)E", 3,
- OP_MATCH_STC, OP_MASK_IOP, 0, address_offset_overflow},
- {"sth", "t,i(s)", "t,i(s)E", 3,
- OP_MATCH_STH, OP_MASK_IOP, 0, address_offset_overflow},
- {"sthio", "t,i(s)", "t,i(s)E", 3,
- OP_MATCH_STHIO, OP_MASK_IOP, 0, address_offset_overflow},
- {"stw", "t,i(s)", "t,i(s)E", 3,
- OP_MATCH_STW, OP_MASK_IOP, 0, address_offset_overflow},
- {"stwio", "t,i(s)", "t,i(s)E", 3,
- OP_MATCH_STWIO, OP_MASK_IOP, 0, address_offset_overflow},
- {"sub", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_SUB, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
- {"sync", "", "E", 0,
- OP_MATCH_SYNC, OP_MASK_SYNC, 0, no_overflow},
- {"trap", "b", "b,E", 1,
- OP_MATCH_TRAP, OP_MASK_TRAP, 0, no_overflow},
- {"eret", "", "E", 0,
- OP_MATCH_ERET, OP_MASK, 0, no_overflow},
- {"custom", "l,d,s,t", "l,d,s,t,E", 4,
- OP_MATCH_CUSTOM, OP_MASK_ROP, 0, custom_opcode_overflow},
- {"wrctl", "c,s", "c,s,E", 2,
- OP_MATCH_WRCTL, OP_MASK_WRCTL, 0, no_overflow},
- {"wrprs", "d,s", "d,s,E", 2,
- OP_MATCH_WRPRS, OP_MASK_RRT|OP_MASK_ROPX|OP_MASK_ROP, 0, no_overflow},
- {"xor", "d,s,t", "d,s,t,E", 3,
- OP_MATCH_XOR, OP_MASK_ROPX | OP_MASK_ROP, 0, no_overflow},
- {"xorhi", "t,s,u", "t,s,u,E", 3,
- OP_MATCH_XORHI, OP_MASK_IOP, 0, unsigned_immed16_overflow},
- {"xori", "t,s,u", "t,s,u,E", 3,
- OP_MATCH_XORI, OP_MASK_IOP, NIOS2_INSN_XORI, unsigned_immed16_overflow}
+ /* { name, args, args_test, num_args, size, format,
+ match, mask, pinfo, overflow } */
+ {"add", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_ADD, MASK_R1_ADD, 0, no_overflow},
+ {"addi", "t,s,i", "t,s,i,E", 3, 4, iw_i_type,
+ MATCH_R1_ADDI, MASK_R1_ADDI, NIOS2_INSN_ADDI, signed_immed16_overflow},
+ {"and", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_AND, MASK_R1_AND, 0, no_overflow},
+ {"andhi", "t,s,u", "t,s,u,E", 3, 4, iw_i_type,
+ MATCH_R1_ANDHI, MASK_R1_ANDHI, 0, unsigned_immed16_overflow},
+ {"andi", "t,s,u", "t,s,u,E", 3, 4, iw_i_type,
+ MATCH_R1_ANDI, MASK_R1_ANDI, NIOS2_INSN_ANDI, unsigned_immed16_overflow},
+ {"beq", "s,t,o", "s,t,o,E", 3, 4, iw_i_type,
+ MATCH_R1_BEQ, MASK_R1_BEQ, NIOS2_INSN_CBRANCH, branch_target_overflow},
+ {"bge", "s,t,o", "s,t,o,E", 3, 4, iw_i_type,
+ MATCH_R1_BGE, MASK_R1_BGE, NIOS2_INSN_CBRANCH, branch_target_overflow},
+ {"bgeu", "s,t,o", "s,t,o,E", 3, 4, iw_i_type,
+ MATCH_R1_BGEU, MASK_R1_BGEU, NIOS2_INSN_CBRANCH, branch_target_overflow},
+ {"bgt", "s,t,o", "s,t,o,E", 3, 4, iw_i_type,
+ MATCH_R1_BGT, MASK_R1_BGT,
+ NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH, branch_target_overflow},
+ {"bgtu", "s,t,o", "s,t,o,E", 3, 4, iw_i_type,
+ MATCH_R1_BGTU, MASK_R1_BGTU,
+ NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH, branch_target_overflow},
+ {"ble", "s,t,o", "s,t,o,E", 3, 4, iw_i_type,
+ MATCH_R1_BLE, MASK_R1_BLE,
+ NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH, branch_target_overflow},
+ {"bleu", "s,t,o", "s,t,o,E", 3, 4, iw_i_type,
+ MATCH_R1_BLEU, MASK_R1_BLEU,
+ NIOS2_INSN_MACRO|NIOS2_INSN_CBRANCH, branch_target_overflow},
+ {"blt", "s,t,o", "s,t,o,E", 3, 4, iw_i_type,
+ MATCH_R1_BLT, MASK_R1_BLT, NIOS2_INSN_CBRANCH, branch_target_overflow},
+ {"bltu", "s,t,o", "s,t,o,E", 3, 4, iw_i_type,
+ MATCH_R1_BLTU, MASK_R1_BLTU, NIOS2_INSN_CBRANCH, branch_target_overflow},
+ {"bne", "s,t,o", "s,t,o,E", 3, 4, iw_i_type,
+ MATCH_R1_BNE, MASK_R1_BNE, NIOS2_INSN_CBRANCH, branch_target_overflow},
+ {"br", "o", "o,E", 1, 4, iw_i_type,
+ MATCH_R1_BR, MASK_R1_BR, NIOS2_INSN_UBRANCH, branch_target_overflow},
+ {"break", "j", "j,E", 1, 4, iw_r_type,
+ MATCH_R1_BREAK, MASK_R1_BREAK, NIOS2_INSN_OPTARG, no_overflow},
+ {"bret", "", "E", 0, 4, iw_r_type,
+ MATCH_R1_BRET, MASK_R1_BRET, 0, no_overflow},
+ {"call", "m", "m,E", 1, 4, iw_j_type,
+ MATCH_R1_CALL, MASK_R1_CALL, NIOS2_INSN_CALL, call_target_overflow},
+ {"callr", "s", "s,E", 1, 4, iw_r_type,
+ MATCH_R1_CALLR, MASK_R1_CALLR, 0, no_overflow},
+ {"cmpeq", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_CMPEQ, MASK_R1_CMPEQ, 0, no_overflow},
+ {"cmpeqi", "t,s,i", "t,s,i,E", 3, 4, iw_i_type,
+ MATCH_R1_CMPEQI, MASK_R1_CMPEQI, 0, signed_immed16_overflow},
+ {"cmpge", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_CMPGE, MASK_R1_CMPGE, 0, no_overflow},
+ {"cmpgei", "t,s,i", "t,s,i,E", 3, 4, iw_i_type,
+ MATCH_R1_CMPGEI, MASK_R1_CMPGEI, 0, signed_immed16_overflow},
+ {"cmpgeu", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_CMPGEU, MASK_R1_CMPGEU, 0, no_overflow},
+ {"cmpgeui", "t,s,u", "t,s,u,E", 3, 4, iw_i_type,
+ MATCH_R1_CMPGEUI, MASK_R1_CMPGEUI, 0, unsigned_immed16_overflow},
+ {"cmpgt", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_CMPGT, MASK_R1_CMPGT, NIOS2_INSN_MACRO, no_overflow},
+ {"cmpgti", "t,s,i", "t,s,i,E", 3, 4, iw_i_type,
+ MATCH_R1_CMPGTI, MASK_R1_CMPGTI, NIOS2_INSN_MACRO, signed_immed16_overflow},
+ {"cmpgtu", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_CMPGTU, MASK_R1_CMPGTU, NIOS2_INSN_MACRO, no_overflow},
+ {"cmpgtui", "t,s,u", "t,s,u,E", 3, 4, iw_i_type,
+ MATCH_R1_CMPGTUI, MASK_R1_CMPGTUI,
+ NIOS2_INSN_MACRO, unsigned_immed16_overflow},
+ {"cmple", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_CMPLE, MASK_R1_CMPLE, NIOS2_INSN_MACRO, no_overflow},
+ {"cmplei", "t,s,i", "t,s,i,E", 3, 4, iw_i_type,
+ MATCH_R1_CMPLEI, MASK_R1_CMPLEI, NIOS2_INSN_MACRO, signed_immed16_overflow},
+ {"cmpleu", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_CMPLEU, MASK_R1_CMPLEU, NIOS2_INSN_MACRO, no_overflow},
+ {"cmpleui", "t,s,u", "t,s,u,E", 3, 4, iw_i_type,
+ MATCH_R1_CMPLEUI, MASK_R1_CMPLEUI,
+ NIOS2_INSN_MACRO, unsigned_immed16_overflow},
+ {"cmplt", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_CMPLT, MASK_R1_CMPLT, 0, no_overflow},
+ {"cmplti", "t,s,i", "t,s,i,E", 3, 4, iw_i_type,
+ MATCH_R1_CMPLTI, MASK_R1_CMPLTI, 0, signed_immed16_overflow},
+ {"cmpltu", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_CMPLTU, MASK_R1_CMPLTU, 0, no_overflow},
+ {"cmpltui", "t,s,u", "t,s,u,E", 3, 4, iw_i_type,
+ MATCH_R1_CMPLTUI, MASK_R1_CMPLTUI, 0, unsigned_immed16_overflow},
+ {"cmpne", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_CMPNE, MASK_R1_CMPNE, 0, no_overflow},
+ {"cmpnei", "t,s,i", "t,s,i,E", 3, 4, iw_i_type,
+ MATCH_R1_CMPNEI, MASK_R1_CMPNEI, 0, signed_immed16_overflow},
+ {"custom", "l,d,s,t", "l,d,s,t,E", 4, 4, iw_custom_type,
+ MATCH_R1_CUSTOM, MASK_R1_CUSTOM, 0, custom_opcode_overflow},
+ {"div", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_DIV, MASK_R1_DIV, 0, no_overflow},
+ {"divu", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_DIVU, MASK_R1_DIVU, 0, no_overflow},
+ {"eret", "", "E", 0, 4, iw_r_type,
+ MATCH_R1_ERET, MASK_R1_ERET, 0, no_overflow},
+ {"flushd", "i(s)", "i(s),E", 2, 4, iw_i_type,
+ MATCH_R1_FLUSHD, MASK_R1_FLUSHD, 0, address_offset_overflow},
+ {"flushda", "i(s)", "i(s),E", 2, 4, iw_i_type,
+ MATCH_R1_FLUSHDA, MASK_R1_FLUSHDA, 0, address_offset_overflow},
+ {"flushi", "s", "s,E", 1, 4, iw_r_type,
+ MATCH_R1_FLUSHI, MASK_R1_FLUSHI, 0, no_overflow},
+ {"flushp", "", "E", 0, 4, iw_r_type,
+ MATCH_R1_FLUSHP, MASK_R1_FLUSHP, 0, no_overflow},
+ {"initd", "i(s)", "i(s),E", 2, 4, iw_i_type,
+ MATCH_R1_INITD, MASK_R1_INITD, 0, address_offset_overflow},
+ {"initda", "i(s)", "i(s),E", 2, 4, iw_i_type,
+ MATCH_R1_INITDA, MASK_R1_INITDA, 0, address_offset_overflow},
+ {"initi", "s", "s,E", 1, 4, iw_r_type,
+ MATCH_R1_INITI, MASK_R1_INITI, 0, no_overflow},
+ {"jmp", "s", "s,E", 1, 4, iw_r_type,
+ MATCH_R1_JMP, MASK_R1_JMP, 0, no_overflow},
+ {"jmpi", "m", "m,E", 1, 4, iw_j_type,
+ MATCH_R1_JMPI, MASK_R1_JMPI, 0, call_target_overflow},
+ {"ldb", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+ MATCH_R1_LDB, MASK_R1_LDB, 0, address_offset_overflow},
+ {"ldbio", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+ MATCH_R1_LDBIO, MASK_R1_LDBIO, 0, address_offset_overflow},
+ {"ldbu", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+ MATCH_R1_LDBU, MASK_R1_LDBU, 0, address_offset_overflow},
+ {"ldbuio", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+ MATCH_R1_LDBUIO, MASK_R1_LDBUIO, 0, address_offset_overflow},
+ {"ldh", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+ MATCH_R1_LDH, MASK_R1_LDH, 0, address_offset_overflow},
+ {"ldhio", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+ MATCH_R1_LDHIO, MASK_R1_LDHIO, 0, address_offset_overflow},
+ {"ldhu", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+ MATCH_R1_LDHU, MASK_R1_LDHU, 0, address_offset_overflow},
+ {"ldhuio", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+ MATCH_R1_LDHUIO, MASK_R1_LDHUIO, 0, address_offset_overflow},
+ {"ldw", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+ MATCH_R1_LDW, MASK_R1_LDW, 0, address_offset_overflow},
+ {"ldwio", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+ MATCH_R1_LDWIO, MASK_R1_LDWIO, 0, address_offset_overflow},
+ {"mov", "d,s", "d,s,E", 2, 4, iw_r_type,
+ MATCH_R1_MOV, MASK_R1_MOV, NIOS2_INSN_MACRO_MOV, no_overflow},
+ {"movhi", "t,u", "t,u,E", 2, 4, iw_i_type,
+ MATCH_R1_MOVHI, MASK_R1_MOVHI,
+ NIOS2_INSN_MACRO_MOVI, unsigned_immed16_overflow},
+ {"movi", "t,i", "t,i,E", 2, 4, iw_i_type,
+ MATCH_R1_MOVI, MASK_R1_MOVI, NIOS2_INSN_MACRO_MOVI, signed_immed16_overflow},
+ {"movia", "t,o", "t,o,E", 2, 4, iw_i_type,
+ MATCH_R1_ORHI, MASK_R1_ORHI, NIOS2_INSN_MACRO_MOVIA, no_overflow},
+ {"movui", "t,u", "t,u,E", 2, 4, iw_i_type,
+ MATCH_R1_MOVUI, MASK_R1_MOVUI,
+ NIOS2_INSN_MACRO_MOVI, unsigned_immed16_overflow},
+ {"mul", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_MUL, MASK_R1_MUL, 0, no_overflow},
+ {"muli", "t,s,i", "t,s,i,E", 3, 4, iw_i_type,
+ MATCH_R1_MULI, MASK_R1_MULI, 0, signed_immed16_overflow},
+ {"mulxss", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_MULXSS, MASK_R1_MULXSS, 0, no_overflow},
+ {"mulxsu", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_MULXSU, MASK_R1_MULXSU, 0, no_overflow},
+ {"mulxuu", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_MULXUU, MASK_R1_MULXUU, 0, no_overflow},
+ {"nextpc", "d", "d,E", 1, 4, iw_r_type,
+ MATCH_R1_NEXTPC, MASK_R1_NEXTPC, 0, no_overflow},
+ {"nop", "", "E", 0, 4, iw_r_type,
+ MATCH_R1_NOP, MASK_R1_NOP, NIOS2_INSN_MACRO_MOV, no_overflow},
+ {"nor", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_NOR, MASK_R1_NOR, 0, no_overflow},
+ {"or", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_OR, MASK_R1_OR, 0, no_overflow},
+ {"orhi", "t,s,u", "t,s,u,E", 3, 4, iw_i_type,
+ MATCH_R1_ORHI, MASK_R1_ORHI, 0, unsigned_immed16_overflow},
+ {"ori", "t,s,u", "t,s,u,E", 3, 4, iw_i_type,
+ MATCH_R1_ORI, MASK_R1_ORI, NIOS2_INSN_ORI, unsigned_immed16_overflow},
+ {"rdctl", "d,c", "d,c,E", 2, 4, iw_r_type,
+ MATCH_R1_RDCTL, MASK_R1_RDCTL, 0, no_overflow},
+ {"rdprs", "t,s,i", "t,s,i,E", 3, 4, iw_i_type,
+ MATCH_R1_RDPRS, MASK_R1_RDPRS, 0, signed_immed16_overflow},
+ {"ret", "", "E", 0, 4, iw_r_type,
+ MATCH_R1_RET, MASK_R1_RET, 0, no_overflow},
+ {"rol", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_ROL, MASK_R1_ROL, 0, no_overflow},
+ {"roli", "d,s,j", "d,s,j,E", 3, 4, iw_r_type,
+ MATCH_R1_ROLI, MASK_R1_ROLI, 0, unsigned_immed5_overflow},
+ {"ror", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_ROR, MASK_R1_ROR, 0, no_overflow},
+ {"sll", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_SLL, MASK_R1_SLL, 0, no_overflow},
+ {"slli", "d,s,j", "d,s,j,E", 3, 4, iw_r_type,
+ MATCH_R1_SLLI, MASK_R1_SLLI, 0, unsigned_immed5_overflow},
+ {"sra", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_SRA, MASK_R1_SRA, 0, no_overflow},
+ {"srai", "d,s,j", "d,s,j,E", 3, 4, iw_r_type,
+ MATCH_R1_SRAI, MASK_R1_SRAI, 0, unsigned_immed5_overflow},
+ {"srl", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_SRL, MASK_R1_SRL, 0, no_overflow},
+ {"srli", "d,s,j", "d,s,j,E", 3, 4, iw_r_type,
+ MATCH_R1_SRLI, MASK_R1_SRLI, 0, unsigned_immed5_overflow},
+ {"stb", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+ MATCH_R1_STB, MASK_R1_STB, 0, address_offset_overflow},
+ {"stbio", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+ MATCH_R1_STBIO, MASK_R1_STBIO, 0, address_offset_overflow},
+ {"sth", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+ MATCH_R1_STH, MASK_R1_STH, 0, address_offset_overflow},
+ {"sthio", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+ MATCH_R1_STHIO, MASK_R1_STHIO, 0, address_offset_overflow},
+ {"stw", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+ MATCH_R1_STW, MASK_R1_STW, 0, address_offset_overflow},
+ {"stwio", "t,i(s)", "t,i(s),E", 3, 4, iw_i_type,
+ MATCH_R1_STWIO, MASK_R1_STWIO, 0, address_offset_overflow},
+ {"sub", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_SUB, MASK_R1_SUB, 0, no_overflow},
+ {"subi", "t,s,i", "t,s,i,E", 3, 4, iw_i_type,
+ MATCH_R1_SUBI, MASK_R1_SUBI, NIOS2_INSN_MACRO, signed_immed16_overflow},
+ {"sync", "", "E", 0, 4, iw_r_type,
+ MATCH_R1_SYNC, MASK_R1_SYNC, 0, no_overflow},
+ {"trap", "j", "j,E", 1, 4, iw_r_type,
+ MATCH_R1_TRAP, MASK_R1_TRAP, NIOS2_INSN_OPTARG, no_overflow},
+ {"wrctl", "c,s", "c,s,E", 2, 4, iw_r_type,
+ MATCH_R1_WRCTL, MASK_R1_WRCTL, 0, no_overflow},
+ {"wrprs", "d,s", "d,s,E", 2, 4, iw_r_type,
+ MATCH_R1_WRPRS, MASK_R1_WRPRS, 0, no_overflow},
+ {"xor", "d,s,t", "d,s,t,E", 3, 4, iw_r_type,
+ MATCH_R1_XOR, MASK_R1_XOR, 0, no_overflow},
+ {"xorhi", "t,s,u", "t,s,u,E", 3, 4, iw_i_type,
+ MATCH_R1_XORHI, MASK_R1_XORHI, 0, unsigned_immed16_overflow},
+ {"xori", "t,s,u", "t,s,u,E", 3, 4, iw_i_type,
+ MATCH_R1_XORI, MASK_R1_XORI, NIOS2_INSN_XORI, unsigned_immed16_overflow}
};
#define NIOS2_NUM_OPCODES \
- ((sizeof nios2_builtin_opcodes) / (sizeof (nios2_builtin_opcodes[0])))
-const int bfd_nios2_num_builtin_opcodes = NIOS2_NUM_OPCODES;
+ ((sizeof nios2_r1_opcodes) / (sizeof (nios2_r1_opcodes[0])))
+const int nios2_num_r1_opcodes = NIOS2_NUM_OPCODES;
-/* This is not const to allow for dynamic extensions to the
- built-in instruction set. */
-struct nios2_opcode *nios2_opcodes =
- (struct nios2_opcode *) nios2_builtin_opcodes;
-int bfd_nios2_num_opcodes = NIOS2_NUM_OPCODES;
+struct nios2_opcode *nios2_opcodes = (struct nios2_opcode *) nios2_r1_opcodes;
+int nios2_num_opcodes = NIOS2_NUM_OPCODES;
#undef NIOS2_NUM_OPCODES