+/* Read and identify an instruction at PC. If INSNP is non-null,
+ store the instruction word into that location. Return the opcode
+ pointer or NULL if the memory couldn't be read or disassembled. */
+
+static const struct nios2_opcode *
+nios2_fetch_insn (struct gdbarch *gdbarch, CORE_ADDR pc,
+ unsigned int *insnp)
+{
+ LONGEST memword;
+ unsigned long mach = gdbarch_bfd_arch_info (gdbarch)->mach;
+ unsigned int insn;
+
+ if (mach == bfd_mach_nios2r2)
+ {
+ if (!safe_read_memory_integer (pc, NIOS2_OPCODE_SIZE,
+ BFD_ENDIAN_LITTLE, &memword)
+ && !safe_read_memory_integer (pc, NIOS2_CDX_OPCODE_SIZE,
+ BFD_ENDIAN_LITTLE, &memword))
+ return NULL;
+ }
+ else if (!safe_read_memory_integer (pc, NIOS2_OPCODE_SIZE,
+ gdbarch_byte_order (gdbarch), &memword))
+ return NULL;
+
+ insn = (unsigned int) memword;
+ if (insnp)
+ *insnp = insn;
+ return nios2_find_opcode_hash (insn, mach);
+}
+
+
+/* Match and disassemble an ADD-type instruction, with 3 register operands.
+ Returns true on success, and fills in the operand pointers. */
+
+static int
+nios2_match_add (uint32_t insn, const struct nios2_opcode *op,
+ unsigned long mach, int *ra, int *rb, int *rc)
+{
+ int is_r2 = (mach == bfd_mach_nios2r2);
+
+ if (!is_r2 && (op->match == MATCH_R1_ADD || op->match == MATCH_R1_MOV))
+ {
+ *ra = GET_IW_R_A (insn);
+ *rb = GET_IW_R_B (insn);
+ *rc = GET_IW_R_C (insn);
+ return 1;
+ }
+ else if (!is_r2)
+ return 0;
+ else if (op->match == MATCH_R2_ADD || op->match == MATCH_R2_MOV)
+ {
+ *ra = GET_IW_F3X6L5_A (insn);
+ *rb = GET_IW_F3X6L5_B (insn);
+ *rc = GET_IW_F3X6L5_C (insn);
+ return 1;
+ }
+ else if (op->match == MATCH_R2_ADD_N)
+ {
+ *ra = nios2_r2_reg3_mappings[GET_IW_T3X1_A3 (insn)];
+ *rb = nios2_r2_reg3_mappings[GET_IW_T3X1_B3 (insn)];
+ *rc = nios2_r2_reg3_mappings[GET_IW_T3X1_C3 (insn)];
+ return 1;
+ }
+ else if (op->match == MATCH_R2_MOV_N)
+ {
+ *ra = GET_IW_F2_A (insn);
+ *rb = 0;
+ *rc = GET_IW_F2_B (insn);
+ return 1;
+ }
+ return 0;
+}
+
+/* Match and disassemble a SUB-type instruction, with 3 register operands.
+ Returns true on success, and fills in the operand pointers. */
+
+static int
+nios2_match_sub (uint32_t insn, const struct nios2_opcode *op,
+ unsigned long mach, int *ra, int *rb, int *rc)
+{
+ int is_r2 = (mach == bfd_mach_nios2r2);
+
+ if (!is_r2 && op->match == MATCH_R1_SUB)
+ {
+ *ra = GET_IW_R_A (insn);
+ *rb = GET_IW_R_B (insn);
+ *rc = GET_IW_R_C (insn);
+ return 1;
+ }
+ else if (!is_r2)
+ return 0;
+ else if (op->match == MATCH_R2_SUB)
+ {
+ *ra = GET_IW_F3X6L5_A (insn);
+ *rb = GET_IW_F3X6L5_B (insn);
+ *rc = GET_IW_F3X6L5_C (insn);
+ return 1;
+ }
+ else if (op->match == MATCH_R2_SUB_N)
+ {
+ *ra = nios2_r2_reg3_mappings[GET_IW_T3X1_A3 (insn)];
+ *rb = nios2_r2_reg3_mappings[GET_IW_T3X1_B3 (insn)];
+ *rc = nios2_r2_reg3_mappings[GET_IW_T3X1_C3 (insn)];
+ return 1;
+ }
+ return 0;
+}
+
+/* Match and disassemble an ADDI-type instruction, with 2 register operands
+ and one immediate operand.
+ Returns true on success, and fills in the operand pointers. */
+
+static int
+nios2_match_addi (uint32_t insn, const struct nios2_opcode *op,
+ unsigned long mach, int *ra, int *rb, int *imm)
+{
+ int is_r2 = (mach == bfd_mach_nios2r2);
+
+ if (!is_r2 && op->match == MATCH_R1_ADDI)
+ {
+ *ra = GET_IW_I_A (insn);
+ *rb = GET_IW_I_B (insn);
+ *imm = (signed) (GET_IW_I_IMM16 (insn) << 16) >> 16;
+ return 1;
+ }
+ else if (!is_r2)
+ return 0;
+ else if (op->match == MATCH_R2_ADDI)
+ {
+ *ra = GET_IW_F2I16_A (insn);
+ *rb = GET_IW_F2I16_B (insn);
+ *imm = (signed) (GET_IW_F2I16_IMM16 (insn) << 16) >> 16;
+ return 1;
+ }
+ else if (op->match == MATCH_R2_ADDI_N || op->match == MATCH_R2_SUBI_N)
+ {
+ *ra = nios2_r2_reg3_mappings[GET_IW_T2X1I3_A3 (insn)];
+ *rb = nios2_r2_reg3_mappings[GET_IW_T2X1I3_B3 (insn)];
+ *imm = nios2_r2_asi_n_mappings[GET_IW_T2X1I3_IMM3 (insn)];
+ if (op->match == MATCH_R2_SUBI_N)
+ *imm = - (*imm);
+ return 1;
+ }
+ else if (op->match == MATCH_R2_SPADDI_N)
+ {
+ *ra = nios2_r2_reg3_mappings[GET_IW_T1I7_A3 (insn)];
+ *rb = NIOS2_SP_REGNUM;
+ *imm = GET_IW_T1I7_IMM7 (insn) << 2;
+ return 1;
+ }
+ else if (op->match == MATCH_R2_SPINCI_N || op->match == MATCH_R2_SPDECI_N)
+ {
+ *ra = NIOS2_SP_REGNUM;
+ *rb = NIOS2_SP_REGNUM;
+ *imm = GET_IW_X1I7_IMM7 (insn) << 2;
+ if (op->match == MATCH_R2_SPDECI_N)
+ *imm = - (*imm);
+ return 1;
+ }
+ return 0;
+}
+
+/* Match and disassemble an ORHI-type instruction, with 2 register operands
+ and one unsigned immediate operand.
+ Returns true on success, and fills in the operand pointers. */
+
+static int
+nios2_match_orhi (uint32_t insn, const struct nios2_opcode *op,
+ unsigned long mach, int *ra, int *rb, unsigned int *uimm)
+{
+ int is_r2 = (mach == bfd_mach_nios2r2);
+
+ if (!is_r2 && op->match == MATCH_R1_ORHI)
+ {
+ *ra = GET_IW_I_A (insn);
+ *rb = GET_IW_I_B (insn);
+ *uimm = GET_IW_I_IMM16 (insn);
+ return 1;
+ }
+ else if (!is_r2)
+ return 0;
+ else if (op->match == MATCH_R2_ORHI)
+ {
+ *ra = GET_IW_F2I16_A (insn);
+ *rb = GET_IW_F2I16_B (insn);
+ *uimm = GET_IW_F2I16_IMM16 (insn);
+ return 1;
+ }
+ return 0;
+}
+
+/* Match and disassemble a STW-type instruction, with 2 register operands
+ and one immediate operand.
+ Returns true on success, and fills in the operand pointers. */
+
+static int
+nios2_match_stw (uint32_t insn, const struct nios2_opcode *op,
+ unsigned long mach, int *ra, int *rb, int *imm)
+{
+ int is_r2 = (mach == bfd_mach_nios2r2);
+
+ if (!is_r2 && (op->match == MATCH_R1_STW || op->match == MATCH_R1_STWIO))
+ {
+ *ra = GET_IW_I_A (insn);
+ *rb = GET_IW_I_B (insn);
+ *imm = (signed) (GET_IW_I_IMM16 (insn) << 16) >> 16;
+ return 1;
+ }
+ else if (!is_r2)
+ return 0;
+ else if (op->match == MATCH_R2_STW)
+ {
+ *ra = GET_IW_F2I16_A (insn);
+ *rb = GET_IW_F2I16_B (insn);
+ *imm = (signed) (GET_IW_F2I16_IMM16 (insn) << 16) >> 16;
+ return 1;
+ }
+ else if (op->match == MATCH_R2_STWIO)
+ {
+ *ra = GET_IW_F2X4I12_A (insn);
+ *rb = GET_IW_F2X4I12_B (insn);
+ *imm = (signed) (GET_IW_F2X4I12_IMM12 (insn) << 20) >> 20;
+ return 1;
+ }
+ else if (op->match == MATCH_R2_STW_N)
+ {
+ *ra = nios2_r2_reg3_mappings[GET_IW_T2I4_A3 (insn)];
+ *rb = nios2_r2_reg3_mappings[GET_IW_T2I4_B3 (insn)];
+ *imm = GET_IW_T2I4_IMM4 (insn) << 2;
+ return 1;
+ }
+ else if (op->match == MATCH_R2_STWSP_N)
+ {
+ *ra = NIOS2_SP_REGNUM;
+ *rb = GET_IW_F1I5_B (insn);
+ *imm = GET_IW_F1I5_IMM5 (insn) << 2;
+ return 1;
+ }
+ else if (op->match == MATCH_R2_STWZ_N)
+ {
+ *ra = nios2_r2_reg3_mappings[GET_IW_T1X1I6_A3 (insn)];
+ *rb = 0;
+ *imm = GET_IW_T1X1I6_IMM6 (insn) << 2;
+ return 1;
+ }
+ return 0;
+}
+
+/* Match and disassemble a LDW-type instruction, with 2 register operands
+ and one immediate operand.
+ Returns true on success, and fills in the operand pointers. */
+
+static int
+nios2_match_ldw (uint32_t insn, const struct nios2_opcode *op,
+ unsigned long mach, int *ra, int *rb, int *imm)
+{
+ int is_r2 = (mach == bfd_mach_nios2r2);
+
+ if (!is_r2 && (op->match == MATCH_R1_LDW || op->match == MATCH_R1_LDWIO))
+ {
+ *ra = GET_IW_I_A (insn);
+ *rb = GET_IW_I_B (insn);
+ *imm = (signed) (GET_IW_I_IMM16 (insn) << 16) >> 16;
+ return 1;
+ }
+ else if (!is_r2)
+ return 0;
+ else if (op->match == MATCH_R2_LDW)
+ {
+ *ra = GET_IW_F2I16_A (insn);
+ *rb = GET_IW_F2I16_B (insn);
+ *imm = (signed) (GET_IW_F2I16_IMM16 (insn) << 16) >> 16;
+ return 1;
+ }
+ else if (op->match == MATCH_R2_LDWIO)
+ {
+ *ra = GET_IW_F2X4I12_A (insn);
+ *rb = GET_IW_F2X4I12_B (insn);
+ *imm = (signed) (GET_IW_F2X4I12_IMM12 (insn) << 20) >> 20;
+ return 1;
+ }
+ else if (op->match == MATCH_R2_LDW_N)
+ {
+ *ra = nios2_r2_reg3_mappings[GET_IW_T2I4_A3 (insn)];
+ *rb = nios2_r2_reg3_mappings[GET_IW_T2I4_B3 (insn)];
+ *imm = GET_IW_T2I4_IMM4 (insn) << 2;
+ return 1;
+ }
+ else if (op->match == MATCH_R2_LDWSP_N)
+ {
+ *ra = NIOS2_SP_REGNUM;
+ *rb = GET_IW_F1I5_B (insn);
+ *imm = GET_IW_F1I5_IMM5 (insn) << 2;
+ return 1;
+ }
+ return 0;
+}
+
+/* Match and disassemble a RDCTL instruction, with 2 register operands.
+ Returns true on success, and fills in the operand pointers. */
+
+static int
+nios2_match_rdctl (uint32_t insn, const struct nios2_opcode *op,
+ unsigned long mach, int *ra, int *rc)
+{
+ int is_r2 = (mach == bfd_mach_nios2r2);
+
+ if (!is_r2 && (op->match == MATCH_R1_RDCTL))
+ {
+ *ra = GET_IW_R_IMM5 (insn);
+ *rc = GET_IW_R_C (insn);
+ return 1;
+ }
+ else if (!is_r2)
+ return 0;
+ else if (op->match == MATCH_R2_RDCTL)
+ {
+ *ra = GET_IW_F3X6L5_IMM5 (insn);
+ *rc = GET_IW_F3X6L5_C (insn);
+ return 1;
+ }
+ return 0;
+}
+
+/* Match and disassemble a PUSH.N or STWM instruction.
+ Returns true on success, and fills in the operand pointers. */
+
+static int
+nios2_match_stwm (uint32_t insn, const struct nios2_opcode *op,
+ unsigned long mach, unsigned int *reglist,
+ int *ra, int *imm, int *wb, int *id)
+{
+ int is_r2 = (mach == bfd_mach_nios2r2);
+
+ if (!is_r2)
+ return 0;
+ else if (op->match == MATCH_R2_PUSH_N)
+ {
+ *reglist = 1 << 31;
+ if (GET_IW_L5I4X1_FP (insn))
+ *reglist |= (1 << 28);
+ if (GET_IW_L5I4X1_CS (insn))
+ {
+ int val = GET_IW_L5I4X1_REGRANGE (insn);
+ *reglist |= nios2_r2_reg_range_mappings[val];
+ }
+ *ra = NIOS2_SP_REGNUM;
+ *imm = GET_IW_L5I4X1_IMM4 (insn) << 2;
+ *wb = 1;
+ *id = 0;
+ return 1;
+ }
+ else if (op->match == MATCH_R2_STWM)
+ {
+ unsigned int rawmask = GET_IW_F1X4L17_REGMASK (insn);
+ if (GET_IW_F1X4L17_RS (insn))
+ {
+ *reglist = ((rawmask << 14) & 0x00ffc000);
+ if (rawmask & (1 << 10))
+ *reglist |= (1 << 28);
+ if (rawmask & (1 << 11))
+ *reglist |= (1 << 31);
+ }
+ else
+ *reglist = rawmask << 2;
+ *ra = GET_IW_F1X4L17_A (insn);
+ *imm = 0;
+ *wb = GET_IW_F1X4L17_WB (insn);
+ *id = GET_IW_F1X4L17_ID (insn);
+ return 1;
+ }
+ return 0;
+}
+
+/* Match and disassemble a POP.N or LDWM instruction.
+ Returns true on success, and fills in the operand pointers. */
+
+static int
+nios2_match_ldwm (uint32_t insn, const struct nios2_opcode *op,
+ unsigned long mach, unsigned int *reglist,
+ int *ra, int *imm, int *wb, int *id, int *ret)
+{
+ int is_r2 = (mach == bfd_mach_nios2r2);
+
+ if (!is_r2)
+ return 0;
+ else if (op->match == MATCH_R2_POP_N)
+ {
+ *reglist = 1 << 31;
+ if (GET_IW_L5I4X1_FP (insn))
+ *reglist |= (1 << 28);
+ if (GET_IW_L5I4X1_CS (insn))
+ {
+ int val = GET_IW_L5I4X1_REGRANGE (insn);
+ *reglist |= nios2_r2_reg_range_mappings[val];
+ }
+ *ra = NIOS2_SP_REGNUM;
+ *imm = GET_IW_L5I4X1_IMM4 (insn) << 2;
+ *wb = 1;
+ *id = 1;
+ *ret = 1;
+ return 1;
+ }
+ else if (op->match == MATCH_R2_LDWM)
+ {
+ unsigned int rawmask = GET_IW_F1X4L17_REGMASK (insn);
+ if (GET_IW_F1X4L17_RS (insn))
+ {
+ *reglist = ((rawmask << 14) & 0x00ffc000);
+ if (rawmask & (1 << 10))
+ *reglist |= (1 << 28);
+ if (rawmask & (1 << 11))
+ *reglist |= (1 << 31);
+ }
+ else
+ *reglist = rawmask << 2;
+ *ra = GET_IW_F1X4L17_A (insn);
+ *imm = 0;
+ *wb = GET_IW_F1X4L17_WB (insn);
+ *id = GET_IW_F1X4L17_ID (insn);
+ *ret = GET_IW_F1X4L17_PC (insn);
+ return 1;
+ }
+ return 0;
+}
+
+/* Match and disassemble a branch instruction, with (potentially)
+ 2 register operands and one immediate operand.
+ Returns true on success, and fills in the operand pointers. */
+
+enum branch_condition {
+ branch_none,
+ branch_eq,
+ branch_ne,
+ branch_ge,
+ branch_geu,
+ branch_lt,
+ branch_ltu
+};
+
+static int
+nios2_match_branch (uint32_t insn, const struct nios2_opcode *op,
+ unsigned long mach, int *ra, int *rb, int *imm,
+ enum branch_condition *cond)
+{
+ int is_r2 = (mach == bfd_mach_nios2r2);
+
+ if (!is_r2)
+ {
+ switch (op->match)
+ {
+ case MATCH_R1_BR:
+ *cond = branch_none;
+ break;
+ case MATCH_R1_BEQ:
+ *cond = branch_eq;
+ break;
+ case MATCH_R1_BNE:
+ *cond = branch_ne;
+ break;
+ case MATCH_R1_BGE:
+ *cond = branch_ge;
+ break;
+ case MATCH_R1_BGEU:
+ *cond = branch_geu;
+ break;
+ case MATCH_R1_BLT:
+ *cond = branch_lt;
+ break;
+ case MATCH_R1_BLTU:
+ *cond = branch_ltu;
+ break;
+ default:
+ return 0;
+ }
+ *imm = (signed) (GET_IW_I_IMM16 (insn) << 16) >> 16;
+ *ra = GET_IW_I_A (insn);
+ *rb = GET_IW_I_B (insn);
+ return 1;
+ }
+ else
+ {
+ switch (op->match)
+ {
+ case MATCH_R2_BR_N:
+ *cond = branch_none;
+ *ra = NIOS2_Z_REGNUM;
+ *rb = NIOS2_Z_REGNUM;
+ *imm = (signed) ((GET_IW_I10_IMM10 (insn) << 1) << 21) >> 21;
+ return 1;
+ case MATCH_R2_BEQZ_N:
+ *cond = branch_eq;
+ *ra = nios2_r2_reg3_mappings[GET_IW_T1I7_A3 (insn)];
+ *rb = NIOS2_Z_REGNUM;
+ *imm = (signed) ((GET_IW_T1I7_IMM7 (insn) << 1) << 24) >> 24;
+ return 1;
+ case MATCH_R2_BNEZ_N:
+ *cond = branch_ne;
+ *ra = nios2_r2_reg3_mappings[GET_IW_T1I7_A3 (insn)];
+ *rb = NIOS2_Z_REGNUM;
+ *imm = (signed) ((GET_IW_T1I7_IMM7 (insn) << 1) << 24) >> 24;
+ return 1;
+ case MATCH_R2_BR:
+ *cond = branch_none;
+ break;
+ case MATCH_R2_BEQ:
+ *cond = branch_eq;
+ break;
+ case MATCH_R2_BNE:
+ *cond = branch_ne;
+ break;
+ case MATCH_R2_BGE:
+ *cond = branch_ge;
+ break;
+ case MATCH_R2_BGEU:
+ *cond = branch_geu;
+ break;
+ case MATCH_R2_BLT:
+ *cond = branch_lt;
+ break;
+ case MATCH_R2_BLTU:
+ *cond = branch_ltu;
+ break;
+ default:
+ return 0;
+ }
+ *ra = GET_IW_F2I16_A (insn);
+ *rb = GET_IW_F2I16_B (insn);
+ *imm = (signed) (GET_IW_F2I16_IMM16 (insn) << 16) >> 16;
+ return 1;
+ }
+ return 0;
+}
+
+/* Match and disassemble a direct jump instruction, with an
+ unsigned operand. Returns true on success, and fills in the operand
+ pointer. */
+
+static int
+nios2_match_jmpi (uint32_t insn, const struct nios2_opcode *op,
+ unsigned long mach, unsigned int *uimm)
+{
+ int is_r2 = (mach == bfd_mach_nios2r2);
+
+ if (!is_r2 && op->match == MATCH_R1_JMPI)
+ {
+ *uimm = GET_IW_J_IMM26 (insn) << 2;
+ return 1;
+ }
+ else if (!is_r2)
+ return 0;
+ else if (op->match == MATCH_R2_JMPI)
+ {
+ *uimm = GET_IW_L26_IMM26 (insn) << 2;
+ return 1;
+ }
+ return 0;
+}
+
+/* Match and disassemble a direct call instruction, with an
+ unsigned operand. Returns true on success, and fills in the operand
+ pointer. */
+
+static int
+nios2_match_calli (uint32_t insn, const struct nios2_opcode *op,
+ unsigned long mach, unsigned int *uimm)
+{
+ int is_r2 = (mach == bfd_mach_nios2r2);
+
+ if (!is_r2 && op->match == MATCH_R1_CALL)
+ {
+ *uimm = GET_IW_J_IMM26 (insn) << 2;
+ return 1;
+ }
+ else if (!is_r2)
+ return 0;
+ else if (op->match == MATCH_R2_CALL)
+ {
+ *uimm = GET_IW_L26_IMM26 (insn) << 2;
+ return 1;
+ }
+ return 0;
+}
+
+/* Match and disassemble an indirect jump instruction, with a
+ (possibly implicit) register operand. Returns true on success, and fills
+ in the operand pointer. */
+
+static int
+nios2_match_jmpr (uint32_t insn, const struct nios2_opcode *op,
+ unsigned long mach, int *ra)
+{
+ int is_r2 = (mach == bfd_mach_nios2r2);
+
+ if (!is_r2)
+ switch (op->match)
+ {
+ case MATCH_R1_JMP:
+ *ra = GET_IW_I_A (insn);
+ return 1;
+ case MATCH_R1_RET:
+ *ra = NIOS2_RA_REGNUM;
+ return 1;
+ case MATCH_R1_ERET:
+ *ra = NIOS2_EA_REGNUM;
+ return 1;
+ case MATCH_R1_BRET:
+ *ra = NIOS2_BA_REGNUM;
+ return 1;
+ default:
+ return 0;
+ }
+ else
+ switch (op->match)
+ {
+ case MATCH_R2_JMP:
+ *ra = GET_IW_F2I16_A (insn);
+ return 1;
+ case MATCH_R2_JMPR_N:
+ *ra = GET_IW_F1X1_A (insn);
+ return 1;
+ case MATCH_R2_RET:
+ case MATCH_R2_RET_N:
+ *ra = NIOS2_RA_REGNUM;
+ return 1;
+ case MATCH_R2_ERET:
+ *ra = NIOS2_EA_REGNUM;
+ return 1;
+ case MATCH_R2_BRET:
+ *ra = NIOS2_BA_REGNUM;
+ return 1;
+ default:
+ return 0;
+ }
+ return 0;
+}
+
+/* Match and disassemble an indirect call instruction, with a register
+ operand. Returns true on success, and fills in the operand pointer. */
+
+static int
+nios2_match_callr (uint32_t insn, const struct nios2_opcode *op,
+ unsigned long mach, int *ra)
+{
+ int is_r2 = (mach == bfd_mach_nios2r2);
+
+ if (!is_r2 && op->match == MATCH_R1_CALLR)
+ {
+ *ra = GET_IW_I_A (insn);
+ return 1;
+ }
+ else if (!is_r2)
+ return 0;
+ else if (op->match == MATCH_R2_CALLR)
+ {
+ *ra = GET_IW_F2I16_A (insn);
+ return 1;
+ }
+ else if (op->match == MATCH_R2_CALLR_N)
+ {
+ *ra = GET_IW_F1X1_A (insn);
+ return 1;
+ }
+ return 0;
+}
+
+/* Match and disassemble a break instruction, with an unsigned operand.
+ Returns true on success, and fills in the operand pointer. */
+
+static int
+nios2_match_break (uint32_t insn, const struct nios2_opcode *op,
+ unsigned long mach, unsigned int *uimm)
+{
+ int is_r2 = (mach == bfd_mach_nios2r2);
+
+ if (!is_r2 && op->match == MATCH_R1_BREAK)
+ {
+ *uimm = GET_IW_R_IMM5 (insn);
+ return 1;
+ }
+ else if (!is_r2)
+ return 0;
+ else if (op->match == MATCH_R2_BREAK)
+ {
+ *uimm = GET_IW_F3X6L5_IMM5 (insn);
+ return 1;
+ }
+ else if (op->match == MATCH_R2_BREAK_N)
+ {
+ *uimm = GET_IW_X2L5_IMM5 (insn);
+ return 1;
+ }
+ return 0;
+}
+
+/* Match and disassemble a trap instruction, with an unsigned operand.
+ Returns true on success, and fills in the operand pointer. */
+
+static int
+nios2_match_trap (uint32_t insn, const struct nios2_opcode *op,
+ unsigned long mach, unsigned int *uimm)
+{
+ int is_r2 = (mach == bfd_mach_nios2r2);
+
+ if (!is_r2 && op->match == MATCH_R1_TRAP)
+ {
+ *uimm = GET_IW_R_IMM5 (insn);
+ return 1;
+ }
+ else if (!is_r2)
+ return 0;
+ else if (op->match == MATCH_R2_TRAP)
+ {
+ *uimm = GET_IW_F3X6L5_IMM5 (insn);
+ return 1;
+ }
+ else if (op->match == MATCH_R2_TRAP_N)
+ {
+ *uimm = GET_IW_X2L5_IMM5 (insn);
+ return 1;
+ }
+ return 0;
+}
+