[PATCH v2] RISC-V: Support MIPS extensions: xmipscbop, xmipscmov, xmipsexectl, and xmipslsp
Nelson Chu
nelson@rivosinc.com
Tue Mar 11 04:39:16 GMT 2025
Hi Jovan,
I don't know why this series was in my spam folder, so I just noticed it
for now...
On Thu, Feb 13, 2025 at 7:12 PM Jovan Dmitrovic <
jovan.dmitrovic@htecgroup.com> wrote:
> From: Chao-ying Fu <cfu@wavecomp.com>
>
> 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, 313 insertions(+)
> create mode 100644 gas/testsuite/gas/riscv/mips-insns.d
> create mode 100644 gas/testsuite/gas/riscv/mips-insns.s
>
> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
> index c9e4b03b17d..fb44c71819c 100644
> --- a/bfd/elfxx-riscv.c
> +++ b/bfd/elfxx-riscv.c
> @@ -1513,6 +1513,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}
> };
>
The spec above seems to be version v1.8, so are these extensions still the
same as v1.0? Besides, a minor stuff that I cannot find these extension
names in the spec, so maybe these names were defined somewhere else?
> @@ -2812,6 +2816,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_*"));
> diff --git a/gas/NEWS b/gas/NEWS
> index 6c5af12178f..63e55c7593e 100644
> --- a/gas/NEWS
> +++ b/gas/NEWS
> @@ -40,6 +40,12 @@ Changes in 2.44:
> for example, .cfi_offset r1,8, .cfi_offset ra,8, .cfi_offset $r1,8,
> .cfi_offset $ra,8.
>
> +* Add support for RISC-V Zcmp (cm.mva01s, cm.mvsa01), Smrnmi, S[sm]dbltrp,
> + 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.
>
This seems outdated.
> Changes in 2.43:
>
> * Add support for LoongArch .option for fine-grained control of assembly
> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
> index ac1a10aa5e4..9db337108a1 100644
> --- a/gas/config/tc-riscv.c
> +++ b/gas/config/tc-riscv.c
> @@ -1758,6 +1758,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;
> }
> @@ -4179,6 +4194,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;
> }
> diff --git a/gas/testsuite/gas/riscv/march-help.l
> b/gas/testsuite/gas/riscv/march-help.l
> index f92c98fc4c5..59a1c0476ec 100644
> --- a/gas/testsuite/gas/riscv/march-help.l
> +++ b/gas/testsuite/gas/riscv/march-help.l
> @@ -166,3 +166,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
> index 00000000000..922be836ec5
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mips-insns.d
> @@ -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\)
> diff --git a/gas/testsuite/gas/riscv/mips-insns.s
> b/gas/testsuite/gas/riscv/mips-insns.s
> new file mode 100644
> index 00000000000..820be76ff8c
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mips-insns.s
> @@ -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
> diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
> index 71ad7fff84d..de8816275a6 100644
> --- a/include/opcode/riscv-opc.h
> +++ b/include/opcode/riscv-opc.h
> @@ -3786,6 +3786,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
> @@ -4923,6 +4942,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(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. */
> diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
> index 6bcea638025..3d9e23379d3 100644
> --- a/include/opcode/riscv.h
> +++ b/include/opcode/riscv.h
> @@ -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
> @@ -561,6 +597,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. */
> diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
> index d67b2c2aaf0..7d5b781201a 100644
> --- a/opcodes/riscv-dis.c
> +++ b/opcodes/riscv-dis.c
> @@ -506,6 +506,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);
> @@ -874,6 +879,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;
> }
> diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
> index ceb94a563e2..5d95f34e1f8 100644
> --- a/opcodes/riscv-opc.c
> +++ b/opcodes/riscv-opc.c
> @@ -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: 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 },
> @@ -3510,6 +3514,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 },
>
According to riscv toolchain conventions spec,
https://github.com/riscv-non-isa/riscv-toolchain-conventions/blob/main/src/toolchain-conventions.adoc#conventions-for-vendor-extensions
A vendor extension needs a prefix, and the instruction mnemonic also need
the prefix. I see mips already have the prefix "mips" for above
extension names, so the vendor instructions will also need the same prefix
"mips.", for example, mips.pause and mips.pref.
Thanks
Nelson
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://sourceware.org/pipermail/binutils/attachments/20250311/c9b3628e/attachment-0001.htm>
More information about the Binutils
mailing list