[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