public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2] RISC-V: Supports Zcb extension.
@ 2023-07-12 12:40 Jiawei
  2023-07-18  3:49 ` Nelson Chu
  0 siblings, 1 reply; 2+ messages in thread
From: Jiawei @ 2023-07-12 12:40 UTC (permalink / raw)
  To: binutils
  Cc: nelson, kito.cheng, palmer, jbeulich, christoph.muellner,
	jeremy.bennett, mary.bennett, nandni.jamnadas, charlie.keaney,
	simon.cook, tariq.kurd, gaofei, sinan.lin, wuwei2016, shihua,
	shiyulong, chenyixuan, Jiawei

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;
+		      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


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH v2] RISC-V: Supports Zcb extension.
  2023-07-12 12:40 [PATCH v2] RISC-V: Supports Zcb extension Jiawei
@ 2023-07-18  3:49 ` Nelson Chu
  0 siblings, 0 replies; 2+ messages in thread
From: Nelson Chu @ 2023-07-18  3:49 UTC (permalink / raw)
  To: Jiawei
  Cc: binutils, kito.cheng, palmer, jbeulich, christoph.muellner,
	jeremy.bennett, mary.bennett, nandni.jamnadas, charlie.keaney,
	simon.cook, tariq.kurd, gaofei, sinan.lin, wuwei2016, shihua,
	shiyulong, chenyixuan

[-- Attachment #1: Type: text/plain, Size: 28422 bytes --]

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
>
>

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-07-18  3:49 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-12 12:40 [PATCH v2] RISC-V: Supports Zcb extension Jiawei
2023-07-18  3:49 ` Nelson Chu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).