Refactoring/cleanup of nios2 opcodes and assembler code.
authorSandra Loosemore <sandra@codesourcery.com>
Thu, 23 Oct 2014 16:54:15 +0000 (09:54 -0700)
committerSandra Loosemore <sandra@codesourcery.com>
Thu, 23 Oct 2014 16:54:15 +0000 (09:54 -0700)
2014-10-23  Sandra Loosemore  <sandra@codesourcery.com>

include/opcode/
* 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.

opcodes/
* 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.

gas/
* 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.

gdb/
* nios2-tdep.c (nios2_analyze_prologue): Use new instruction field
accessors and constants from nios2 opcodes update.
(nios2_get_next_pc): Likewise.

gas/ChangeLog
gas/config/tc-nios2.c
gdb/ChangeLog
gdb/nios2-tdep.c
include/opcode/ChangeLog
include/opcode/nios2.h
include/opcode/nios2r1.h [new file with mode: 0644]
opcodes/ChangeLog
opcodes/nios2-dis.c
opcodes/nios2-opc.c

index 3a82302..a664eab 100644 (file)
@@ -1,3 +1,64 @@
+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.
index 21f4288..3ed7a9e 100644 (file)
@@ -139,6 +139,10 @@ typedef struct nios2_insn_info
 {
   /* 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
@@ -152,15 +156,6 @@ typedef struct nios2_insn_info
   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.  */
@@ -196,10 +191,6 @@ static struct hash_control *nios2_reg_hash = NULL;
 #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;
@@ -303,27 +294,6 @@ md_atof (int type, char *litP, int *sizeP)
 #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
@@ -345,24 +315,6 @@ nios2_special_relocation_p (const char *str)
          || 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 };
@@ -816,9 +768,9 @@ nios2_relax_frag (segT segment, fragS *fragp, long stretch)
            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;
@@ -902,6 +854,7 @@ md_convert_frag (bfd *headers ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED,
   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
@@ -912,25 +865,26 @@ md_convert_frag (bfd *headers ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED,
        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,
@@ -938,7 +892,8 @@ md_convert_frag (bfd *headers ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED,
          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;
@@ -949,7 +904,7 @@ md_convert_frag (bfd *headers ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED,
     {
       /* 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;
   
@@ -960,12 +915,12 @@ md_convert_frag (bfd *headers ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED,
        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);
@@ -976,7 +931,7 @@ md_convert_frag (bfd *headers ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED,
       /* 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;
@@ -985,12 +940,18 @@ md_convert_frag (bfd *headers ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED,
   /* 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;
@@ -998,7 +959,7 @@ md_convert_frag (bfd *headers ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED,
     }
 
   /* 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;
 }
@@ -1071,9 +1032,10 @@ nios2_diagnose_overflow (valueT fixup, reloc_howto_type *howto,
       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)
        {
@@ -1240,7 +1202,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
             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;
@@ -1297,6 +1260,16 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 \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
@@ -1363,6 +1336,54 @@ nios2_insn_reloc_destroy (nios2_insn_relocS *reloc)
 }
 #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.
@@ -1371,7 +1392,6 @@ nios2_insn_reloc_destroy (nios2_insn_relocS *reloc)
 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)
 {
@@ -1407,10 +1427,8 @@ nios2_assemble_expression (const char *exprstr,
 
   /* 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;
@@ -1429,480 +1447,310 @@ nios2_assemble_expression (const char *exprstr,
   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
@@ -1911,73 +1759,18 @@ const int nios2_num_arg_info_structs = NIOS2_NUM_ARGS;
    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 == '%')
@@ -2000,7 +1793,6 @@ nios2_consume_arg (nios2_insn_infoS *insn, char *argstr, const char *parsestr)
     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);
@@ -2038,8 +1830,6 @@ nios2_consume_separator (char *argstr, const char *separator)
 
   if (p != NULL)
     *p++ = 0;
-  else
-    as_bad (_("expecting %c near %s"), *separator, argstr);
   return p;
 }
 
@@ -2069,23 +1859,25 @@ nios2_parse_args (nios2_insn_infoS *insn, char *argstr,
   
   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"));
        }
@@ -2096,13 +1888,6 @@ nios2_parse_args (nios2_insn_infoS *insn, char *argstr,
     }
 
   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"));
 }
 
 
@@ -2310,17 +2095,18 @@ static void
 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);
 }
@@ -2346,10 +2132,10 @@ output_ubranch (nios2_insn_infoS *insn)
         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.  */
     }
@@ -2376,10 +2162,10 @@ output_cbranch (nios2_insn_infoS *insn)
         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.  */
     }
@@ -2399,15 +2185,21 @@ output_call (nios2_insn_infoS *insn)
   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);
 }
 
@@ -2419,14 +2211,18 @@ output_addi (nios2_insn_infoS *insn)
   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;
        }
     }
@@ -2443,10 +2239,14 @@ output_andi (nios2_insn_infoS *insn)
       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;
        }
     }
@@ -2463,10 +2263,14 @@ output_ori (nios2_insn_infoS *insn)
       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;
        }
     }
@@ -2483,10 +2287,14 @@ output_xori (nios2_insn_infoS *insn)
       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;
        }
     }
@@ -2504,22 +2312,22 @@ output_movia (nios2_insn_infoS *insn)
      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);
@@ -2599,10 +2407,9 @@ md_begin (void)
      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,
@@ -2631,20 +2438,6 @@ md_begin (void)
 
     }
 
-  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
@@ -2680,7 +2473,6 @@ md_assemble (char *op_str)
 {
   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;
@@ -2707,6 +2499,7 @@ md_assemble (char *op_str)
       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)
@@ -2726,53 +2519,41 @@ md_assemble (char *op_str)
          == 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.  */
index 76957c4..370a7ad 100644 (file)
@@ -1,3 +1,9 @@
+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.
index 18a5913..69cefac 100644 (file)
@@ -558,13 +558,13 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
 
       /* 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
@@ -609,13 +609,13 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
          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)
            {
@@ -627,12 +627,12 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
            }
        }
 
-      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
@@ -651,12 +651,12 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
          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)
            {
@@ -665,14 +665,14 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
            }
        }
 
-      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
@@ -693,8 +693,7 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
                    {
                      /* 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;
@@ -709,11 +708,11 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
            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)
            {
@@ -724,7 +723,7 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
          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
@@ -779,24 +778,24 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
         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:
@@ -1372,65 +1371,65 @@ nios2_get_next_pc (struct frame_info *frame, CORE_ADDR pc)
   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);
 
index a8b6229..be122b6 100644 (file)
@@ -1,3 +1,53 @@
+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.
index 04beff9..dc0e058 100644 (file)
  * 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
 {
@@ -56,12 +65,14 @@ 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.
@@ -84,6 +95,8 @@ struct nios2_opcode
                                   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.  */
@@ -112,398 +125,28 @@ struct nios2_opcode
 #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[];
@@ -511,10 +154,6 @@ extern struct nios2_reg *nios2_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);
diff --git a/include/opcode/nios2r1.h b/include/opcode/nios2r1.h
new file mode 100644 (file)
index 0000000..32a517d
--- /dev/null
@@ -0,0 +1,474 @@
+/* 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 */
index 49fc81d..1841df4 100644 (file)
@@ -1,3 +1,27 @@
+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.
index b5c680f..00ee342 100644 (file)
@@ -35,7 +35,7 @@
 #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.  */
@@ -45,36 +45,66 @@ typedef struct _nios2_opcode_hash
   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)
          {
@@ -93,11 +123,12 @@ nios2_init_opcode_hash (void)
            *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)
        {
@@ -107,9 +138,9 @@ nios2_init_opcode_hash (void)
       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)
        {
@@ -127,19 +158,27 @@ const struct nios2_opcode *
 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;
@@ -191,13 +230,23 @@ nios2_control_regs (void)
   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;
@@ -209,98 +258,180 @@ nios2_print_insn_arg (const char *argptr,
     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;
@@ -332,46 +463,28 @@ nios2_disassemble (bfd_vma address, unsigned long opcode,
 
   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;
 }
 
 
index 47a7ee4..a12a2f8 100644 (file)
 
 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 \
@@ -172,244 +172,236 @@ int nios2_num_regs = 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