[PATCH] RISC-V: Add zilsd & zclsd support
Kito Cheng
kito.cheng@gmail.com
Fri May 9 08:23:16 GMT 2025
Ooops, sorry, this version is missing one extra testcase. plz just see v2
On Fri, May 9, 2025 at 4:15 PM Kito Cheng <kito.cheng@sifive.com> wrote:
>
> From: dysun <sundongya@nucleisys.com>
>
> 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>
> ---
> bfd/elfxx-riscv.c | 20 ++++++++
> gas/testsuite/gas/riscv/march-help.l | 2 +
> gas/testsuite/gas/riscv/zilsd-zclsd-fail.d | 3 ++
> gas/testsuite/gas/riscv/zilsd-zclsd-fail.l | 15 ++++++
> gas/testsuite/gas/riscv/zilsd-zclsd-fail.s | 15 ++++++
> gas/testsuite/gas/riscv/zilsd-zclsd.d | 29 ++++++++++++
> gas/testsuite/gas/riscv/zilsd-zclsd.s | 20 ++++++++
> include/opcode/riscv.h | 2 +
> opcodes/riscv-opc.c | 54 ++++++++++++++++++++++
> 9 files changed, 160 insertions(+)
> create mode 100644 gas/testsuite/gas/riscv/zilsd-zclsd-fail.d
> create mode 100644 gas/testsuite/gas/riscv/zilsd-zclsd-fail.l
> create mode 100644 gas/testsuite/gas/riscv/zilsd-zclsd-fail.s
> create mode 100644 gas/testsuite/gas/riscv/zilsd-zclsd.d
> create mode 100644 gas/testsuite/gas/riscv/zilsd-zclsd.s
>
> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
> index 83e237c2a03..7b4d108db52 100644
> --- a/bfd/elfxx-riscv.c
> +++ b/bfd/elfxx-riscv.c
> @@ -1222,6 +1222,7 @@ static struct riscv_implicit_subset riscv_implicit_subsets[] =
>
> {"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},
>
> @@ -1365,6 +1366,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =
> {"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 },
> @@ -1444,6 +1446,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =
> {"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}
> };
>
> @@ -2140,6 +2143,15 @@ riscv_parse_check_conflicts (riscv_parse_subset_t *rps)
> (_("`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"),
> @@ -2808,6 +2820,10 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
> 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:
> @@ -3125,6 +3141,10 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
> 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/march-help.l b/gas/testsuite/gas/riscv/march-help.l
> index bcc3a8f1fbd..caf897b22b8 100644
> --- a/gas/testsuite/gas/riscv/march-help.l
> +++ b/gas/testsuite/gas/riscv/march-help.l
> @@ -28,6 +28,7 @@ All available -march extensions for RISC-V:
> zimop 1.0
> zicfiss 1.0
> zicfilp 1.0
> + zilsd 1.0
> zmmul 1.0
> za64rs 1.0
> za128rs 1.0
> @@ -107,6 +108,7 @@ All available -march extensions for RISC-V:
> 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 00000000000..da73c2dd78e
> --- /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 00000000000..18e29039c6d
> --- /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 00000000000..925cd483592
> --- /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 00000000000..816371c52ec
> --- /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 00000000000..28d83ed860d
> --- /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 c5dd546aac5..7fca806b643 100644
> --- a/include/opcode/riscv.h
> +++ b/include/opcode/riscv.h
> @@ -562,6 +562,8 @@ enum riscv_insn_class
> 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 340d1255e18..78ff561dfb6 100644
> --- a/opcodes/riscv-opc.c
> +++ b/opcodes/riscv-opc.c
> @@ -161,6 +161,7 @@ riscv_get_sp_base (insn_t opcode, unsigned int xlen)
> #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)
> @@ -205,6 +206,20 @@ match_rs2_rd_even (const struct riscv_opcode *op, insn_t insn)
> return ((rs2 & 1) == 0) && ((rd & 1) == 0) && match_opcode (op, insn);
> }
>
> +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)
> {
> @@ -212,12 +227,38 @@ match_rd_nonzero (const struct riscv_opcode *op, insn_t insn)
> && ((insn & MASK_RD) != 0);
> }
>
> +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)
> {
> @@ -625,10 +666,18 @@ const struct riscv_opcode riscv_opcodes[] =
> {"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,14 @@ const struct riscv_opcode riscv_opcodes[] =
> {"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 },
> +/*zclsd */
> +{"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 },
> --
> 2.34.1
>
More information about the Binutils
mailing list