]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
RISC-V: Added vendor extensions, xmipscbop, xmipscmov, xmipsexectl and xmipslsp
authorChao-ying Fu <cfu@wavecomp.com>
Fri, 9 May 2025 01:52:17 +0000 (09:52 +0800)
committerNelson Chu <nelson@rivosinc.com>
Fri, 9 May 2025 04:24:15 +0000 (12:24 +0800)
Spec:
https://mips.com/wp-content/uploads/2025/03/P8700-F_Programmers_Reference_Manual_Rev1.82_3-19-2025.pdf

Added MIPS vendor extensions, xmipscbop, xmipscmov, xmipsexectl and xmipslsp
with verison 1.0.

Passed binutils testsuites of targets elf32/elf64/linux32/linux64.

Signed-off-by: Jovan Dmitrović <jovan.dmitrovic@htecgroup.com>
Signed-off-by: Chao-ying Fu <cfu@wavecomp.com>
bfd/elfxx-riscv.c
gas/NEWS
gas/config/tc-riscv.c
gas/doc/c-riscv.texi
gas/testsuite/gas/riscv/march-help.l
gas/testsuite/gas/riscv/mips-insns.d [new file with mode: 0644]
gas/testsuite/gas/riscv/mips-insns.s [new file with mode: 0644]
include/opcode/riscv-opc.h
include/opcode/riscv.h
opcodes/riscv-dis.c
opcodes/riscv-opc.c

index ec254915c767b860dccbaa4b28e6ab8ec538a37f..5cb2500a35a6066bf896b1f9fb85e019b386e0c4 100644 (file)
@@ -1523,6 +1523,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}
 };
 
@@ -2863,6 +2867,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_*"));
index b4fc2e9e9be225e3f8fefbd2f447c90751857332..bff2248c9b0064f90bc48098e12162d31dba2a0c 100644 (file)
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -13,6 +13,7 @@
 
 * Add support for RISC-V vendor extensions:
   T-Head: xtheadvdot v1.0.
+  MIPS: xmipscbop v1.0, xmipscmov v1.0, xmipsexectl v1.0, xmipslsp v1.0.
 
 * Add support for the x86 Zhaoxin PadLock XMODX instructions.
 
index 8485ad441f5c02e8610c471d10f70567fa62b4d3..79121e7a65a66e0052aa53938d9bd494d53b14f7 100644 (file)
@@ -1752,6 +1752,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;
                }
index 0a92e7805ee2e8a84e753222fa1c1e7609647a22..28ccfb26b4b02282cfd3ae6075caa51d2c143f88 100644 (file)
@@ -892,4 +892,25 @@ XSfCease provides an instruction to instigates power-down sequence.
 
 It is documented in @url{https://sifive.cdn.prismic.io/sifive/767804da-53b2-4893-97d5-b7c030ae0a94_s76mc_core_complex_manual_21G3.pdf}.
 
+@item XMipsCbop
+The XMipsCbop extension provides instruction mips.pref.
+
+It is documented in @url{https://mips.com/wp-content/uploads/2025/03/P8700-F_Programmers_Reference_Manual_Rev1.82_3-19-2025.pdf}.
+
+@item XMipsCmov
+The XMipsCmov extension provides instruction mips.ccmov.
+
+It is documented in @url{https://mips.com/wp-content/uploads/2025/03/P8700-F_Programmers_Reference_Manual_Rev1.82_3-19-2025.pdf}.
+
+@item XMipsExectl
+The XMipsExectl extension provides instructions mips.ehb, mips.ihb and mips.pause.
+
+It is documented in @url{https://mips.com/wp-content/uploads/2025/03/P8700-F_Programmers_Reference_Manual_Rev1.82_3-19-2025.pdf}.
+
+@item XMipsSlsp
+
+The XMipsSlsp extension provides instructions mips.ldp, mips.lwp, mips.sdp and mips.swp.
+
+It is documented in @url{https://mips.com/wp-content/uploads/2025/03/P8700-F_Programmers_Reference_Manual_Rev1.82_3-19-2025.pdf}.
+
 @end table
index d77472fda9c343de15e97e9541a877e027fa0e89..e71795663f5d464081dc6ea28d4005c8e18e157f 100644 (file)
@@ -173,3 +173,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
diff --git a/gas/testsuite/gas/riscv/mips-insns.d b/gas/testsuite/gas/riscv/mips-insns.d
new file mode 100644 (file)
index 0000000..999c433
--- /dev/null
@@ -0,0 +1,31 @@
+#as:
+#objdump: -dr
+
+.*:[   ]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[      ]+[0-9a-f]+:[   ]+0003000b[     ]+mips.pref[    ]+0x0,0x0\(t1\)
+[      ]+[0-9a-f]+:[   ]+1ff38f8b[     ]+mips.pref[    ]+0x1f,0x1ff\(t2\)
+[      ]+[0-9a-f]+:[   ]+6eb6350b[     ]+mips.ccmov[   ]+a0,a1,a2,a3
+[      ]+[0-9a-f]+:[   ]+00301013[     ]+mips.ehb
+[      ]+[0-9a-f]+:[   ]+00101013[     ]+mips.ihb
+[      ]+[0-9a-f]+:[   ]+00501013[     ]+mips.pause
+[      ]+[0-9a-f]+:[   ]+e80f4e0b[     ]+mips.ldp[     ]+t3,t4,0\(t5\)
+[      ]+[0-9a-f]+:[   ]+e88f4e0b[     ]+mips.ldp[     ]+t3,t4,8\(t5\)
+[      ]+[0-9a-f]+:[   ]+1f00cf8b[     ]+mips.ldp[     ]+t6,gp,112\(ra\)
+[      ]+[0-9a-f]+:[   ]+1f80cf8b[     ]+mips.ldp[     ]+t6,gp,120\(ra\)
+[      ]+[0-9a-f]+:[   ]+5816450b[     ]+mips.lwp[     ]+a0,a1,0\(a2\)
+[      ]+[0-9a-f]+:[   ]+5856450b[     ]+mips.lwp[     ]+a0,a1,4\(a2\)
+[      ]+[0-9a-f]+:[   ]+7797c68b[     ]+mips.lwp[     ]+a3,a4,120\(a5\)
+[      ]+[0-9a-f]+:[   ]+77d7c68b[     ]+mips.lwp[     ]+a3,a4,124\(a5\)
+[      ]+[0-9a-f]+:[   ]+e9cf500b[     ]+mips.sdp[     ]+t3,t4,0\(t5\)
+[      ]+[0-9a-f]+:[   ]+e9cf540b[     ]+mips.sdp[     ]+t3,t4,8\(t5\)
+[      ]+[0-9a-f]+:[   ]+1ff0d80b[     ]+mips.sdp[     ]+t6,gp,112\(ra\)
+[      ]+[0-9a-f]+:[   ]+1ff0dc0b[     ]+mips.sdp[     ]+t6,gp,120\(ra\)
+[      ]+[0-9a-f]+:[   ]+58a6508b[     ]+mips.swp[     ]+a0,a1,0\(a2\)
+[      ]+[0-9a-f]+:[   ]+58a6528b[     ]+mips.swp[     ]+a0,a1,4\(a2\)
+[      ]+[0-9a-f]+:[   ]+76d7dc8b[     ]+mips.swp[     ]+a3,a4,120\(a5\)
+[      ]+[0-9a-f]+:[   ]+76d7de8b[     ]+mips.swp[     ]+a3,a4,124\(a5\)
diff --git a/gas/testsuite/gas/riscv/mips-insns.s b/gas/testsuite/gas/riscv/mips-insns.s
new file mode 100644 (file)
index 0000000..793c6ef
--- /dev/null
@@ -0,0 +1,42 @@
+       .attribute arch, "rv64i"
+       # xmipscbop
+       .option push
+       .option arch, +xmipscbop
+       mips.pref       0, 0(t1)
+       mips.pref       31, 511(t2)
+       .option pop
+
+       # xmipscmov
+       .option push
+       .option arch, +xmipscmov
+       mips.ccmov      a0,a1,a2,a3
+       .option pop
+
+       # xmipsexectl
+       .option push
+       .option arch, +xmipsexectl
+       mips.ehb
+       mips.ihb
+       mips.pause
+       .option pop
+
+       # xmipslsp
+       .option push
+       .option arch, +xmipslsp
+       mips.ldp        t3, t4, 0(t5)
+       mips.ldp        t3, t4, 8(t5)
+       mips.ldp        t6, gp, 112(ra)
+       mips.ldp        t6, gp, 120(ra)
+       mips.lwp        a0, a1, 0(a2)
+       mips.lwp        a0, a1, 4(a2)
+       mips.lwp        a3, a4, 120(a5)
+       mips.lwp        a3, a4, 124(a5)
+       mips.sdp        t3, t4, 0(t5)
+       mips.sdp        t3, t4, 8(t5)
+       mips.sdp        t6, gp, 112(ra)
+       mips.sdp        t6, gp, 120(ra)
+       mips.swp        a0, a1, 0(a2)
+       mips.swp        a0, a1, 4(a2)
+       mips.swp        a3, a4, 120(a5)
+       mips.swp        a3, a4, 124(a5)
+       .option pop
index fea49481498c09b2aed043ccb0e76766f2022d17..ab378ae069388f5593877d6be79fb52cde25bd68 100644 (file)
 #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
@@ -4945,6 +4964,16 @@ DECLARE_INSN(ssamoswap_w, MATCH_SSAMOSWAP_W, MASK_SSAMOSWAP_W)
 DECLARE_INSN(ssamoswap_d, MATCH_SSAMOSWAP_D, MASK_SSAMOSWAP_D)
 /* Zicfilp instructions.  */
 DECLARE_INSN(lpad, MATCH_LPAD, MASK_LPAD)
+/* MIPS custom instructions.  */
+DECLARE_INSN(mips_ccmov, MATCH_MIPS_CCMOV, MASK_MIPS_CCMOV)
+DECLARE_INSN(mips_lwp, MATCH_MIPS_LWP, MASK_MIPS_LWP)
+DECLARE_INSN(mips_ldp, MATCH_MIPS_LDP, MASK_MIPS_LDP)
+DECLARE_INSN(mips_swp, MATCH_MIPS_SWP, MASK_MIPS_SWP)
+DECLARE_INSN(mips_sdp, MATCH_MIPS_SDP, MASK_MIPS_SDP)
+DECLARE_INSN(mips_ehb, MATCH_MIPS_EHB, MASK_MIPS_EHB)
+DECLARE_INSN(mips_ihb, MATCH_MIPS_IHB, MASK_MIPS_IHB)
+DECLARE_INSN(mips_pause, MATCH_MIPS_PAUSE, MASK_MIPS_PAUSE)
+DECLARE_INSN(mips_pref, MATCH_MIPS_PREF, MASK_MIPS_PREF)
 #endif /* DECLARE_INSN */
 #ifdef DECLARE_CSR
 /* Unprivileged Counter/Timers CSRs.  */
index d76bcdb295cbdabff64d251d7260d2894da7cdc8..c5dd546aac5677f47e5edc6b41da553fc951147a 100644 (file)
@@ -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
@@ -563,6 +599,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.  */
index 277b8fd473761c46ecb084d5d913bde89a0c51ba..9c3158a9bf953cc9e096b34e63d044d32066763a 100644 (file)
@@ -513,6 +513,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",
+                pd->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);
@@ -881,6 +886,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;
            }
index 6f49fdbaa7c321e5e455eea1eacbe102230eb0ec..340d1255e181a86a81b99956c8b17ceebb43ab1b 100644 (file)
@@ -532,6 +532,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: mips.ehb, mips.ihb, and mips.pause before slli.  */
+{"mips.ehb", 0, INSN_CLASS_XMIPSEXECTL, "", MATCH_MIPS_EHB, MASK_MIPS_EHB, match_opcode, 0 },
+{"mips.ihb", 0, INSN_CLASS_XMIPSEXECTL, "", MATCH_MIPS_IHB, MASK_MIPS_IHB, match_opcode, 0 },
+{"mips.pause", 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 },
@@ -3522,6 +3526,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.  */
+{"mips.ccmov", 0, INSN_CLASS_XMIPSCMOV, "d,t,s,r", MATCH_MIPS_CCMOV, MASK_MIPS_CCMOV, match_opcode, 0},
+{"mips.ldp", 0, INSN_CLASS_XMIPSLSP, "d,r,Xm$(s)", MATCH_MIPS_LDP, MASK_MIPS_LDP, match_opcode, 0 },
+{"mips.lwp", 0, INSN_CLASS_XMIPSLSP, "d,r,Xm%(s)", MATCH_MIPS_LWP, MASK_MIPS_LWP, match_opcode, 0 },
+{"mips.pref", 0, INSN_CLASS_XMIPSCBOP, "Xm@,Xm#(s)", MATCH_MIPS_PREF, MASK_MIPS_PREF, match_opcode, 0 },
+{"mips.sdp", 0, INSN_CLASS_XMIPSLSP, "t,r,Xm^(s)", MATCH_MIPS_SDP, MASK_MIPS_SDP, match_opcode, 0 },
+{"mips.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}
 };