RISC-V: Add zilsd & zclsd support

Ref: https://github.com/riscv/riscv-zilsd/blob/main/zilsd.adoc

Signed-off-by: dysun <sundongya@nucleisys.com>

Co-developed-by: LIU Xu <liuxu@nucleisys.com>
Co-developed-by: ZHAO Fujin <zhaofujin@nucleisys.com>
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 9364442..7b9285e 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1239,6 +1239,7 @@
 
   {"zicfilp", "+zicsr", check_implicit_always},
   {"zicfiss", "+zimop,+zicsr", check_implicit_always},
+  {"zclsd", "+zca,+zilsd", check_implicit_always},
 
   {"sha", "+h,+ssstateen,+shcounterenw,+shvstvala,+shtvala,+shvstvecd,+shvsatpa,+shgatpa", check_implicit_always},
 
@@ -1382,6 +1383,7 @@
   {"zimop",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zicfiss",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zicfilp",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
+  {"zilsd",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zmmul",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"za64rs",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"za128rs",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
@@ -1462,6 +1464,7 @@
   {"zcmop",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zcmp",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {"zcmt",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
+  {"zclsd",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
   {NULL, 0, 0, 0, 0}
 };
 
@@ -2158,6 +2161,15 @@
 	(_("`xtheadvector' is conflict with the `v' extension"));
       no_conflict = false;
     }
+  if (riscv_lookup_subset (rps->subset_list, "zclsd", &subset)
+      && ((riscv_lookup_subset (rps->subset_list, "c", &subset)
+	   && riscv_lookup_subset (rps->subset_list, "f", &subset))
+	  || riscv_lookup_subset (rps->subset_list, "zcf", &subset)))
+    {
+      rps->error_handler
+	(_("`zclsd' is conflict with the `c+f'/ `zcf' extension"));
+      no_conflict = false;
+    }
   if (riscv_lookup_subset (rps->subset_list, "ssnpm", &subset) && xlen != 64)
     {
       rps->error_handler (_ ("rv%d does not support the `ssnpm' extension"),
@@ -2826,6 +2838,10 @@
     case INSN_CLASS_SMCTR_OR_SSCTR:
       return (riscv_subset_supports (rps, "smctr")
 	      || riscv_subset_supports (rps, "ssctr"));
+    case INSN_CLASS_ZILSD:
+      return riscv_subset_supports (rps, "zilsd");
+    case INSN_CLASS_ZCLSD:
+      return riscv_subset_supports (rps, "zclsd");
     case INSN_CLASS_SMRNMI:
       return riscv_subset_supports (rps, "smrnmi");
     case INSN_CLASS_SVINVAL:
@@ -3143,6 +3159,10 @@
       return "zcmt";
     case INSN_CLASS_SMCTR_OR_SSCTR:
       return _("smctr' or `ssctr");
+    case INSN_CLASS_ZILSD:
+     return "zilsd";
+    case INSN_CLASS_ZCLSD:
+      return "zclsd";
     case INSN_CLASS_SMRNMI:
       return "smrnmi";
     case INSN_CLASS_SVINVAL:
diff --git a/gas/testsuite/gas/riscv/l-s-macro-zilsd.d b/gas/testsuite/gas/riscv/l-s-macro-zilsd.d
new file mode 100644
index 0000000..c05bae6
--- /dev/null
+++ b/gas/testsuite/gas/riscv/l-s-macro-zilsd.d
@@ -0,0 +1,53 @@
+#as: -march=rv32i_zilsd
+#name: Lx/Sx macro insns for Zilsd
+#source: l-s-macro.s
+#objdump: -dwr
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+ <L>:
+[ 	]+[0-9a-f]+:[ 	]+00000517[ 	]+auipc[ 	]+a0,0x0[ 	]+[0-9a-f]+:[ 	]+R_RISCV_PCREL_HI20[ 	]+bval
+[ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX.*
+[ 	]+[0-9a-f]+:[ 	]+00050503[ 	]+lb[ 	]+a0,0\(a0\) # [0-9a-f]+( <.*>)?[ 	]+[0-9a-f]+:[ 	]+R_RISCV_PCREL_LO12_I[ 	]+.*
+[ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX.*
+[ 	]+[0-9a-f]+:[ 	]+00000517[ 	]+auipc[ 	]+a0,0x0[ 	]+[0-9a-f]+:[ 	]+R_RISCV_PCREL_HI20[ 	]+bval
+[ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX.*
+[ 	]+[0-9a-f]+:[ 	]+00054503[ 	]+lbu[ 	]+a0,0\(a0\) # [0-9a-f]+( <.*>)?[ 	]+[0-9a-f]+:[ 	]+R_RISCV_PCREL_LO12_I[ 	]+.*
+[ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX.*
+[ 	]+[0-9a-f]+:[ 	]+00000517[ 	]+auipc[ 	]+a0,0x0[ 	]+[0-9a-f]+:[ 	]+R_RISCV_PCREL_HI20[ 	]+hval
+[ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX.*
+[ 	]+[0-9a-f]+:[ 	]+00051503[ 	]+lh[ 	]+a0,0\(a0\) # [0-9a-f]+( <.*>)?[ 	]+[0-9a-f]+:[ 	]+R_RISCV_PCREL_LO12_I[ 	]+.*
+[ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX.*
+[ 	]+[0-9a-f]+:[ 	]+00000517[ 	]+auipc[ 	]+a0,0x0[ 	]+[0-9a-f]+:[ 	]+R_RISCV_PCREL_HI20[ 	]+hval
+[ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX.*
+[ 	]+[0-9a-f]+:[ 	]+00055503[ 	]+lhu[ 	]+a0,0\(a0\) # [0-9a-f]+( <.*>)?[ 	]+[0-9a-f]+:[ 	]+R_RISCV_PCREL_LO12_I[ 	]+.*
+[ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX.*
+[ 	]+[0-9a-f]+:[ 	]+00000517[ 	]+auipc[ 	]+a0,0x0[ 	]+[0-9a-f]+:[ 	]+R_RISCV_PCREL_HI20[ 	]+wval
+[ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX.*
+[ 	]+[0-9a-f]+:[ 	]+00052503[ 	]+lw[ 	]+a0,0\(a0\) # [0-9a-f]+( <.*>)?[ 	]+[0-9a-f]+:[ 	]+R_RISCV_PCREL_LO12_I[ 	]+.*
+[ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX.*
+[ 	]+[0-9a-f]+:[ 	]+00000517[ 	]+auipc[ 	]+a0,0x0[ 	]+[0-9a-f]+:[ 	]+R_RISCV_PCREL_HI20[ 	]+dval
+[ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX.*
+[ 	]+[0-9a-f]+:[ 	]+00053503[ 	]+ld[ 	]+a0,0\(a0\) # [0-9a-f]+( <.*>)?[ 	]+[0-9a-f]+:[ 	]+R_RISCV_PCREL_LO12_I[ 	]+.*
+[ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX.*
+
+[0-9a-f]+ <S>:
+[ 	]+[0-9a-f]+:[ 	]+00000297[ 	]+auipc[ 	]+t0,0x0[ 	]+[0-9a-f]+:[ 	]+R_RISCV_PCREL_HI20[ 	]+bval
+[ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX.*
+[ 	]+[0-9a-f]+:[ 	]+00a28023[ 	]+sb[ 	]+a0,0\(t0\) # [0-9a-f]+( <.*>)?[ 	]+[0-9a-f]+:[ 	]+R_RISCV_PCREL_LO12_S[ 	]+.*
+[ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX.*
+[ 	]+[0-9a-f]+:[ 	]+00000297[ 	]+auipc[ 	]+t0,0x0[ 	]+[0-9a-f]+:[ 	]+R_RISCV_PCREL_HI20[ 	]+hval
+[ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX.*
+[ 	]+[0-9a-f]+:[ 	]+00a29023[ 	]+sh[ 	]+a0,0\(t0\) # [0-9a-f]+( <.*>)?[ 	]+[0-9a-f]+:[ 	]+R_RISCV_PCREL_LO12_S[ 	]+.*
+[ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX.*
+[ 	]+[0-9a-f]+:[ 	]+00000297[ 	]+auipc[ 	]+t0,0x0[ 	]+[0-9a-f]+:[ 	]+R_RISCV_PCREL_HI20[ 	]+wval
+[ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX.*
+[ 	]+[0-9a-f]+:[ 	]+00a2a023[ 	]+sw[ 	]+a0,0\(t0\) # [0-9a-f]+( <.*>)?[ 	]+[0-9a-f]+:[ 	]+R_RISCV_PCREL_LO12_S[ 	]+.*
+[ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX.*
+[ 	]+[0-9a-f]+:[ 	]+00000297[ 	]+auipc[ 	]+t0,0x0[ 	]+[0-9a-f]+:[ 	]+R_RISCV_PCREL_HI20[ 	]+dval
+[ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX.*
+[ 	]+[0-9a-f]+:[ 	]+00a2b023[ 	]+sd[ 	]+a0,0\(t0\) # [0-9a-f]+( <.*>)?[ 	]+[0-9a-f]+:[ 	]+R_RISCV_PCREL_LO12_S[ 	]+.*
+[ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX.*
diff --git a/gas/testsuite/gas/riscv/l-s-macro.d b/gas/testsuite/gas/riscv/l-s-macro.d
index d6e5993..93753ba 100644
--- a/gas/testsuite/gas/riscv/l-s-macro.d
+++ b/gas/testsuite/gas/riscv/l-s-macro.d
@@ -1,4 +1,4 @@
-#as: -march=rv64i
+#as: -march=rv64i -defsym __64_bit__=1
 #name: Lx/Sx macro insns
 #objdump: -dwr
 
diff --git a/gas/testsuite/gas/riscv/l-s-macro.s b/gas/testsuite/gas/riscv/l-s-macro.s
index 316adc4..d46d3b6 100644
--- a/gas/testsuite/gas/riscv/l-s-macro.s
+++ b/gas/testsuite/gas/riscv/l-s-macro.s
@@ -4,7 +4,9 @@
 	lh	a0, hval
 	lhu	a0, hval
 	lw	a0, wval
+.ifdef __64_bit__
 	lwu	a0, wval
+.endif
 	ld	a0, dval
 
 S:
diff --git a/gas/testsuite/gas/riscv/march-help.l b/gas/testsuite/gas/riscv/march-help.l
index 87faa87..25b78eb 100644
--- a/gas/testsuite/gas/riscv/march-help.l
+++ b/gas/testsuite/gas/riscv/march-help.l
@@ -28,6 +28,7 @@
 	zimop                                   1.0
 	zicfiss                                 1.0
 	zicfilp                                 1.0
+	zilsd                                   1.0
 	zmmul                                   1.0
 	za64rs                                  1.0
 	za128rs                                 1.0
@@ -108,6 +109,7 @@
 	zcmop                                   1.0
 	zcmp                                    1.0
 	zcmt                                    1.0
+	zclsd                                   1.0
 	sha                                     1.0
 	shcounterenw                            1.0
 	shgatpa                                 1.0
diff --git a/gas/testsuite/gas/riscv/zilsd-zclsd-fail.d b/gas/testsuite/gas/riscv/zilsd-zclsd-fail.d
new file mode 100644
index 0000000..da73c2d
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zilsd-zclsd-fail.d
@@ -0,0 +1,3 @@
+#as: -march=rv32ima_zilsd_zclsd
+#source: zilsd-zclsd-fail.s
+#error_output: zilsd-zclsd-fail.l
diff --git a/gas/testsuite/gas/riscv/zilsd-zclsd-fail.l b/gas/testsuite/gas/riscv/zilsd-zclsd-fail.l
new file mode 100644
index 0000000..18e2903
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zilsd-zclsd-fail.l
@@ -0,0 +1,15 @@
+.*: Assembler messages:
+.*: Error: illegal operands `ld x7,\(x5\)'
+.*: Error: illegal operands `ld x9,8\(x11\)'
+.*: Error: illegal operands `ld x13,16\(x16\)'
+.*: Error: illegal operands `sd x7,\(x5\)'
+.*: Error: illegal operands `sd x9,8\(x11\)'
+.*: Error: illegal operands `sd x13,16\(x16\)'
+.*: Error: illegal operands `c.ld x11,\(x9\)'
+.*: Error: illegal operands `c.ld x13,\(x16\)'
+.*: Error: illegal operands `c.ldsp x0,\(x2\)'
+.*: Error: illegal operands `c.ldsp x11,\(x2\)'
+.*: Error: illegal operands `c.sd x11,\(x9\)'
+.*: Error: illegal operands `c.sd x13,\(x16\)'
+.*: Error: illegal operands `c.sdsp x11,\(x2\)'
+.*: Error: illegal operands `c.sdsp x13,8\(x2\)'
diff --git a/gas/testsuite/gas/riscv/zilsd-zclsd-fail.s b/gas/testsuite/gas/riscv/zilsd-zclsd-fail.s
new file mode 100644
index 0000000..925cd48
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zilsd-zclsd-fail.s
@@ -0,0 +1,15 @@
+target:
+    ld x7, (x5)
+    ld x9, 8(x11)
+    ld x13, 16(x16)
+    sd x7, (x5)
+    sd x9, 8(x11)
+    sd x13, 16(x16)
+    c.ld x11, (x9)
+    c.ld x13, (x16)
+    c.ldsp x0, (x2)
+    c.ldsp x11, (x2)
+    c.sd x11, (x9)
+    c.sd x13, (x16)
+    c.sdsp x11, (x2)
+    c.sdsp x13, 8(x2)
diff --git a/gas/testsuite/gas/riscv/zilsd-zclsd.d b/gas/testsuite/gas/riscv/zilsd-zclsd.d
new file mode 100644
index 0000000..816371c
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zilsd-zclsd.d
@@ -0,0 +1,29 @@
+#as: -march=rv32ima_zilsd_zclsd
+#source: zilsd-zclsd.s
+#objdump: -d -Mno-aliases
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+0:[ 	]+0007b303[ 	]+ld[ 	]+t1,0\(a5\)
+[ 	]+4:[ 	]+00883903[ 	]+ld[ 	]+s2,8\(a6\)
+[ 	]+8:[ 	]+0105ba03[ 	]+ld[ 	]+s4,16\(a1\)
+[ 	]+c:[ 	]+0067b023[ 	]+sd[ 	]+t1,0\(a5\)
+[ 	]+10:[ 	]+01283423[ 	]+sd[ 	]+s2,8\(a6\)
+[ 	]+14:[ 	]+0145b823[ 	]+sd[ 	]+s4,16\(a1\)
+[ 	]+18:[ 	]+6380[ 	]+c.ld[ 	]+s0,0\(a5\)
+[ 	]+1a:[ 	]+6408[ 	]+c.ld[ 	]+a0,8\(s0\)
+[ 	]+1c:[ 	]+6a90[ 	]+c.ld[ 	]+a2,16\(a3\)
+[ 	]+1e:[ 	]+e380[ 	]+c.sd[ 	]+s0,0\(a5\)
+[ 	]+20:[ 	]+e408[ 	]+c.sd[ 	]+a0,8\(s0\)
+[ 	]+22:[ 	]+ea90[ 	]+c.sd[ 	]+a2,16\(a3\)
+[ 	]+24:[ 	]+6122[ 	]+c.ldsp[ 	]+sp,8\(sp\)
+[ 	]+26:[ 	]+652a[ 	]+c.ldsp[ 	]+a0,136\(sp\)
+[ 	]+28:[ 	]+7f7e[ 	]+c.ldsp[ 	]+t5,504\(sp\)
+[ 	]+2a:[ 	]+e002[ 	]+c.sdsp[ 	]+zero,0\(sp\)
+[ 	]+2c:[ 	]+e40a[ 	]+c.sdsp[ 	]+sp,8\(sp\)
+[ 	]+2e:[ 	]+e52a[ 	]+c.sdsp[ 	]+a0,136\(sp\)
+[ 	]+30:[ 	]+fffa[ 	]+c.sdsp[ 	]+t5,504\(sp\)
diff --git a/gas/testsuite/gas/riscv/zilsd-zclsd.s b/gas/testsuite/gas/riscv/zilsd-zclsd.s
new file mode 100644
index 0000000..28d83ed
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zilsd-zclsd.s
@@ -0,0 +1,20 @@
+target:
+    ld x6, (x15)
+    ld x18, 8(x16)
+    ld x20, 16(x11)
+    sd x6, (x15)
+    sd x18, 8(x16)
+    sd x20, 16(x11)
+    c.ld x8, (x15)
+    c.ld x10, 8(x8)
+    c.ld x12, 16(x13)
+    c.sd x8, (x15)
+    c.sd x10, 8(x8)
+    c.sd x12, 16(x13)
+    c.ldsp x2, 8(sp)
+    c.ldsp x10, 136(sp)
+    c.ldsp x30, 504(sp)
+    c.sdsp x0, (sp)
+    c.sdsp x2, 8(sp)
+    c.sdsp x10, 136(sp)
+    c.sdsp x30, 504(sp)
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index c5dd546..7fca806 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -562,6 +562,8 @@
   INSN_CLASS_ZCMP,
   INSN_CLASS_ZCMT,
   INSN_CLASS_SMCTR_OR_SSCTR,
+  INSN_CLASS_ZILSD,
+  INSN_CLASS_ZCLSD,
   INSN_CLASS_SMRNMI,
   INSN_CLASS_SVINVAL,
   INSN_CLASS_ZICBOM,
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 340d125..f17d284 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -161,6 +161,7 @@
 #define MASK_RS2 (OP_MASK_RS2 << OP_SH_RS2)
 #define MASK_RD (OP_MASK_RD << OP_SH_RD)
 #define MASK_CRS2 (OP_MASK_CRS2 << OP_SH_CRS2)
+#define MASK_CRS2S (OP_MASK_CRS2S << OP_SH_CRS2S)
 #define MASK_IMM ENCODE_ITYPE_IMM (-1U)
 #define MASK_RVC_IMM ENCODE_CITYPE_IMM (-1U)
 #define MASK_UIMM ENCODE_UTYPE_IMM (-1U)
@@ -206,6 +207,20 @@
 }
 
 static int
+match_rd_even (const struct riscv_opcode *op, insn_t insn)
+{
+  int rd = (insn & MASK_RD) >> OP_SH_RD;
+  return ((rd & 1) == 0) && match_opcode (op, insn);
+}
+
+static int
+match_rs2_even (const struct riscv_opcode *op, insn_t insn)
+{
+  int rs2 = (insn & MASK_RS2) >> OP_SH_RS2;
+  return ((rs2 & 1) == 0) && match_opcode (op, insn);
+}
+
+static int
 match_rd_nonzero (const struct riscv_opcode *op, insn_t insn)
 {
   return (op->pinfo == INSN_MACRO || match_opcode (op, insn))
@@ -213,12 +228,38 @@
 }
 
 static int
+match_rd_even_nonzero (const struct riscv_opcode *op, insn_t insn)
+{
+  return match_rd_nonzero (op, insn) && match_rd_even (op, insn);
+}
+
+static int
 match_rs1_nonzero (const struct riscv_opcode *op ATTRIBUTE_UNUSED, insn_t insn)
 {
   return (insn & MASK_RS1) != 0;
 }
 
 static int
+match_rs1_nonzero_rs2_even (const struct riscv_opcode *op ATTRIBUTE_UNUSED, insn_t insn)
+{
+  return match_rs1_nonzero (op, insn) && match_rs2_even (op, insn);
+}
+
+static int
+match_crs2s_even (const struct riscv_opcode *op, insn_t insn)
+{
+  int crs2s = (insn & MASK_CRS2S) >> OP_SH_CRS2S;
+  return ((crs2s & 1) == 0) && match_opcode (op, insn);
+}
+
+static int
+match_crs2_even (const struct riscv_opcode *op, insn_t insn)
+{
+  int crs2 = (insn & MASK_CRS2) >> OP_SH_CRS2;
+  return ((crs2 & 1) == 0) && match_opcode (op, insn);
+}
+
+static int
 match_c_add (const struct riscv_opcode *op, insn_t insn)
 {
   return match_rd_nonzero (op, insn) && ((insn & MASK_CRS2) != 0);
@@ -625,10 +666,18 @@
 {"ld",         64, INSN_CLASS_C, "Ct,Cl(Cs)", MATCH_C_LD, MASK_C_LD, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
 {"ld",         64, INSN_CLASS_I, "d,o(s)",    MATCH_LD, MASK_LD, match_opcode, INSN_DREF|INSN_8_BYTE },
 {"ld",         64, INSN_CLASS_I, "d,A",       0, (int) M_Lx, match_rd_nonzero, INSN_MACRO },
+{"ld",         32, INSN_CLASS_ZCLSD, "d,Cn(Cc)",  MATCH_C_LDSP, MASK_C_LDSP, match_rd_even_nonzero, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
+{"ld",         32, INSN_CLASS_ZCLSD, "Ct,Cl(Cs)", MATCH_C_LD, MASK_C_LD, match_crs2s_even, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
+{"ld",         32, INSN_CLASS_ZILSD, "d,o(s)",    MATCH_LD, MASK_LD, match_rd_even, INSN_DREF|INSN_8_BYTE },
+{"ld",         32, INSN_CLASS_ZILSD, "d,A",       0, (int) M_Lx, match_rd_even_nonzero, INSN_MACRO },
 {"sd",         64, INSN_CLASS_C, "CV,CN(Cc)", MATCH_C_SDSP, MASK_C_SDSP, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
 {"sd",         64, INSN_CLASS_C, "Ct,Cl(Cs)", MATCH_C_SD, MASK_C_SD, match_opcode, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
 {"sd",         64, INSN_CLASS_I, "t,q(s)",    MATCH_SD, MASK_SD, match_opcode, INSN_DREF|INSN_8_BYTE },
 {"sd",         64, INSN_CLASS_I, "t,A,s",     0, (int) M_Sx_FSx, match_rs1_nonzero, INSN_MACRO },
+{"sd",         32, INSN_CLASS_ZCLSD, "CV,CN(Cc)", MATCH_C_SDSP, MASK_C_SDSP, match_crs2_even, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
+{"sd",         32, INSN_CLASS_ZCLSD, "Ct,Cl(Cs)", MATCH_C_SD, MASK_C_SD, match_crs2s_even, INSN_ALIAS|INSN_DREF|INSN_8_BYTE },
+{"sd",         32, INSN_CLASS_ZILSD, "t,q(s)",    MATCH_SD, MASK_SD, match_rs2_even, INSN_DREF|INSN_8_BYTE },
+{"sd",         32, INSN_CLASS_ZILSD, "t,A,s",     0, (int) M_Sx_FSx, match_rs1_nonzero_rs2_even, INSN_MACRO },
 {"sext.w",     64, INSN_CLASS_C, "d,CU",      MATCH_C_ADDIW, MASK_C_ADDIW|MASK_RVC_IMM, match_rd_nonzero, INSN_ALIAS },
 {"sext.w",     64, INSN_CLASS_I, "d,s",       MATCH_ADDIW, MASK_ADDIW|MASK_IMM, match_opcode, INSN_ALIAS },
 {"addiw",      64, INSN_CLASS_C, "d,CU,Co",   MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, INSN_ALIAS },
@@ -1160,9 +1209,13 @@
 {"c.addiw",   64, INSN_CLASS_C,   "d,Co",      MATCH_C_ADDIW, MASK_C_ADDIW, match_rd_nonzero, 0 },
 {"c.addw",    64, INSN_CLASS_C,   "Cs,Ct",     MATCH_C_ADDW, MASK_C_ADDW, match_opcode, 0 },
 {"c.subw",    64, INSN_CLASS_C,   "Cs,Ct",     MATCH_C_SUBW, MASK_C_SUBW, match_opcode, 0 },
+{"c.ldsp",    32, INSN_CLASS_ZCLSD, "d,Cn(Cc)",  MATCH_C_LDSP, MASK_C_LDSP, match_rd_even_nonzero, INSN_DREF|INSN_8_BYTE },
 {"c.ldsp",    64, INSN_CLASS_C,   "d,Cn(Cc)",  MATCH_C_LDSP, MASK_C_LDSP, match_rd_nonzero, INSN_DREF|INSN_8_BYTE },
+{"c.ld",      32, INSN_CLASS_ZCLSD, "Ct,Cl(Cs)", MATCH_C_LD, MASK_C_LD, match_crs2s_even, INSN_DREF|INSN_8_BYTE },
 {"c.ld",      64, INSN_CLASS_C,   "Ct,Cl(Cs)", MATCH_C_LD, MASK_C_LD, match_opcode, INSN_DREF|INSN_8_BYTE },
+{"c.sdsp",    32, INSN_CLASS_ZCLSD, "CV,CN(Cc)", MATCH_C_SDSP, MASK_C_SDSP, match_crs2_even, INSN_DREF|INSN_8_BYTE },
 {"c.sdsp",    64, INSN_CLASS_C,   "CV,CN(Cc)", MATCH_C_SDSP, MASK_C_SDSP, match_opcode, INSN_DREF|INSN_8_BYTE },
+{"c.sd",      32, INSN_CLASS_ZCLSD, "Ct,Cl(Cs)", MATCH_C_SD, MASK_C_SD, match_crs2s_even, INSN_DREF|INSN_8_BYTE },
 {"c.sd",      64, INSN_CLASS_C,   "Ct,Cl(Cs)", MATCH_C_SD, MASK_C_SD, match_opcode, INSN_DREF|INSN_8_BYTE },
 {"c.fldsp",    0, INSN_CLASS_D_AND_C, "D,Cn(Cc)",  MATCH_C_FLDSP, MASK_C_FLDSP, match_opcode, INSN_DREF|INSN_8_BYTE },
 {"c.fld",      0, INSN_CLASS_D_AND_C, "CD,Cl(Cs)", MATCH_C_FLD, MASK_C_FLD, match_opcode, INSN_DREF|INSN_8_BYTE },