From e26a5104014a4e63e1203775ef27410571310b8c Mon Sep 17 00:00:00 2001
From: Chao-ying Fu <cfu@wavecomp.com>
Date: Mon, 23 Dec 2024 16:32:14 -0800
Subject: [PATCH] RISC-V: Support MIPS extensions: xmipscbop, xmipscmov,
xmipsexectl, and xmipslsp
MIPS custom instructions include pref, ccmov, ehb, ihb, mipspause, ldp, lwp,
sdp, and swp.
Spec: https://mips.com/wp-content/uploads/2024/11/P8700-F_Programmers_Reference_Manual_Rev1.80_11-13-2024.pdf .
Signed-off-by: Jovan Dmitrović <jovan.dmitrovic@htecgroup.com>
Signed-off-by: Chao-ying Fu <cfu@wavecomp.com>
---
bfd/elfxx-riscv.c | 12 ++++
gas/NEWS | 6 +-
gas/config/tc-riscv.c | 101 +++++++++++++++++++++++++++
gas/testsuite/gas/riscv/march-help.l | 4 ++
gas/testsuite/gas/riscv/mips-insns.d | 31 ++++++++
gas/testsuite/gas/riscv/mips-insns.s | 42 +++++++++++
include/opcode/riscv-opc.h | 29 ++++++++
include/opcode/riscv.h | 40 +++++++++++
opcodes/riscv-dis.c | 36 ++++++++++
opcodes/riscv-opc.c | 12 ++++
10 files changed, 311 insertions(+), 2 deletions(-)
create mode 100644 gas/testsuite/gas/riscv/mips-insns.d
create mode 100644 gas/testsuite/gas/riscv/mips-insns.s
@@ -1504,6 +1504,10 @@ static struct riscv_supported_ext riscv_supported_vendor_x_ext[] =
{"xsfvqmaccqoq", ISA_SPEC_CLASS_DRAFT, 1, 0, 0},
{"xsfvqmaccdod", ISA_SPEC_CLASS_DRAFT, 1, 0, 0},
{"xsfvfnrclipxfqf", ISA_SPEC_CLASS_DRAFT, 1, 0, 0},
+ {"xmipscbop", ISA_SPEC_CLASS_DRAFT, 1, 0, 0},
+ {"xmipscmov", ISA_SPEC_CLASS_DRAFT, 1, 0, 0},
+ {"xmipsexectl", ISA_SPEC_CLASS_DRAFT, 1, 0, 0},
+ {"xmipslsp", ISA_SPEC_CLASS_DRAFT, 1, 0, 0},
{NULL, 0, 0, 0, 0}
};
@@ -2793,6 +2797,14 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
return riscv_subset_supports (rps, "xsfvqmaccdod");
case INSN_CLASS_XSFVFNRCLIPXFQF:
return riscv_subset_supports (rps, "xsfvfnrclipxfqf");
+ case INSN_CLASS_XMIPSCBOP:
+ return riscv_subset_supports (rps, "xmipscbop");
+ case INSN_CLASS_XMIPSCMOV:
+ return riscv_subset_supports (rps, "xmipscmov");
+ case INSN_CLASS_XMIPSEXECTL:
+ return riscv_subset_supports (rps, "xmipsexectl");
+ case INSN_CLASS_XMIPSLSP:
+ return riscv_subset_supports (rps, "xmipslsp");
default:
rps->error_handler
(_("internal: unreachable INSN_CLASS_*"));
@@ -24,8 +24,10 @@
* On x86 emulation support (for secondary targets) was dropped.
* Add support for RISC-V Zcmp (cm.mva01s, cm.mvsa01), Smrnmi, S[sm]dbltrp,
- CORE-V (xcvbitmanip, xcvsimd) extensions with version 1.0 and more SiFive
- extensions (xsfvqmaccdod, xsfvqmaccqoq and xsfvfnrclipxfqf).
+ CORE-V (xcvbitmanip, xcvsimd) extensions with version 1.0, more SiFive
+ extensions (xsfvqmaccdod, xsfvqmaccqoq and xsfvfnrclipxfqf, and MIPS
+ extensions (xmipscbop, xmipscmov, xmipsexectl, and xmipslsp): pref, ccmov,
+ ehb, ihb, mipspause, ldp, lwp, sdp, and swp.
Changes in 2.43:
@@ -1750,6 +1750,21 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length)
goto unknown_validate_operand;
}
break;
+ case 'm': /* Vendor-specific (MIPS) operands. */
+ switch (*++oparg)
+ {
+ case '@': USE_BITS (OP_MASK_MIPS_HINT, OP_SH_MIPS_HINT);
+ break;
+ case '#': USE_BITS (OP_MASK_MIPS_IMM9, OP_SH_MIPS_IMM9);
+ break;
+ case '$': used_bits |= ENCODE_MIPS_LDP_IMM (-1U); break;
+ case '%': used_bits |= ENCODE_MIPS_LWP_IMM (-1U); break;
+ case '^': used_bits |= ENCODE_MIPS_SDP_IMM (-1U); break;
+ case '&': used_bits |= ENCODE_MIPS_SWP_IMM (-1U); break;
+ default:
+ goto unknown_validate_operand;
+ }
+ break;
default:
goto unknown_validate_operand;
}
@@ -4173,6 +4188,92 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
#undef ENCODE_UIMM_BIT_FIELD
break;
+ case 'm': /* Vendor-specific (MIPS) operands. */
+ switch (*++oparg)
+ {
+ case '@': /* hint 0 - 31. */
+ my_getExpression (imm_expr, asarg);
+ check_absolute_expr (ip, imm_expr, FALSE);
+ if ((unsigned long)imm_expr->X_add_number > 31)
+ as_bad(_("Improper hint amount (%lu)"),
+ (unsigned long)imm_expr->X_add_number);
+ INSERT_OPERAND(MIPS_HINT, *ip, imm_expr->X_add_number);
+ imm_expr->X_op = O_absent;
+ asarg = expr_parse_end;
+ continue;
+
+ case '#': /* immediate 0 - 511. */
+ my_getExpression (imm_expr, asarg);
+ check_absolute_expr (ip, imm_expr, FALSE);
+ if ((unsigned long)imm_expr->X_add_number > 511)
+ as_bad(_("Improper immediate amount (%lu)"),
+ (unsigned long)imm_expr->X_add_number);
+ INSERT_OPERAND(MIPS_IMM9, *ip, imm_expr->X_add_number);
+ imm_expr->X_op = O_absent;
+ asarg = expr_parse_end;
+ continue;
+
+ case '$': /* LDP offset 0 to (1<<7)-8. */
+ my_getExpression (imm_expr, asarg);
+ check_absolute_expr (ip, imm_expr, FALSE);
+ if ((unsigned long)imm_expr->X_add_number >= (1 << 7)
+ || ((unsigned long)imm_expr->X_add_number & 0x7) != 0)
+ as_bad(_("Improper LDP offset amount (%lu)"),
+ (unsigned long)imm_expr->X_add_number);
+ INSERT_OPERAND(MIPS_LDP_OFFSET, *ip,
+ (imm_expr->X_add_number >> 3));
+ imm_expr->X_op = O_absent;
+ asarg = expr_parse_end;
+ continue;
+
+ case '%': /* LWP offset 0 to (1<<7)-4. */
+ my_getExpression (imm_expr, asarg);
+ check_absolute_expr (ip, imm_expr, FALSE);
+ if ((unsigned long)imm_expr->X_add_number >= (1 << 7)
+ || ((unsigned long)imm_expr->X_add_number & 0x3) != 0)
+ as_bad(_("Improper LWP offset amount (%lu)"),
+ (unsigned long)imm_expr->X_add_number);
+ INSERT_OPERAND(MIPS_LWP_OFFSET, *ip,
+ (imm_expr->X_add_number >> 2));
+ imm_expr->X_op = O_absent;
+ asarg = expr_parse_end;
+ continue;
+
+ case '^': /* SDP offset 0 to (1<<7)-8. */
+ my_getExpression (imm_expr, asarg);
+ check_absolute_expr (ip, imm_expr, FALSE);
+ if ((unsigned long)imm_expr->X_add_number >= (1 << 7)
+ || ((unsigned long)imm_expr->X_add_number & 0x7) != 0)
+ as_bad(_("Improper SDP offset amount (%lu)"),
+ (unsigned long)imm_expr->X_add_number);
+ INSERT_OPERAND(MIPS_SDP_OFFSET10, *ip,
+ (imm_expr->X_add_number >> 3));
+ INSERT_OPERAND(MIPS_SDP_OFFSET25, *ip,
+ (imm_expr->X_add_number >> 5));
+ imm_expr->X_op = O_absent;
+ asarg = expr_parse_end;
+ continue;
+
+ case '&': /* SWP offset 0 to (1<<7)-4. */
+ my_getExpression (imm_expr, asarg);
+ check_absolute_expr (ip, imm_expr, FALSE);
+ if ((unsigned long)imm_expr->X_add_number >= (1 << 7)
+ || ((unsigned long)imm_expr->X_add_number & 0x3) != 0)
+ as_bad(_("Improper SWP offset amount (%lu)"),
+ (unsigned long)imm_expr->X_add_number);
+ INSERT_OPERAND(MIPS_SWP_OFFSET9, *ip,
+ (imm_expr->X_add_number >> 2));
+ INSERT_OPERAND(MIPS_SWP_OFFSET25, *ip,
+ (imm_expr->X_add_number >> 5));
+ imm_expr->X_op = O_absent;
+ asarg = expr_parse_end;
+ continue;
+
+ default:
+ goto unknown_riscv_ip_operand;
+ }
+ break;
+
default:
goto unknown_riscv_ip_operand;
}
@@ -162,3 +162,7 @@ All available -march extensions for RISC-V:
xsfvqmaccqoq 1.0
xsfvqmaccdod 1.0
xsfvfnrclipxfqf 1.0
+ xmipscbop 1.0
+ xmipscmov 1.0
+ xmipsexectl 1.0
+ xmipslsp 1.0
new file mode 100644
@@ -0,0 +1,31 @@
+#as:
+#objdump: -dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[ ]+[0-9a-f]+:[ ]+0003000b[ ]+pref[ ]+0x0,0x0\(t1\)
+[ ]+[0-9a-f]+:[ ]+1ff38f8b[ ]+pref[ ]+0x1f,0x1ff\(t2\)
+[ ]+[0-9a-f]+:[ ]+6eb6350b[ ]+ccmov[ ]+a0,a1,a2,a3
+[ ]+[0-9a-f]+:[ ]+00301013[ ]+ehb
+[ ]+[0-9a-f]+:[ ]+00101013[ ]+ihb
+[ ]+[0-9a-f]+:[ ]+00501013[ ]+mipspause
+[ ]+[0-9a-f]+:[ ]+e80f4e0b[ ]+ldp[ ]+t3,t4,0\(t5\)
+[ ]+[0-9a-f]+:[ ]+e88f4e0b[ ]+ldp[ ]+t3,t4,8\(t5\)
+[ ]+[0-9a-f]+:[ ]+1f00cf8b[ ]+ldp[ ]+t6,gp,112\(ra\)
+[ ]+[0-9a-f]+:[ ]+1f80cf8b[ ]+ldp[ ]+t6,gp,120\(ra\)
+[ ]+[0-9a-f]+:[ ]+5816450b[ ]+lwp[ ]+a0,a1,0\(a2\)
+[ ]+[0-9a-f]+:[ ]+5856450b[ ]+lwp[ ]+a0,a1,4\(a2\)
+[ ]+[0-9a-f]+:[ ]+7797c68b[ ]+lwp[ ]+a3,a4,120\(a5\)
+[ ]+[0-9a-f]+:[ ]+77d7c68b[ ]+lwp[ ]+a3,a4,124\(a5\)
+[ ]+[0-9a-f]+:[ ]+e9cf500b[ ]+sdp[ ]+t3,t4,0\(t5\)
+[ ]+[0-9a-f]+:[ ]+e9cf540b[ ]+sdp[ ]+t3,t4,8\(t5\)
+[ ]+[0-9a-f]+:[ ]+1ff0d80b[ ]+sdp[ ]+t6,gp,112\(ra\)
+[ ]+[0-9a-f]+:[ ]+1ff0dc0b[ ]+sdp[ ]+t6,gp,120\(ra\)
+[ ]+[0-9a-f]+:[ ]+58a6508b[ ]+swp[ ]+a0,a1,0\(a2\)
+[ ]+[0-9a-f]+:[ ]+58a6528b[ ]+swp[ ]+a0,a1,4\(a2\)
+[ ]+[0-9a-f]+:[ ]+76d7dc8b[ ]+swp[ ]+a3,a4,120\(a5\)
+[ ]+[0-9a-f]+:[ ]+76d7de8b[ ]+swp[ ]+a3,a4,124\(a5\)
new file mode 100644
@@ -0,0 +1,42 @@
+ .attribute arch, "rv64i"
+ # xmipscbop
+ .option push
+ .option arch, +xmipscbop
+ pref 0, 0(t1)
+ pref 31, 511(t2)
+ .option pop
+
+ # xmipscmov
+ .option push
+ .option arch, +xmipscmov
+ ccmov a0,a1,a2,a3
+ .option pop
+
+ # xmipsexectl
+ .option push
+ .option arch, +xmipsexectl
+ ehb
+ ihb
+ mipspause
+ .option pop
+
+ # xmipslsp
+ .option push
+ .option arch, +xmipslsp
+ ldp t3, t4, 0(t5)
+ ldp t3, t4, 8(t5)
+ ldp t6, gp, 112(ra)
+ ldp t6, gp, 120(ra)
+ lwp a0, a1, 0(a2)
+ lwp a0, a1, 4(a2)
+ lwp a3, a4, 120(a5)
+ lwp a3, a4, 124(a5)
+ sdp t3, t4, 0(t5)
+ sdp t3, t4, 8(t5)
+ sdp t6, gp, 112(ra)
+ sdp t6, gp, 120(ra)
+ swp a0, a1, 0(a2)
+ swp a0, a1, 4(a2)
+ swp a3, a4, 120(a5)
+ swp a3, a4, 124(a5)
+ .option pop
@@ -3767,6 +3767,25 @@
#define MASK_SFVFNRCLIPXUFQF 0xfe00707f
#define MATCH_SFVFNRCLIPXFQF 0x8e00505b
#define MASK_SFVFNRCLIPXFQF 0xfe00707f
+/* MIPS custom instruction. */
+#define MATCH_MIPS_CCMOV 0x600300b
+#define MASK_MIPS_CCMOV 0x600707f
+#define MATCH_MIPS_LWP 0x0010400b
+#define MASK_MIPS_LWP 0x0030707f
+#define MATCH_MIPS_LDP 0x0000400b
+#define MASK_MIPS_LDP 0x0070707f
+#define MATCH_MIPS_SWP 0x0000508b
+#define MASK_MIPS_SWP 0x000071ff
+#define MATCH_MIPS_SDP 0x0000500b
+#define MASK_MIPS_SDP 0x000073ff
+#define MATCH_MIPS_EHB 0x00301013
+#define MASK_MIPS_EHB 0xffffffff
+#define MATCH_MIPS_IHB 0x00101013
+#define MASK_MIPS_IHB 0xffffffff
+#define MATCH_MIPS_PAUSE 0x00501013
+#define MASK_MIPS_PAUSE 0xffffffff
+#define MATCH_MIPS_PREF 0x0000000b
+#define MASK_MIPS_PREF 0xe000707f
/* Unprivileged Counter/Timers CSR addresses. */
#define CSR_CYCLE 0xc00
#define CSR_TIME 0xc01
@@ -4884,6 +4903,16 @@ DECLARE_INSN(th_sync_s, MATCH_TH_SYNC_S, MASK_TH_SYNC_S)
/* XVentanaCondOps instructions. */
DECLARE_INSN(vt_maskc, MATCH_VT_MASKC, MASK_VT_MASKC)
DECLARE_INSN(vt_maskcn, MATCH_VT_MASKCN, MASK_VT_MASKCN)
+/* MIPS custom instructions. */
+DECLARE_INSN(ccmov, MATCH_MIPS_CCMOV, MASK_MIPS_CCMOV)
+DECLARE_INSN(lwp, MATCH_MIPS_LWP, MASK_MIPS_LWP)
+DECLARE_INSN(ldp, MATCH_MIPS_LDP, MASK_MIPS_LDP)
+DECLARE_INSN(swp, MATCH_MIPS_SWP, MASK_MIPS_SWP)
+DECLARE_INSN(sdp, MATCH_MIPS_SDP, MASK_MIPS_SDP)
+DECLARE_INSN(ehb, MATCH_MIPS_EHB, MASK_MIPS_EHB)
+DECLARE_INSN(ihb, MATCH_MIPS_IHB, MASK_MIPS_IHB)
+DECLARE_INSN(mipspause, MATCH_MIPS_PAUSE, MASK_MIPS_PAUSE)
+DECLARE_INSN(pref, MATCH_MIPS_PREF, MASK_MIPS_PREF)
#endif /* DECLARE_INSN */
#ifdef DECLARE_CSR
/* Unprivileged Counter/Timers CSRs. */
@@ -132,6 +132,15 @@ static inline unsigned int riscv_insn_length (insn_t insn)
((RV_X(x, 25, 1)) | (RV_X(x, 20, 5) << 1) | (RV_IMM_SIGN_N(x, 20, 5) << 5))
#define EXTRACT_CV_SIMD_UIMM6(x) \
((RV_X(x, 25, 1)) | (RV_X(x, 20, 5) << 1))
+/* Vendor-specific (MIPS) extract macros. */
+#define EXTRACT_MIPS_LWP_IMM(x) \
+ (RV_X(x, 22, 5) << 2)
+#define EXTRACT_MIPS_LDP_IMM(x) \
+ (RV_X(x, 23, 4) << 3)
+#define EXTRACT_MIPS_SWP_IMM(x) \
+ ((RV_X(x, 25, 2) << 5) | (RV_X(x, 9, 3) << 2))
+#define EXTRACT_MIPS_SDP_IMM(x) \
+ ((RV_X(x, 25, 2) << 5) | (RV_X(x, 10, 2) << 3))
#define ENCODE_ITYPE_IMM(x) \
(RV_X(x, 0, 12) << 20)
@@ -200,6 +209,15 @@ static inline unsigned int riscv_insn_length (insn_t insn)
((RV_X(x, 0, 1) << 25) | (RV_X(x, 1, 5) << 20))
#define ENCODE_CV_SIMD_UIMM6(x) \
((RV_X(x, 0, 1) << 25) | (RV_X(x, 1, 5) << 20))
+/* Vendor-specific (MIPS) encode macros. */
+#define ENCODE_MIPS_LWP_IMM(x) \
+ (RV_X(x, 2, 5) << 22)
+#define ENCODE_MIPS_LDP_IMM(x) \
+ (RV_X(x, 3, 4) << 23)
+#define ENCODE_MIPS_SWP_IMM(x) \
+ ((RV_X(x, 5, 2) << 25) | (RV_X(x, 2, 3) << 9))
+#define ENCODE_MIPS_SDP_IMM(x) \
+ ((RV_X(x, 5, 2) << 25) | (RV_X(x, 3, 2) << 10))
#define VALID_ITYPE_IMM(x) (EXTRACT_ITYPE_IMM(ENCODE_ITYPE_IMM(x)) == (x))
#define VALID_STYPE_IMM(x) (EXTRACT_STYPE_IMM(ENCODE_STYPE_IMM(x)) == (x))
@@ -383,6 +401,24 @@ static inline unsigned int riscv_insn_length (insn_t insn)
#define OP_MASK_XSO1 0x1
#define OP_SH_XSO1 26
+/* MIPS fields. */
+#define OP_MASK_MIPS_IMM9 0x1ff
+#define OP_SH_MIPS_IMM9 20
+#define OP_MASK_MIPS_HINT 0x1f
+#define OP_SH_MIPS_HINT 7
+#define OP_MASK_MIPS_LWP_OFFSET 0x1f
+#define OP_SH_MIPS_LWP_OFFSET 22
+#define OP_MASK_MIPS_LDP_OFFSET 0xf
+#define OP_SH_MIPS_LDP_OFFSET 23
+#define OP_MASK_MIPS_SWP_OFFSET9 0x7
+#define OP_SH_MIPS_SWP_OFFSET9 9
+#define OP_MASK_MIPS_SWP_OFFSET25 0x3
+#define OP_SH_MIPS_SWP_OFFSET25 25
+#define OP_MASK_MIPS_SDP_OFFSET10 0x3
+#define OP_SH_MIPS_SDP_OFFSET10 10
+#define OP_MASK_MIPS_SDP_OFFSET25 0x3
+#define OP_SH_MIPS_SDP_OFFSET25 25
+
/* ABI names for selected x-registers. */
#define X_RA 1
@@ -557,6 +593,10 @@ enum riscv_insn_class
INSN_CLASS_XSFVQMACCQOQ,
INSN_CLASS_XSFVQMACCDOD,
INSN_CLASS_XSFVFNRCLIPXFQF,
+ INSN_CLASS_XMIPSCBOP,
+ INSN_CLASS_XMIPSCMOV,
+ INSN_CLASS_XMIPSEXECTL,
+ INSN_CLASS_XMIPSLSP,
};
/* This structure holds information for a particular instruction. */
@@ -517,6 +517,11 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
print (info->stream, dis_style_immediate, "0");
break;
+ case 'r':
+ print (info->stream, dis_style_register, "%s",
+ riscv_gpr_names[EXTRACT_OPERAND (RS3, l)]);
+ break;
+
case 's':
if ((l & MASK_JALR) == MATCH_JALR)
maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0);
@@ -880,6 +885,37 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
break;
}
break;
+ case 'm': /* Vendor-specific (MIPS) operands. */
+ switch (*++oparg)
+ {
+ case '@':
+ print (info->stream, dis_style_register, "0x%x",
+ (unsigned) EXTRACT_OPERAND (MIPS_HINT, l));
+ break;
+ case '#':
+ print (info->stream, dis_style_register, "0x%x",
+ (unsigned) EXTRACT_OPERAND (MIPS_IMM9, l));
+ break;
+ case '$':
+ print (info->stream, dis_style_immediate, "%d",
+ (unsigned)EXTRACT_MIPS_LDP_IMM (l));
+ break;
+ case '%':
+ print (info->stream, dis_style_immediate, "%d",
+ (unsigned)EXTRACT_MIPS_LWP_IMM (l));
+ break;
+ case '^':
+ print (info->stream, dis_style_immediate, "%d",
+ (unsigned)EXTRACT_MIPS_SDP_IMM (l));
+ break;
+ case '&':
+ print (info->stream, dis_style_immediate, "%d",
+ (unsigned)EXTRACT_MIPS_SWP_IMM (l));
+ break;
+ default:
+ goto undefined_modifier;
+ }
+ break;
default:
goto undefined_modifier;
}
@@ -507,6 +507,10 @@ const struct riscv_opcode riscv_opcodes[] =
{"la.tls.gd", 0, INSN_CLASS_I, "d,A", 0, (int) M_LA_TLS_GD, NULL, INSN_MACRO },
{"la.tls.ie", 0, INSN_CLASS_I, "d,A", 0, (int) M_LA_TLS_IE, match_rd_nonzero, INSN_MACRO },
{"neg", 0, INSN_CLASS_I, "d,t", MATCH_SUB, MASK_SUB|MASK_RS1, match_opcode, INSN_ALIAS }, /* sub 0 */
+/* Put MIPS custom instructions: ehb, ihb, and mipspause before slli. */
+{"ehb", 0, INSN_CLASS_XMIPSEXECTL, "", MATCH_MIPS_EHB, MASK_MIPS_EHB, match_opcode, 0 },
+{"ihb", 0, INSN_CLASS_XMIPSEXECTL, "", MATCH_MIPS_IHB, MASK_MIPS_IHB, match_opcode, 0 },
+{"mipspause", 0, INSN_CLASS_XMIPSEXECTL, "", MATCH_MIPS_PAUSE, MASK_MIPS_PAUSE, match_opcode, 0 },
{"slli", 0, INSN_CLASS_C, "d,CU,C>", MATCH_C_SLLI, MASK_C_SLLI, match_slli_as_c_slli, INSN_ALIAS },
{"slli", 0, INSN_CLASS_I, "d,s,>", MATCH_SLLI, MASK_SLLI, match_opcode, 0 },
{"sll", 0, INSN_CLASS_C, "d,CU,C>", MATCH_C_SLLI, MASK_C_SLLI, match_slli_as_c_slli, INSN_ALIAS },
@@ -3463,6 +3467,14 @@ const struct riscv_opcode riscv_opcodes[] =
{"sf.vfnrclip.xu.f.qf", 0, INSN_CLASS_XSFVFNRCLIPXFQF, "Vd,Vt,S", MATCH_SFVFNRCLIPXUFQF, MASK_SFVFNRCLIPXUFQF, match_opcode, 0},
{"sf.vfnrclip.x.f.qf", 0, INSN_CLASS_XSFVFNRCLIPXFQF, "Vd,Vt,S", MATCH_SFVFNRCLIPXFQF, MASK_SFVFNRCLIPXFQF, match_opcode, 0},
+/* MIPS custom instructions. */
+{"ccmov", 0, INSN_CLASS_XMIPSCMOV, "d,t,s,r", MATCH_MIPS_CCMOV, MASK_MIPS_CCMOV, match_opcode, 0},
+{"ldp", 0, INSN_CLASS_XMIPSLSP, "d,r,Xm$(s)", MATCH_MIPS_LDP, MASK_MIPS_LDP, match_opcode, 0 },
+{"lwp", 0, INSN_CLASS_XMIPSLSP, "d,r,Xm%(s)", MATCH_MIPS_LWP, MASK_MIPS_LWP, match_opcode, 0 },
+{"pref", 0, INSN_CLASS_XMIPSCBOP, "Xm@,Xm#(s)", MATCH_MIPS_PREF, MASK_MIPS_PREF, match_opcode, 0 },
+{"sdp", 0, INSN_CLASS_XMIPSLSP, "t,r,Xm^(s)", MATCH_MIPS_SDP, MASK_MIPS_SDP, match_opcode, 0 },
+{"swp", 0, INSN_CLASS_XMIPSLSP, "t,r,Xm&(s)", MATCH_MIPS_SWP, MASK_MIPS_SWP, match_opcode, 0 },
+
/* Terminate the list. */
{0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
};
--
2.34.1