[PATCH v2] RISC-V: Supports Zcb extension.
Nelson Chu
nelson@rivosinc.com
Tue Jul 18 03:49:45 GMT 2023
Thanks, committed with minor indent fixes and the following changes...
On Wed, Jul 12, 2023 at 8:40 PM Jiawei <jiawei@iscas.ac.cn> wrote:
> This patch support Zcb extension, contains new compressed instructions,
> some instructions depend on other existed extension, like 'zba', 'zbb'
> and 'zmmul'. Zcb also imply Zca extension to enable the compressing
> features.
>
> V2: Move operands definations into 'W', refined testcases as Nelson's
> suggestions.
>
> Co-Authored by: Charlie Keaney <charlie.keaney@embecosm.com>
> Co-Authored by: Mary Bennett <mary.bennett@embecosm.com>
> Co-Authored by: Nandni Jamnadas <nandni.jamnadas@embecosm.com>
> Co-Authored by: Sinan Lin <sinan.lin@linux.alibaba.com>
> Co-Authored by: Simon Cook <simon.cook@embecosm.com>
> Co-Authored by: Shihua Liao <shihua@iscas.ac.cn>
> Co-Authored by: Yulong Shi <yulong@iscas.ac.cn>
>
> bfd/ChangeLog:
>
> * elfxx-riscv.c (riscv_multi_subset_supports): New extension.
> (riscv_multi_subset_supports_ext): Ditto.
>
> gas/ChangeLog:
>
> * config/tc-riscv.c (validate_riscv_insn): New operators.
> (riscv_ip): Ditto.
> * testsuite/gas/riscv/zcb.d: New test.
> * testsuite/gas/riscv/zcb.s: New test.
>
> include/ChangeLog:
>
> * opcode/riscv-opc.h (MATCH_C_LBU): New opcode.
> (MASK_C_LBU): New mask.
> (MATCH_C_LHU): New opcode.
> (MASK_C_LHU): New mask.
> (MATCH_C_LH): New opcode.
> (MASK_C_LH): New mask.
> (MATCH_C_SB): New opcode.
> (MASK_C_SB): New mask.
> (MATCH_C_SH): New opcode.
> (MASK_C_SH): New mask.
> (MATCH_C_ZEXT_B): New opcode.
> (MASK_C_ZEXT_B): New mask.
> (MATCH_C_SEXT_B): New opcode.
> (MASK_C_SEXT_B): New mask.
> (MATCH_C_ZEXT_H): New opcode.
> (MASK_C_ZEXT_H): New mask.
> (MATCH_C_SEXT_H): New opcode.
> (MASK_C_SEXT_H): New mask.
> (MATCH_C_ZEXT_W): New opcode.
> (MASK_C_ZEXT_W): New mask.
> (MATCH_C_NOT): New opcode.
> (MASK_C_NOT): New mask.
> (MATCH_C_MUL): New opcode.
> (MASK_C_MUL): New mask.
> (DECLARE_INSN): New opcode.
> * opcode/riscv.h (EXTRACT_ZCB_BYTE_UIMM): New inline func.
> (EXTRACT_ZCB_HALFWORD_UIMM): Ditto.
> (ENCODE_ZCB_BYTE_UIMM): Ditto.
> (ENCODE_ZCB_HALFWORD_UIMM): Ditto.
> (VALID_ZCB_BYTE_UIMM): Ditto.
> (VALID_ZCB_HALFWORD_UIMM): Ditto.
> (enum riscv_insn_class): New extension class.
>
> opcodes/ChangeLog:
>
> * riscv-dis.c (print_insn_args): New operators.
> * riscv-opc.c: New instructions.
>
> ---
> bfd/elfxx-riscv.c | 21 ++++++++++++++
> gas/config/tc-riscv.c | 54 ++++++++++++++++++++++++++++++++++-
> gas/testsuite/gas/riscv/zcb.d | 32 +++++++++++++++++++++
> gas/testsuite/gas/riscv/zcb.s | 25 ++++++++++++++++
> include/opcode/riscv-opc.h | 38 ++++++++++++++++++++++++
> include/opcode/riscv.h | 14 +++++++++
> opcodes/riscv-dis.c | 14 +++++++++
> opcodes/riscv-opc.c | 28 ++++++++++++++++++
> 8 files changed, 225 insertions(+), 1 deletion(-)
> create mode 100644 gas/testsuite/gas/riscv/zcb.d
> create mode 100644 gas/testsuite/gas/riscv/zcb.s
>
> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
> index 25864a8cf89..06e48b8a9f2 100644
> --- a/bfd/elfxx-riscv.c
> +++ b/bfd/elfxx-riscv.c
> @@ -1173,6 +1173,7 @@ static struct riscv_implicit_subset
> riscv_implicit_subsets[] =
> {"zvksc", "zvbc", check_implicit_always},
> {"zcf", "zca", check_implicit_always},
> {"zcd", "zca", check_implicit_always},
> + {"zcb", "zca", check_implicit_always},
> {"smaia", "ssaia", check_implicit_always},
> {"smstateen", "ssstateen", check_implicit_always},
> {"smepmp", "zicsr", check_implicit_always},
> @@ -1307,6 +1308,7 @@ static struct riscv_supported_ext
> riscv_supported_std_z_ext[] =
> {"zvl65536b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
> {"ztso", ISA_SPEC_CLASS_DRAFT, 0, 1, 0 },
> {"zca", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
> + {"zcb", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
> {"zcf", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
> {"zcd", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
> {NULL, 0, 0, 0, 0}
> @@ -2494,6 +2496,17 @@ riscv_multi_subset_supports (riscv_parse_subset_t
> *rps,
> return riscv_subset_supports (rps, "zvksed");
> case INSN_CLASS_ZVKSH:
> return riscv_subset_supports (rps, "zvksh");
> + case INSN_CLASS_ZCB:
> + return riscv_subset_supports (rps, "zcb");
> + case INSN_CLASS_ZCB_AND_ZBB:
> + return riscv_subset_supports (rps, "zcb")
> + && riscv_subset_supports (rps, "zbb");
> + case INSN_CLASS_ZCB_AND_ZBA:
> + return riscv_subset_supports (rps, "zcb")
> + && riscv_subset_supports (rps, "zba");
> + case INSN_CLASS_ZCB_AND_ZMMUL:
> + return riscv_subset_supports (rps, "zcb")
> + && riscv_subset_supports (rps, "zmmul");
> case INSN_CLASS_SVINVAL:
> return riscv_subset_supports (rps, "svinval");
> case INSN_CLASS_H:
> @@ -2698,6 +2711,14 @@ riscv_multi_subset_supports_ext
> (riscv_parse_subset_t *rps,
> return _("zvksed");
> case INSN_CLASS_ZVKSH:
> return _("zvksh");
> + case INSN_CLASS_ZCB:
> + return "zcb";
> + case INSN_CLASS_ZCB_AND_ZBA:
> + return _("zcb' and `zba");
> + case INSN_CLASS_ZCB_AND_ZBB:
> + return _("zcb' and `zbb");
> + case INSN_CLASS_ZCB_AND_ZMMUL:
> + return _("zcb' and `zmmul', or `zcb' and `m");
> case INSN_CLASS_SVINVAL:
> return "svinval";
> case INSN_CLASS_H:
> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
> index 2eb0d1877ee..3d53edb3833 100644
> --- a/gas/config/tc-riscv.c
> +++ b/gas/config/tc-riscv.c
> @@ -1426,6 +1426,18 @@ validate_riscv_insn (const struct riscv_opcode
> *opc, int length)
> goto unknown_validate_operand;
> }
> break;
> + case 'c':
> + switch (*++oparg)
> + {
> + /* byte immediate operators, load/store byte insns. */
> + case 'h': used_bits |= ENCODE_ZCB_HALFWORD_UIMM (-1U);
> break;
> + /* halfword immediate operators, load/store halfword
> insns. */
> + case 'b': used_bits |= ENCODE_ZCB_BYTE_UIMM (-1U); break;
> + case 'f': break;
> + default:
> + goto unknown_validate_operand;
> + }
> + break;
> default:
> goto unknown_validate_operand;
> }
> @@ -2935,7 +2947,6 @@ riscv_ip (char *str, struct riscv_cl_insn *ip,
> expressionS *imm_expr,
> goto unknown_riscv_ip_operand;
> }
> break;
> -
> default:
> goto unknown_riscv_ip_operand;
> }
> @@ -3559,11 +3570,52 @@ riscv_ip (char *str, struct riscv_cl_insn *ip,
> expressionS *imm_expr,
> goto unknown_riscv_ip_operand;
> }
> break;
> + case 'c':
> + switch (*++oparg)
> + {
> + case 'h': /* immediate field for c.lh/c.lhu/c.sh. */
> + /* handle cases, such as c.sh rs2', (rs1') */
> + if (riscv_handle_implicit_zero_offset (imm_expr,
> asarg))
> + continue;
> + if (my_getSmallExpression (imm_expr, imm_reloc,
> asarg, p)
> + || imm_expr->X_op != O_constant
> + || !VALID_ZCB_HALFWORD_UIMM ((valueT)
> imm_expr->X_add_number))
> + break;
> + ip->insn_opcode |= ENCODE_ZCB_HALFWORD_UIMM
> (imm_expr->X_add_number);
> + goto rvc_imm_done;
> +
> + case 'b': /* immediate field for c.lbu/c.sb. */
> + /* handle cases, such as c.lbu rd', (rs1') */
> + if (riscv_handle_implicit_zero_offset (imm_expr,
> asarg))
> + continue;
> + if (my_getSmallExpression (imm_expr, imm_reloc,
> asarg, p)
> + || imm_expr->X_op != O_constant
> + || !VALID_ZCB_BYTE_UIMM ((valueT)
> imm_expr->X_add_number))
> + break;
> + ip->insn_opcode |= ENCODE_ZCB_BYTE_UIMM
> (imm_expr->X_add_number);
> + goto rvc_imm_done;
> +
> + case 'f': /* operand for matching immediate 255.
> */
> + if (my_getSmallExpression (imm_expr, imm_reloc,
> asarg, p)
> + || imm_expr->X_op != O_constant
> + || imm_expr->X_add_number != 255)
> + break;
> + /* this operand is used for matching immediate 255,
> and
> + we do not write anything to encoding by this
> operand. */
> + asarg = expr_end;
>
... This should already be updated to expr_parse_end.
Thanks
Nelson
> + imm_expr->X_op = O_absent;
> + continue;
> +
> + default:
> + goto unknown_riscv_ip_operand;
> + }
> + break;
> default:
> goto unknown_riscv_ip_operand;
> }
> break;
>
> +
> case 'X': /* Integer immediate. */
> {
> size_t n;
> diff --git a/gas/testsuite/gas/riscv/zcb.d b/gas/testsuite/gas/riscv/zcb.d
> new file mode 100644
> index 00000000000..26a122b205c
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zcb.d
> @@ -0,0 +1,32 @@
> +#as: -march=rv64im_zba_zbb_zcb
> +#objdump: -d -Mno-aliases
> +
> +.*:[ ]+file format .*
> +
> +Disassembly of section .text:
> +
> +0+000 <target>:
> +[ ]+[0-9a-f]+:[ ]+8020[ ]+c.lbu[ ]+s0,2\(s0\)
> +[ ]+[0-9a-f]+:[ ]+8380[ ]+c.lbu[ ]+s0,0\(a5\)
> +[ ]+[0-9a-f]+:[ ]+8420[ ]+c.lhu[ ]+s0,2\(s0\)
> +[ ]+[0-9a-f]+:[ ]+8780[ ]+c.lhu[ ]+s0,0\(a5\)
> +[ ]+[0-9a-f]+:[ ]+8460[ ]+c.lh[ ]+s0,2\(s0\)
> +[ ]+[0-9a-f]+:[ ]+87c0[ ]+c.lh[ ]+s0,0\(a5\)
> +[ ]+[0-9a-f]+:[ ]+8820[ ]+c.sb[ ]+s0,2\(s0\)
> +[ ]+[0-9a-f]+:[ ]+8b80[ ]+c.sb[ ]+s0,0\(a5\)
> +[ ]+[0-9a-f]+:[ ]+8c20[ ]+c.sh[ ]+s0,2\(s0\)
> +[ ]+[0-9a-f]+:[ ]+8f80[ ]+c.sh[ ]+s0,0\(a5\)
> +[ ]+[0-9a-f]+:[ ]+9c61[ ]+c.zext.b[ ]+s0
> +[ ]+[0-9a-f]+:[ ]+9fe1[ ]+c.zext.b[ ]+a5
> +[ ]+[0-9a-f]+:[ ]+9c65[ ]+c.sext.b[ ]+s0
> +[ ]+[0-9a-f]+:[ ]+9fe5[ ]+c.sext.b[ ]+a5
> +[ ]+[0-9a-f]+:[ ]+9c69[ ]+c.zext.h[ ]+s0
> +[ ]+[0-9a-f]+:[ ]+9fe9[ ]+c.zext.h[ ]+a5
> +[ ]+[0-9a-f]+:[ ]+9c6d[ ]+c.sext.h[ ]+s0
> +[ ]+[0-9a-f]+:[ ]+9fed[ ]+c.sext.h[ ]+a5
> +[ ]+[0-9a-f]+:[ ]+9c71[ ]+c.zext.w[ ]+s0
> +[ ]+[0-9a-f]+:[ ]+9ff1[ ]+c.zext.w[ ]+a5
> +[ ]+[0-9a-f]+:[ ]+9c75[ ]+c.not[ ]+s0
> +[ ]+[0-9a-f]+:[ ]+9ff5[ ]+c.not[ ]+a5
> +[ ]+[0-9a-f]+:[ ]+9c5d[ ]+c.mul[ ]+s0,a5
> +[ ]+[0-9a-f]+:[ ]+9cd1[ ]+c.mul[ ]+s1,a2
> diff --git a/gas/testsuite/gas/riscv/zcb.s b/gas/testsuite/gas/riscv/zcb.s
> new file mode 100644
> index 00000000000..2e70ab29c30
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/zcb.s
> @@ -0,0 +1,25 @@
> +target:
> + lbu x8,2(x8)
> + c.lbu x8,(x15)
> + lhu x8,2(x8)
> + c.lhu x8,(x15)
> + lh x8,2(x8)
> + c.lh x8,(x15)
> + sb x8,2(x8)
> + c.sb x8,(x15)
> + sh x8,2(x8)
> + c.sh x8,(x15)
> + zext.b x8,x8
> + c.zext.b x15
> + sext.b x8,x8
> + c.sext.b x15
> + zext.h x8,x8
> + c.zext.h x15
> + sext.h x8,x8
> + c.sext.h x15
> + zext.w x8,x8
> + c.zext.w x15
> + not x8,x8
> + c.not x15
> + mul x8,x8,x15
> + c.mul x9,x12
> diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
> index 90f44153750..53f5f200508 100644
> --- a/include/opcode/riscv-opc.h
> +++ b/include/opcode/riscv-opc.h
> @@ -2210,6 +2210,31 @@
> #define MASK_VSM3C_VI 0xfe00707f
> #define MATCH_VSM3ME_VV 0x82002077
> #define MASK_VSM3ME_VV 0xfe00707f
> +/* Zcb instructions. */
> +#define MATCH_C_LBU 0x8000
> +#define MASK_C_LBU 0xfc03
> +#define MATCH_C_LHU 0x8400
> +#define MASK_C_LHU 0xfc43
> +#define MATCH_C_LH 0x8440
> +#define MASK_C_LH 0xfc43
> +#define MATCH_C_SB 0x8800
> +#define MASK_C_SB 0xfc03
> +#define MATCH_C_SH 0x8c00
> +#define MASK_C_SH 0xfc43
> +#define MATCH_C_ZEXT_B 0x9c61
> +#define MASK_C_ZEXT_B 0xfc7f
> +#define MATCH_C_SEXT_B 0x9c65
> +#define MASK_C_SEXT_B 0xfc7f
> +#define MATCH_C_ZEXT_H 0x9c69
> +#define MASK_C_ZEXT_H 0xfc7f
> +#define MATCH_C_SEXT_H 0x9c6d
> +#define MASK_C_SEXT_H 0xfc7f
> +#define MATCH_C_ZEXT_W 0x9c71
> +#define MASK_C_ZEXT_W 0xfc7f
> +#define MATCH_C_NOT 0x9c75
> +#define MASK_C_NOT 0xfc7f
> +#define MATCH_C_MUL 0x9c41
> +#define MASK_C_MUL 0xfc63
> /* Svinval instruction. */
> #define MATCH_SINVAL_VMA 0x16000073
> #define MASK_SINVAL_VMA 0xfe007fff
> @@ -3367,6 +3392,19 @@ DECLARE_INSN(vsm4r_vv, MATCH_VSM4R_VV,
> MASK_VSM4R_VV)
> /* Zvksh instructions. */
> DECLARE_INSN(vsm3c_vi, MATCH_VSM3C_VI, MASK_VSM3C_VI)
> DECLARE_INSN(vsm3me_vv, MATCH_VSM3ME_VV, MASK_VSM3ME_VV)
> +/* Zcb instructions. */
> +DECLARE_INSN(c_sext_b, MATCH_C_SEXT_B, MASK_C_SEXT_B)
> +DECLARE_INSN(c_sext_h, MATCH_C_SEXT_H, MASK_C_SEXT_H)
> +DECLARE_INSN(c_zext_b, MATCH_C_ZEXT_B, MASK_C_ZEXT_B)
> +DECLARE_INSN(c_zext_h, MATCH_C_ZEXT_H, MASK_C_ZEXT_H)
> +DECLARE_INSN(c_zext_w, MATCH_C_ZEXT_W, MASK_C_ZEXT_W)
> +DECLARE_INSN(c_mul, MATCH_C_MUL, MASK_C_MUL)
> +DECLARE_INSN(c_not, MATCH_C_NOT, MASK_C_NOT)
> +DECLARE_INSN(c_lbu, MATCH_C_LBU, MASK_C_LBU)
> +DECLARE_INSN(c_lhu, MATCH_C_LHU, MASK_C_LHU)
> +DECLARE_INSN(c_lh, MATCH_C_LH, MASK_C_LH)
> +DECLARE_INSN(c_sb, MATCH_C_SB, MASK_C_SB)
> +DECLARE_INSN(c_sh, MATCH_C_SH, MASK_C_SH)
> /* Vendor-specific (T-Head) XTheadBa instructions. */
> DECLARE_INSN(th_addsl, MATCH_TH_ADDSL, MASK_TH_ADDSL)
> /* Vendor-specific (T-Head) XTheadBb instructions. */
> diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
> index 739d6dafae9..808f3657303 100644
> --- a/include/opcode/riscv.h
> +++ b/include/opcode/riscv.h
> @@ -108,6 +108,10 @@ static inline unsigned int riscv_insn_length (insn_t
> insn)
> (RV_X(x, 20, 10))
> #define EXTRACT_RVV_VC_IMM(x) \
> (RV_X(x, 20, 11))
> +#define EXTRACT_ZCB_BYTE_UIMM(x) \
> + (RV_X(x, 6, 1) | (RV_X(x, 5, 1) << 1))
> +#define EXTRACT_ZCB_HALFWORD_UIMM(x) \
> + (RV_X(x, 5, 1) << 1)
>
> #define ENCODE_ITYPE_IMM(x) \
> (RV_X(x, 0, 12) << 20)
> @@ -155,6 +159,10 @@ static inline unsigned int riscv_insn_length (insn_t
> insn)
> (RV_X(x, 0, 11) << 20)
> #define ENCODE_RVV_VI_UIMM6(x) \
> (RV_X(x, 0, 5) << 15 | RV_X(x, 5, 1) << 26)
> +#define ENCODE_ZCB_BYTE_UIMM(x) \
> + ((RV_X(x, 0, 1) << 6) | (RV_X(x, 1, 1) << 5))
> +#define ENCODE_ZCB_HALFWORD_UIMM(x) \
> + (RV_X(x, 1, 1) << 5)
>
> #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))
> @@ -180,6 +188,8 @@ static inline unsigned int riscv_insn_length (insn_t
> insn)
> #define VALID_CJTYPE_IMM(x) (EXTRACT_CJTYPE_IMM(ENCODE_CJTYPE_IMM(x)) ==
> (x))
> #define VALID_RVV_VB_IMM(x) (EXTRACT_RVV_VB_IMM(ENCODE_RVV_VB_IMM(x)) ==
> (x))
> #define VALID_RVV_VC_IMM(x) (EXTRACT_RVV_VC_IMM(ENCODE_RVV_VC_IMM(x)) ==
> (x))
> +#define VALID_ZCB_BYTE_UIMM(x)
> (EXTRACT_ZCB_BYTE_UIMM(ENCODE_ZCB_BYTE_UIMM(x)) == (x))
> +#define VALID_ZCB_HALFWORD_UIMM(x)
> (EXTRACT_ZCB_HALFWORD_UIMM(ENCODE_ZCB_HALFWORD_UIMM(x)) == (x))
>
> #define RISCV_RTYPE(insn, rd, rs1, rs2) \
> ((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ((rs1) << OP_SH_RS1) | ((rs2)
> << OP_SH_RS2))
> @@ -421,6 +431,10 @@ enum riscv_insn_class
> INSN_CLASS_ZVKNHA_OR_ZVKNHB,
> INSN_CLASS_ZVKSED,
> INSN_CLASS_ZVKSH,
> + INSN_CLASS_ZCB,
> + INSN_CLASS_ZCB_AND_ZBA,
> + INSN_CLASS_ZCB_AND_ZBB,
> + INSN_CLASS_ZCB_AND_ZMMUL,
> INSN_CLASS_SVINVAL,
> INSN_CLASS_ZICBOM,
> INSN_CLASS_ZICBOP,
> diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
> index 827d9b67437..2826248f8af 100644
> --- a/opcodes/riscv-dis.c
> +++ b/opcodes/riscv-dis.c
> @@ -614,6 +614,20 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma
> pc, disassemble_info *info
> goto undefined_modifier;
> }
> break;
> + case 'c': /* Zcb extension 16 bits length instruction
> fields. */
> + switch (*++oparg)
> + {
> + case 'b':
> + print (info->stream, dis_style_immediate, "%d",
> + (int)EXTRACT_ZCB_BYTE_UIMM (l));
> + break;
> + case 'h':
> + print (info->stream, dis_style_immediate, "%d",
> + (int)EXTRACT_ZCB_HALFWORD_UIMM (l));
> + break;
> + default: break;
> + }
> + break;
> default:
> goto undefined_modifier;
> }
> diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
> index 533e3f4a079..6a854736fec 100644
> --- a/opcodes/riscv-opc.c
> +++ b/opcodes/riscv-opc.c
> @@ -380,12 +380,14 @@ const struct riscv_opcode riscv_opcodes[] =
> {"mv", 0, INSN_CLASS_I, "d,s", MATCH_ADDI,
> MASK_ADDI|MASK_IMM, match_opcode, INSN_ALIAS },
> {"move", 0, INSN_CLASS_C, "d,CV", MATCH_C_MV, MASK_C_MV,
> match_c_add, INSN_ALIAS },
> {"move", 0, INSN_CLASS_I, "d,s", MATCH_ADDI,
> MASK_ADDI|MASK_IMM, match_opcode, INSN_ALIAS },
> +{"zext.b", 0, INSN_CLASS_ZCB, "Cs,Cw", MATCH_C_ZEXT_B,
> MASK_C_ZEXT_B, match_opcode, INSN_ALIAS },
> {"zext.b", 0, INSN_CLASS_I, "d,s", MATCH_ANDI|ENCODE_ITYPE_IMM
> (255), MASK_ANDI | MASK_IMM, match_opcode, INSN_ALIAS },
> {"and", 0, INSN_CLASS_C, "Cs,Cw,Ct", MATCH_C_AND, MASK_C_AND,
> match_opcode, INSN_ALIAS },
> {"and", 0, INSN_CLASS_C, "Cs,Ct,Cw", MATCH_C_AND, MASK_C_AND,
> match_opcode, INSN_ALIAS },
> {"and", 0, INSN_CLASS_C, "Cs,Cw,Co", MATCH_C_ANDI, MASK_C_ANDI,
> match_opcode, INSN_ALIAS },
> {"and", 0, INSN_CLASS_I, "d,s,t", MATCH_AND, MASK_AND,
> match_opcode, 0 },
> {"and", 0, INSN_CLASS_I, "d,s,j", MATCH_ANDI, MASK_ANDI,
> match_opcode, INSN_ALIAS },
> +{"andi", 0, INSN_CLASS_ZCB, "Cs,Cw,Wcf",MATCH_C_ZEXT_B,
> MASK_C_ZEXT_B, match_opcode, INSN_ALIAS },
> {"andi", 0, INSN_CLASS_C, "Cs,Cw,Co", MATCH_C_ANDI, MASK_C_ANDI,
> match_opcode, INSN_ALIAS },
> {"andi", 0, INSN_CLASS_I, "d,s,j", MATCH_ANDI, MASK_ANDI,
> match_opcode, 0 },
> {"beqz", 0, INSN_CLASS_C, "Cs,Cp", MATCH_C_BEQZ, MASK_C_BEQZ,
> match_opcode, INSN_ALIAS|INSN_CONDBRANCH },
> @@ -449,16 +451,20 @@ const struct riscv_opcode riscv_opcodes[] =
> {"sub", 0, INSN_CLASS_I, "d,s,t", MATCH_SUB, MASK_SUB,
> match_opcode, 0 },
> {"lb", 0, INSN_CLASS_I, "d,o(s)", MATCH_LB, MASK_LB,
> match_opcode, INSN_DREF|INSN_1_BYTE },
> {"lb", 0, INSN_CLASS_I, "d,A", 0, (int) M_LB, match_never,
> INSN_MACRO },
> +{"lbu", 0, INSN_CLASS_ZCB, "Ct,Wcb(Cs)", MATCH_C_LBU, MASK_C_LBU,
> match_opcode, INSN_ALIAS|INSN_DREF|INSN_1_BYTE },
> {"lbu", 0, INSN_CLASS_I, "d,o(s)", MATCH_LBU, MASK_LBU,
> match_opcode, INSN_DREF|INSN_1_BYTE },
> {"lbu", 0, INSN_CLASS_I, "d,A", 0, (int) M_LBU,
> match_never, INSN_MACRO },
> +{"lh", 0, INSN_CLASS_ZCB, "Ct,Wch(Cs)", MATCH_C_LH, MASK_C_LH,
> match_opcode, INSN_ALIAS|INSN_DREF|INSN_2_BYTE },
> {"lh", 0, INSN_CLASS_I, "d,o(s)", MATCH_LH, MASK_LH,
> match_opcode, INSN_DREF|INSN_2_BYTE },
> {"lh", 0, INSN_CLASS_I, "d,A", 0, (int) M_LH, match_never,
> INSN_MACRO },
> +{"lhu", 0, INSN_CLASS_ZCB, "Ct,Wch(Cs)", MATCH_C_LHU, MASK_C_LHU,
> match_opcode, INSN_ALIAS|INSN_DREF|INSN_2_BYTE },
> {"lhu", 0, INSN_CLASS_I, "d,o(s)", MATCH_LHU, MASK_LHU,
> match_opcode, INSN_DREF|INSN_2_BYTE },
> {"lhu", 0, INSN_CLASS_I, "d,A", 0, (int) M_LHU,
> match_never, INSN_MACRO },
> {"lw", 0, INSN_CLASS_C, "d,Cm(Cc)", MATCH_C_LWSP, MASK_C_LWSP,
> match_rd_nonzero, INSN_ALIAS|INSN_DREF|INSN_4_BYTE },
> {"lw", 0, INSN_CLASS_C, "Ct,Ck(Cs)", MATCH_C_LW, MASK_C_LW,
> match_opcode, INSN_ALIAS|INSN_DREF|INSN_4_BYTE },
> {"lw", 0, INSN_CLASS_I, "d,o(s)", MATCH_LW, MASK_LW,
> match_opcode, INSN_DREF|INSN_4_BYTE },
> {"lw", 0, INSN_CLASS_I, "d,A", 0, (int) M_LW, match_never,
> INSN_MACRO },
> +{"not", 0, INSN_CLASS_ZCB, "Cs,Cw", MATCH_C_NOT, MASK_C_NOT,
> match_opcode, INSN_ALIAS },
> {"not", 0, INSN_CLASS_I, "d,s", MATCH_XORI|MASK_IMM,
> MASK_XORI|MASK_IMM, match_opcode, INSN_ALIAS },
> {"or", 0, INSN_CLASS_I, "d,s,j", MATCH_ORI, MASK_ORI,
> match_opcode, INSN_ALIAS },
> {"or", 0, INSN_CLASS_C, "Cs,Cw,Ct", MATCH_C_OR, MASK_C_OR,
> match_opcode, INSN_ALIAS },
> @@ -478,8 +484,10 @@ const struct riscv_opcode riscv_opcodes[] =
> {"sltu", 0, INSN_CLASS_I, "d,s,j", MATCH_SLTIU, MASK_SLTIU,
> match_opcode, INSN_ALIAS },
> {"sgt", 0, INSN_CLASS_I, "d,t,s", MATCH_SLT, MASK_SLT,
> match_opcode, INSN_ALIAS },
> {"sgtu", 0, INSN_CLASS_I, "d,t,s", MATCH_SLTU, MASK_SLTU,
> match_opcode, INSN_ALIAS },
> +{"sb", 0, INSN_CLASS_ZCB, "Ct,Wcb(Cs)", MATCH_C_SB, MASK_C_SB,
> match_opcode, INSN_DREF|INSN_1_BYTE|INSN_ALIAS },
> {"sb", 0, INSN_CLASS_I, "t,q(s)", MATCH_SB, MASK_SB,
> match_opcode, INSN_DREF|INSN_1_BYTE },
> {"sb", 0, INSN_CLASS_I, "t,A,s", 0, (int) M_SB, match_never,
> INSN_MACRO },
> +{"sh", 0, INSN_CLASS_ZCB, "Ct,Wch(Cs)", MATCH_C_SH, MASK_C_SH,
> match_opcode, INSN_DREF|INSN_2_BYTE|INSN_ALIAS },
> {"sh", 0, INSN_CLASS_I, "t,q(s)", MATCH_SH, MASK_SH,
> match_opcode, INSN_DREF|INSN_2_BYTE },
> {"sh", 0, INSN_CLASS_I, "t,A,s", 0, (int) M_SH, match_never,
> INSN_MACRO },
> {"sw", 0, INSN_CLASS_C, "CV,CM(Cc)", MATCH_C_SWSP, MASK_C_SWSP,
> match_opcode, INSN_ALIAS|INSN_DREF|INSN_4_BYTE },
> @@ -626,6 +634,7 @@ const struct riscv_opcode riscv_opcodes[] =
> {"amominu.d.aqrl", 64, INSN_CLASS_A, "d,t,0(s)",
> MATCH_AMOMINU_D|MASK_AQRL, MASK_AMOMINU_D|MASK_AQRL, match_opcode,
> INSN_DREF|INSN_8_BYTE },
>
> /* Multiply/Divide instruction subset. */
> +{"mul", 0, INSN_CLASS_ZCB_AND_ZMMUL, "Cs,Cw,Ct", MATCH_C_MUL,
> MASK_C_MUL, match_opcode, INSN_ALIAS },
> {"mul", 0, INSN_CLASS_ZMMUL, "d,s,t", MATCH_MUL, MASK_MUL,
> match_opcode, 0 },
> {"mulh", 0, INSN_CLASS_ZMMUL, "d,s,t", MATCH_MULH, MASK_MULH,
> match_opcode, 0 },
> {"mulhu", 0, INSN_CLASS_ZMMUL, "d,s,t", MATCH_MULHU, MASK_MULHU,
> match_opcode, 0 },
> @@ -1016,10 +1025,13 @@ const struct riscv_opcode riscv_opcodes[] =
> {"max", 0, INSN_CLASS_ZBB, "d,s,t", MATCH_MAX, MASK_MAX,
> match_opcode, 0 },
> {"minu", 0, INSN_CLASS_ZBB, "d,s,t", MATCH_MINU, MASK_MINU,
> match_opcode, 0 },
> {"maxu", 0, INSN_CLASS_ZBB, "d,s,t", MATCH_MAXU, MASK_MAXU,
> match_opcode, 0 },
> +{"sext.b", 0, INSN_CLASS_ZCB_AND_ZBB, "Cs,Cw", MATCH_C_SEXT_B,
> MASK_C_SEXT_B, match_opcode, INSN_ALIAS },
> {"sext.b", 0, INSN_CLASS_ZBB, "d,s", MATCH_SEXT_B, MASK_SEXT_B,
> match_opcode, 0 },
> {"sext.b", 0, INSN_CLASS_I, "d,s", 0, (int) M_SEXTB,
> match_never, INSN_MACRO },
> +{"sext.h", 0, INSN_CLASS_ZCB_AND_ZBB, "Cs,Cw", MATCH_C_SEXT_H,
> MASK_C_SEXT_H, match_opcode, INSN_ALIAS },
> {"sext.h", 0, INSN_CLASS_ZBB, "d,s", MATCH_SEXT_H, MASK_SEXT_H,
> match_opcode, 0 },
> {"sext.h", 0, INSN_CLASS_I, "d,s", 0, (int) M_SEXTH,
> match_never, INSN_MACRO },
> +{"zext.h", 0, INSN_CLASS_ZCB_AND_ZBB, "Cs,Cw", MATCH_C_ZEXT_H,
> MASK_C_ZEXT_H, match_opcode, INSN_ALIAS },
> {"zext.h", 32, INSN_CLASS_ZBB, "d,s", MATCH_PACK, MASK_PACK |
> MASK_RS2, match_opcode, 0 },
> {"zext.h", 64, INSN_CLASS_ZBB, "d,s", MATCH_PACKW, MASK_PACKW |
> MASK_RS2, match_opcode, 0 },
> {"zext.h", 0, INSN_CLASS_I, "d,s", 0, (int) M_ZEXTH,
> match_never, INSN_MACRO },
> @@ -1055,6 +1067,7 @@ const struct riscv_opcode riscv_opcodes[] =
> {"sh1add.uw", 64, INSN_CLASS_ZBA, "d,s,t", MATCH_SH1ADD_UW,
> MASK_SH1ADD_UW, match_opcode, 0 },
> {"sh2add.uw", 64, INSN_CLASS_ZBA, "d,s,t", MATCH_SH2ADD_UW,
> MASK_SH2ADD_UW, match_opcode, 0 },
> {"sh3add.uw", 64, INSN_CLASS_ZBA, "d,s,t", MATCH_SH3ADD_UW,
> MASK_SH3ADD_UW, match_opcode, 0 },
> +{"zext.w", 64, INSN_CLASS_ZCB_AND_ZBA, "Cs,Cw", MATCH_C_ZEXT_W,
> MASK_C_ZEXT_W, match_opcode, INSN_ALIAS },
> {"zext.w", 64, INSN_CLASS_ZBA, "d,s", MATCH_ADD_UW, MASK_ADD_UW |
> MASK_RS2, match_opcode, INSN_ALIAS },
> {"zext.w", 64, INSN_CLASS_I, "d,s", 0, (int) M_ZEXTW,
> match_never, INSN_MACRO },
> {"add.uw", 64, INSN_CLASS_ZBA, "d,s,t", MATCH_ADD_UW, MASK_ADD_UW,
> match_opcode, 0 },
> @@ -1939,6 +1952,21 @@ const struct riscv_opcode riscv_opcodes[] =
> {"vsm3c.vi", 0, INSN_CLASS_ZVKSH, "Vd,Vt,Vj", MATCH_VSM3C_VI,
> MASK_VSM3C_VI, match_opcode, 0},
> {"vsm3me.vv", 0, INSN_CLASS_ZVKSH, "Vd,Vt,Vs", MATCH_VSM3ME_VV,
> MASK_VSM3ME_VV, match_opcode, 0},
>
> +/* ZCB instructions. */
> +{"c.lbu", 0, INSN_CLASS_ZCB, "Ct,Wcb(Cs)", MATCH_C_LBU, MASK_C_LBU,
> match_opcode, INSN_DREF|INSN_1_BYTE },
> +{"c.lhu", 0, INSN_CLASS_ZCB, "Ct,Wch(Cs)", MATCH_C_LHU, MASK_C_LHU,
> match_opcode, INSN_DREF|INSN_2_BYTE },
> +{"c.lh", 0, INSN_CLASS_ZCB, "Ct,Wch(Cs)", MATCH_C_LH, MASK_C_LH,
> match_opcode, INSN_DREF|INSN_2_BYTE },
> +{"c.sb", 0, INSN_CLASS_ZCB, "Ct,Wcb(Cs)", MATCH_C_SB, MASK_C_SB,
> match_opcode, INSN_DREF|INSN_1_BYTE },
> +{"c.sh", 0, INSN_CLASS_ZCB, "Ct,Wch(Cs)", MATCH_C_SH, MASK_C_SH,
> match_opcode, INSN_DREF|INSN_2_BYTE },
> +{"c.not", 0, INSN_CLASS_ZCB, "Cs", MATCH_C_NOT, MASK_C_NOT,
> match_opcode, 0 },
> +{"c.mul", 0, INSN_CLASS_ZCB_AND_ZMMUL, "Cs,Ct", MATCH_C_MUL,
> MASK_C_MUL, match_opcode, 0 },
> +{"c.sext.b", 0, INSN_CLASS_ZCB_AND_ZBB, "Cs", MATCH_C_SEXT_B,
> MASK_C_SEXT_B, match_opcode, 0 },
> +{"c.sext.h", 0, INSN_CLASS_ZCB_AND_ZBB, "Cs", MATCH_C_SEXT_H,
> MASK_C_SEXT_H, match_opcode, 0 },
> +{"c.zext.h", 0, INSN_CLASS_ZCB_AND_ZBB, "Cs", MATCH_C_ZEXT_H,
> MASK_C_ZEXT_H, match_opcode, 0 },
> +{"c.zext.w", 64, INSN_CLASS_ZCB_AND_ZBA, "Cs", MATCH_C_ZEXT_W,
> MASK_C_ZEXT_W, match_opcode, 0 },
> +{"c.zext.b", 0, INSN_CLASS_ZCB, "Cs", MATCH_C_ZEXT_B, MASK_C_ZEXT_B,
> match_opcode, 0 },
> +{"c.sext.w", 64, INSN_CLASS_ZCB, "d", MATCH_C_ADDIW,
> MASK_C_ADDIW|MASK_RVC_IMM, match_rd_nonzero, INSN_ALIAS },
> +
> /* Supervisor instructions. */
> {"csrr", 0, INSN_CLASS_ZICSR, "d,E", MATCH_CSRRS,
> MASK_CSRRS|MASK_RS1, match_opcode, INSN_ALIAS },
> {"csrw", 0, INSN_CLASS_ZICSR, "E,s", MATCH_CSRRW,
> MASK_CSRRW|MASK_RD, match_opcode, INSN_ALIAS },
> --
> 2.25.1
>
>
More information about the Binutils
mailing list