[1/2] RISC-V: Support extension Zicfiss and Zicfilp

Message ID 20250110101733.1532513-1-kito.cheng@sifive.com
State New
Headers
Series [1/2] RISC-V: Support extension Zicfiss and Zicfilp |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Kito Cheng Jan. 10, 2025, 10:17 a.m. UTC
  From: Monk Chiang <monk.chiang@sifive.com>

Spec: https://github.com/riscv/riscv-cfi/releases/tag/v1.0
---
 bfd/elfxx-riscv.c                             | 25 +++++++
 gas/config/tc-riscv.c                         |  4 ++
 gas/testsuite/gas/riscv/csr-dw-regnums.d      |  1 +
 gas/testsuite/gas/riscv/csr-dw-regnums.s      |  2 +
 gas/testsuite/gas/riscv/csr-version-1p10.d    |  2 +
 gas/testsuite/gas/riscv/csr-version-1p10.l    |  4 ++
 gas/testsuite/gas/riscv/csr-version-1p11.d    |  2 +
 gas/testsuite/gas/riscv/csr-version-1p11.l    |  4 ++
 gas/testsuite/gas/riscv/csr-version-1p12.d    |  2 +
 gas/testsuite/gas/riscv/csr-version-1p12.l    |  4 ++
 gas/testsuite/gas/riscv/csr.s                 |  3 +
 gas/testsuite/gas/riscv/march-help.l          |  2 +
 gas/testsuite/gas/riscv/march-imply-zicfilp.d |  6 ++
 gas/testsuite/gas/riscv/march-imply-zicfiss.d |  6 ++
 gas/testsuite/gas/riscv/zicfisslp-32.d        | 27 ++++++++
 gas/testsuite/gas/riscv/zicfisslp-32.s        | 32 +++++++++
 gas/testsuite/gas/riscv/zicfisslp-64.d        | 27 ++++++++
 gas/testsuite/gas/riscv/zicfisslp-64.s        | 32 +++++++++
 include/opcode/riscv-opc.h                    | 33 +++++++++
 include/opcode/riscv.h                        | 20 ++++++
 opcodes/riscv-opc.c                           | 68 ++++++++++++++++---
 21 files changed, 298 insertions(+), 8 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/march-imply-zicfilp.d
 create mode 100644 gas/testsuite/gas/riscv/march-imply-zicfiss.d
 create mode 100644 gas/testsuite/gas/riscv/zicfisslp-32.d
 create mode 100644 gas/testsuite/gas/riscv/zicfisslp-32.s
 create mode 100644 gas/testsuite/gas/riscv/zicfisslp-64.d
 create mode 100644 gas/testsuite/gas/riscv/zicfisslp-64.s
  

Comments

Jan Beulich Jan. 10, 2025, 12:46 p.m. UTC | #1
On 10.01.2025 11:17, Kito Cheng wrote:
> --- a/opcodes/riscv-opc.c
> +++ b/opcodes/riscv-opc.c
> @@ -381,15 +381,46 @@ match_cm_jalt (const struct riscv_opcode *op, insn_t insn)
>      && EXTRACT_ZCMT_INDEX (insn) < 256;
>  }
>  
> -/* The order of overloaded instructions matters.  Label arguments and
> -   register arguments look the same. Instructions that can have either
> -   for arguments must apear in the correct order in this table for the
> -   assembler to pick the right one. In other words, entries with
> -   immediate operands must apear after the same instruction with
> -   registers.
>  
> -   Because of the lookup algorithm used, entries with the same opcode
> -   name must be contiguous.  */

I don't think this comment should be removed.

> +static int
> +match_rs1_x1x5_opcode (const struct riscv_opcode *op,
> +                      insn_t insn)
> +{
> +  int rs1 = (insn & MASK_RS1) >> OP_SH_RS1;
> +  return match_opcode (op, insn) && (rs1 == 1 || rs1 == 5);
> +}
> +
> +static int
> +match_rs2_x1x5_opcode (const struct riscv_opcode *op,
> +                      insn_t insn)
> +{
> +  int rs2 = (insn & MASK_RS2) >> OP_SH_RS2;
> +  return match_opcode (op, insn) && (rs2 == 1 || rs2 == 5);
> +}
> +
> +static int
> +match_c_mop_1 (const struct riscv_opcode *op,
> +               insn_t insn)
> +{
> +  int n = EXTRACT_C_MOP_N (insn) ;
> +  return match_opcode (op, insn) && n == 1;
> +}
> +
> +static int
> +match_c_mop_5 (const struct riscv_opcode *op,
> +               insn_t insn)
> +{
> +  int n = EXTRACT_C_MOP_N (insn) ;
> +  return match_opcode (op, insn) && n == 5;
> +}
> +
> +static int
> +match_rd_x1x5_opcode (const struct riscv_opcode *op,
> +                     insn_t insn)
> +{
> +  int rd = (insn & MASK_RD) >> OP_SH_RD;
> +  return match_opcode (op, insn) && (rd == 1 || rd == 5);
> +}
>  
>  const struct riscv_opcode riscv_opcodes[] =
>  {
> @@ -546,6 +577,10 @@ const struct riscv_opcode riscv_opcodes[] =
>  {"or",          0, INSN_CLASS_C, "Cs,Cw,Ct",  MATCH_C_OR, MASK_C_OR, match_opcode, INSN_ALIAS },
>  {"or",          0, INSN_CLASS_C, "Cs,Ct,Cw",  MATCH_C_OR, MASK_C_OR, match_opcode, INSN_ALIAS },
>  {"or",          0, INSN_CLASS_I, "d,s,t",     MATCH_OR, MASK_OR, match_opcode, 0 },
> +
> +/* Zicfilp instructions.  */
> +{"lpad",        0, INSN_CLASS_ZICFILP, "u", MATCH_LPAD, MASK_LPAD, match_opcode, 0 },

Can the MATCH_* please be padded enough to match adjacent table entries?

Jan
  
Nelson Chu Jan. 13, 2025, 2:37 a.m. UTC | #2
Jan's comments won't be repeated here, so...

On Fri, Jan 10, 2025 at 6:17 PM Kito Cheng <kito.cheng@sifive.com> wrote:

> From: Monk Chiang <monk.chiang@sifive.com>
>
> Spec: https://github.com/riscv/riscv-cfi/releases/tag/v1.0
> ---
>
diff --git a/gas/testsuite/gas/riscv/march-imply-zicfilp.d
> b/gas/testsuite/gas/riscv/march-imply-zicfilp.d
> new file mode 100644
> index 00000000000..753da438121
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/march-imply-zicfilp.d
> @@ -0,0 +1,6 @@
> +#as: -march=rv32i_zicfilp -march-attr
> +#readelf: -A
> +#source: empty.s
> +Attribute Section: riscv
> +File Attributes
> +  Tag_RISCV_arch: "rv32i2p1_zicfilp1p0_zicsr2p0"
>

Should be included into the imply test case since,

https://github.com/bminor/binutils-gdb/commit/14ea7f9b443950dac2b40f234e820be8a09cbb8a


> diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
> index de4c13fb6db..86d995ed97c 100644
> --- a/include/opcode/riscv.h
> +++ b/include/opcode/riscv.h
> @@ -133,6 +133,12 @@ static inline unsigned int riscv_insn_length (insn_t
> insn)
>  #define EXTRACT_CV_SIMD_UIMM6(x) \
>    ((RV_X(x, 25, 1)) | (RV_X(x, 20, 5) << 1))
>
> +#define EXTRACT_ZICFISS_UIMM5(x) \
> +  (RV_X(x, 15, 5))
> +
> +#define EXTRACT_C_MOP_N(x) \
> +  (RV_X(x, 7, 4))
> +
>  #define ENCODE_ITYPE_IMM(x) \
>    (RV_X(x, 0, 12) << 20)
>  #define ENCODE_STYPE_IMM(x) \
> @@ -201,6 +207,9 @@ static inline unsigned int riscv_insn_length (insn_t
> insn)
>  #define ENCODE_CV_SIMD_UIMM6(x) \
>    ((RV_X(x, 0, 1) << 25) | (RV_X(x, 1, 5) << 20))
>
> +#define ENCODE_ZICFISS_UIMM5(x) \
> +  (RV_X(x, 0, 5) << 15)
> +
>  #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))
>  #define VALID_BTYPE_IMM(x) (EXTRACT_BTYPE_IMM(ENCODE_BTYPE_IMM(x)) == (x))
> @@ -229,6 +238,10 @@ static inline unsigned int riscv_insn_length (insn_t
> insn)
>  #define VALID_ZCB_HALFWORD_UIMM(x)
> (EXTRACT_ZCB_HALFWORD_UIMM(ENCODE_ZCB_HALFWORD_UIMM(x)) == (x))
>  #define VALID_ZCMP_SPIMM(x) (EXTRACT_ZCMP_SPIMM(ENCODE_ZCMP_SPIMM(x)) ==
> (x))
>
> +/* Zicfiss extension.  */
> +#define VALID_ZICFISS_UIMM5(x)
> (EXTRACT_ZICFISS_UIMM5(ENCODE_ZICFISS_UIMM5(x)) != 0 \
> +                               &&
> EXTRACT_ZICFISS_UIMM5(ENCODE_ZICFISS_UIMM5(x)) == (x))
> +
>  #define RISCV_RTYPE(insn, rd, rs1, rs2) \
>    ((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ((rs1) << OP_SH_RS1) | ((rs2)
> << OP_SH_RS2))
>  #define RISCV_ITYPE(insn, rd, rs1, imm) \
> @@ -374,6 +387,10 @@ static inline unsigned int riscv_insn_length (insn_t
> insn)
>  #define OP_MASK_SREG2          0x7
>  #define OP_SH_SREG2            2
>
> +/* Zicfiss fields.  */
> +#define OP_MASK_ZICFISS_UIMM5 0x1f
> +#define OP_SH_ZICFISS_UIMM5 15
>

These new defined VALID/ENCODE/EXTRACT for zicfiss looks useless in this
patch?


> +static int
> +match_c_mop_1 (const struct riscv_opcode *op,
> +               insn_t insn)
> +{
> +  int n = EXTRACT_C_MOP_N (insn) ;
> +  return match_opcode (op, insn) && n == 1;
> +}
> +
> +static int
> +match_c_mop_5 (const struct riscv_opcode *op,
> +               insn_t insn)
> +{
> +  int n = EXTRACT_C_MOP_N (insn) ;
> +  return match_opcode (op, insn) && n == 5;
> +}
>

The match_c_mop_1 and match_c_mop_5 look useless in this patch?

Nelson


>  const struct riscv_opcode riscv_opcodes[] =
>  {
> @@ -546,6 +577,10 @@ const struct riscv_opcode riscv_opcodes[] =
>  {"or",          0, INSN_CLASS_C, "Cs,Cw,Ct",  MATCH_C_OR, MASK_C_OR,
> match_opcode, INSN_ALIAS },
>  {"or",          0, INSN_CLASS_C, "Cs,Ct,Cw",  MATCH_C_OR, MASK_C_OR,
> match_opcode, INSN_ALIAS },
>  {"or",          0, INSN_CLASS_I, "d,s,t",     MATCH_OR, MASK_OR,
> match_opcode, 0 },
> +
> +/* Zicfilp instructions.  */
> +{"lpad",        0, INSN_CLASS_ZICFILP, "u", MATCH_LPAD, MASK_LPAD,
> match_opcode, 0 },
> +
>  {"auipc",       0, INSN_CLASS_I, "d,u",       MATCH_AUIPC, MASK_AUIPC,
> match_opcode, 0 },
>  {"seqz",        0, INSN_CLASS_I, "d,s",
>  MATCH_SLTIU|ENCODE_ITYPE_IMM (1), MASK_SLTIU | MASK_IMM, match_opcode,
> INSN_ALIAS },
>  {"snez",        0, INSN_CLASS_I, "d,t",       MATCH_SLTU,
> MASK_SLTU|MASK_RS1, match_opcode, INSN_ALIAS },
> @@ -1150,6 +1185,23 @@ const struct riscv_opcode riscv_opcodes[] =
>  {"czero.eqz",  0, INSN_CLASS_ZICOND, "d,s,t", MATCH_CZERO_EQZ,
> MASK_CZERO_EQZ, match_opcode, 0 },
>  {"czero.nez",  0, INSN_CLASS_ZICOND, "d,s,t", MATCH_CZERO_NEZ,
> MASK_CZERO_NEZ, match_opcode, 0 },
>
> +/* Zicfiss instructions.  */
> +{"sspush",    0, INSN_CLASS_ZICFISS_AND_ZCMOP, "d", MATCH_C_SSPUSH,
> MASK_C_SSPUSH, match_rd_x1x5_opcode, INSN_ALIAS },
> +{"sspush",    0, INSN_CLASS_ZICFISS, "t", MATCH_SSPUSH, MASK_SSPUSH,
> match_rs2_x1x5_opcode, 0 },
> +{"sspopchk",  0, INSN_CLASS_ZICFISS_AND_ZCMOP, "d", MATCH_C_SSPOPCHK,
> MASK_C_SSPOPCHK, match_rd_x1x5_opcode, INSN_ALIAS },
> +{"sspopchk",  0, INSN_CLASS_ZICFISS, "s", MATCH_SSPOPCHK, MASK_SSPOPCHK,
> match_rs1_x1x5_opcode, 0 },
> +{"c.sspush",    0, INSN_CLASS_ZICFISS_AND_ZCMOP, "d", MATCH_C_SSPUSH,
> MASK_C_SSPUSH, match_rd_x1x5_opcode, 0 },
> +{"c.sspopchk",  0, INSN_CLASS_ZICFISS_AND_ZCMOP, "d", MATCH_C_SSPOPCHK,
> MASK_C_SSPOPCHK, match_rd_x1x5_opcode, 0 },
> +{"ssrdp",     0, INSN_CLASS_ZICFISS, "d", MATCH_SSRDP, MASK_SSRDP,
> match_opcode, 0 },
> +{"ssamoswap.w",      32, INSN_CLASS_ZICFISS, "d,t,0(s)",
> MATCH_SSAMOSWAP_W, MASK_SSAMOSWAP_W|MASK_AQRL, match_opcode,
> INSN_DREF|INSN_4_BYTE },
> +{"ssamoswap.w.aq",   32, INSN_CLASS_ZICFISS, "d,t,0(s)",
> MATCH_SSAMOSWAP_W|MASK_AQ, MASK_SSAMOSWAP_W|MASK_AQRL, match_opcode,
> INSN_DREF|INSN_4_BYTE },
> +{"ssamoswap.w.rl",   32, INSN_CLASS_ZICFISS, "d,t,0(s)",
> MATCH_SSAMOSWAP_W|MASK_RL, MASK_SSAMOSWAP_W|MASK_AQRL, match_opcode,
> INSN_DREF|INSN_4_BYTE },
> +{"ssamoswap.w.aqrl", 32, INSN_CLASS_ZICFISS, "d,t,0(s)",
> MATCH_SSAMOSWAP_W|MASK_AQRL, MASK_SSAMOSWAP_W|MASK_AQRL, match_opcode,
> INSN_DREF|INSN_4_BYTE },
> +{"ssamoswap.d",      64, INSN_CLASS_ZICFISS, "d,t,0(s)",
> MATCH_SSAMOSWAP_D, MASK_SSAMOSWAP_D|MASK_AQRL, match_opcode,
> INSN_DREF|INSN_8_BYTE },
> +{"ssamoswap.d.aq",   64, INSN_CLASS_ZICFISS, "d,t,0(s)",
> MATCH_SSAMOSWAP_D|MASK_AQ, MASK_SSAMOSWAP_D|MASK_AQRL, match_opcode,
> INSN_DREF|INSN_8_BYTE },
> +{"ssamoswap.d.rl",   64, INSN_CLASS_ZICFISS, "d,t,0(s)",
> MATCH_SSAMOSWAP_D|MASK_RL, MASK_SSAMOSWAP_D|MASK_AQRL, match_opcode,
> INSN_DREF|INSN_8_BYTE },
> +{"ssamoswap.d.aqrl", 64, INSN_CLASS_ZICFISS, "d,t,0(s)",
> MATCH_SSAMOSWAP_D|MASK_AQRL, MASK_SSAMOSWAP_D|MASK_AQRL, match_opcode,
> INSN_DREF|INSN_8_BYTE },
> +
>  /* Zimop instructions.  */
>  {"mop.r.0",    0, INSN_CLASS_ZIMOP, "d,s",    MATCH_MOP_R_0,
> MASK_MOP_R_0,  match_opcode, 0 },
>  {"mop.r.1",    0, INSN_CLASS_ZIMOP, "d,s",    MATCH_MOP_R_1,
> MASK_MOP_R_1,  match_opcode, 0 },
> --
> 2.34.1
>
>
  
Kito Cheng Jan. 17, 2025, 1:53 a.m. UTC | #3
Hi Nelson and Jan:

Thanks for your comments, v2 has addressed all comments I believe :)

On Mon, Jan 13, 2025 at 10:38 AM Nelson Chu <nelson@rivosinc.com> wrote:
>
> Jan's comments won't be repeated here, so...
>
> On Fri, Jan 10, 2025 at 6:17 PM Kito Cheng <kito.cheng@sifive.com> wrote:
>>
>> From: Monk Chiang <monk.chiang@sifive.com>
>>
>> Spec: https://github.com/riscv/riscv-cfi/releases/tag/v1.0
>> ---
>>
>> diff --git a/gas/testsuite/gas/riscv/march-imply-zicfilp.d b/gas/testsuite/gas/riscv/march-imply-zicfilp.d
>> new file mode 100644
>> index 00000000000..753da438121
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/march-imply-zicfilp.d
>> @@ -0,0 +1,6 @@
>> +#as: -march=rv32i_zicfilp -march-attr
>> +#readelf: -A
>> +#source: empty.s
>> +Attribute Section: riscv
>> +File Attributes
>> +  Tag_RISCV_arch: "rv32i2p1_zicfilp1p0_zicsr2p0"
>
>
> Should be included into the imply test case since,
>
> https://github.com/bminor/binutils-gdb/commit/14ea7f9b443950dac2b40f234e820be8a09cbb8a
>
>
>>
>> diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
>> index de4c13fb6db..86d995ed97c 100644
>> --- a/include/opcode/riscv.h
>> +++ b/include/opcode/riscv.h
>> @@ -133,6 +133,12 @@ static inline unsigned int riscv_insn_length (insn_t insn)
>>  #define EXTRACT_CV_SIMD_UIMM6(x) \
>>    ((RV_X(x, 25, 1)) | (RV_X(x, 20, 5) << 1))
>>
>> +#define EXTRACT_ZICFISS_UIMM5(x) \
>> +  (RV_X(x, 15, 5))
>> +
>> +#define EXTRACT_C_MOP_N(x) \
>> +  (RV_X(x, 7, 4))
>> +
>>  #define ENCODE_ITYPE_IMM(x) \
>>    (RV_X(x, 0, 12) << 20)
>>  #define ENCODE_STYPE_IMM(x) \
>> @@ -201,6 +207,9 @@ static inline unsigned int riscv_insn_length (insn_t insn)
>>  #define ENCODE_CV_SIMD_UIMM6(x) \
>>    ((RV_X(x, 0, 1) << 25) | (RV_X(x, 1, 5) << 20))
>>
>> +#define ENCODE_ZICFISS_UIMM5(x) \
>> +  (RV_X(x, 0, 5) << 15)
>> +
>>  #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))
>>  #define VALID_BTYPE_IMM(x) (EXTRACT_BTYPE_IMM(ENCODE_BTYPE_IMM(x)) == (x))
>> @@ -229,6 +238,10 @@ static inline unsigned int riscv_insn_length (insn_t insn)
>>  #define VALID_ZCB_HALFWORD_UIMM(x) (EXTRACT_ZCB_HALFWORD_UIMM(ENCODE_ZCB_HALFWORD_UIMM(x)) == (x))
>>  #define VALID_ZCMP_SPIMM(x) (EXTRACT_ZCMP_SPIMM(ENCODE_ZCMP_SPIMM(x)) == (x))
>>
>> +/* Zicfiss extension.  */
>> +#define VALID_ZICFISS_UIMM5(x) (EXTRACT_ZICFISS_UIMM5(ENCODE_ZICFISS_UIMM5(x)) != 0 \
>> +                               && EXTRACT_ZICFISS_UIMM5(ENCODE_ZICFISS_UIMM5(x)) == (x))
>> +
>>  #define RISCV_RTYPE(insn, rd, rs1, rs2) \
>>    ((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2))
>>  #define RISCV_ITYPE(insn, rd, rs1, imm) \
>> @@ -374,6 +387,10 @@ static inline unsigned int riscv_insn_length (insn_t insn)
>>  #define OP_MASK_SREG2          0x7
>>  #define OP_SH_SREG2            2
>>
>> +/* Zicfiss fields.  */
>> +#define OP_MASK_ZICFISS_UIMM5 0x1f
>> +#define OP_SH_ZICFISS_UIMM5 15
>
>
> These new defined VALID/ENCODE/EXTRACT for zicfiss looks useless in this patch?
>
>>
>> +static int
>> +match_c_mop_1 (const struct riscv_opcode *op,
>> +               insn_t insn)
>> +{
>> +  int n = EXTRACT_C_MOP_N (insn) ;
>> +  return match_opcode (op, insn) && n == 1;
>> +}
>> +
>> +static int
>> +match_c_mop_5 (const struct riscv_opcode *op,
>> +               insn_t insn)
>> +{
>> +  int n = EXTRACT_C_MOP_N (insn) ;
>> +  return match_opcode (op, insn) && n == 5;
>> +}
>
>
> The match_c_mop_1 and match_c_mop_5 look useless in this patch?
>
> Nelson
>
>>
>>  const struct riscv_opcode riscv_opcodes[] =
>>  {
>> @@ -546,6 +577,10 @@ const struct riscv_opcode riscv_opcodes[] =
>>  {"or",          0, INSN_CLASS_C, "Cs,Cw,Ct",  MATCH_C_OR, MASK_C_OR, match_opcode, INSN_ALIAS },
>>  {"or",          0, INSN_CLASS_C, "Cs,Ct,Cw",  MATCH_C_OR, MASK_C_OR, match_opcode, INSN_ALIAS },
>>  {"or",          0, INSN_CLASS_I, "d,s,t",     MATCH_OR, MASK_OR, match_opcode, 0 },
>> +
>> +/* Zicfilp instructions.  */
>> +{"lpad",        0, INSN_CLASS_ZICFILP, "u", MATCH_LPAD, MASK_LPAD, match_opcode, 0 },
>> +
>>  {"auipc",       0, INSN_CLASS_I, "d,u",       MATCH_AUIPC, MASK_AUIPC, match_opcode, 0 },
>>  {"seqz",        0, INSN_CLASS_I, "d,s",       MATCH_SLTIU|ENCODE_ITYPE_IMM (1), MASK_SLTIU | MASK_IMM, match_opcode, INSN_ALIAS },
>>  {"snez",        0, INSN_CLASS_I, "d,t",       MATCH_SLTU, MASK_SLTU|MASK_RS1, match_opcode, INSN_ALIAS },
>> @@ -1150,6 +1185,23 @@ const struct riscv_opcode riscv_opcodes[] =
>>  {"czero.eqz",  0, INSN_CLASS_ZICOND, "d,s,t", MATCH_CZERO_EQZ, MASK_CZERO_EQZ, match_opcode, 0 },
>>  {"czero.nez",  0, INSN_CLASS_ZICOND, "d,s,t", MATCH_CZERO_NEZ, MASK_CZERO_NEZ, match_opcode, 0 },
>>
>> +/* Zicfiss instructions.  */
>> +{"sspush",    0, INSN_CLASS_ZICFISS_AND_ZCMOP, "d", MATCH_C_SSPUSH, MASK_C_SSPUSH, match_rd_x1x5_opcode, INSN_ALIAS },
>> +{"sspush",    0, INSN_CLASS_ZICFISS, "t", MATCH_SSPUSH, MASK_SSPUSH, match_rs2_x1x5_opcode, 0 },
>> +{"sspopchk",  0, INSN_CLASS_ZICFISS_AND_ZCMOP, "d", MATCH_C_SSPOPCHK, MASK_C_SSPOPCHK, match_rd_x1x5_opcode, INSN_ALIAS },
>> +{"sspopchk",  0, INSN_CLASS_ZICFISS, "s", MATCH_SSPOPCHK, MASK_SSPOPCHK, match_rs1_x1x5_opcode, 0 },
>> +{"c.sspush",    0, INSN_CLASS_ZICFISS_AND_ZCMOP, "d", MATCH_C_SSPUSH, MASK_C_SSPUSH, match_rd_x1x5_opcode, 0 },
>> +{"c.sspopchk",  0, INSN_CLASS_ZICFISS_AND_ZCMOP, "d", MATCH_C_SSPOPCHK, MASK_C_SSPOPCHK, match_rd_x1x5_opcode, 0 },
>> +{"ssrdp",     0, INSN_CLASS_ZICFISS, "d", MATCH_SSRDP, MASK_SSRDP, match_opcode, 0 },
>> +{"ssamoswap.w",      32, INSN_CLASS_ZICFISS, "d,t,0(s)", MATCH_SSAMOSWAP_W, MASK_SSAMOSWAP_W|MASK_AQRL, match_opcode, INSN_DREF|INSN_4_BYTE },
>> +{"ssamoswap.w.aq",   32, INSN_CLASS_ZICFISS, "d,t,0(s)", MATCH_SSAMOSWAP_W|MASK_AQ, MASK_SSAMOSWAP_W|MASK_AQRL, match_opcode, INSN_DREF|INSN_4_BYTE },
>> +{"ssamoswap.w.rl",   32, INSN_CLASS_ZICFISS, "d,t,0(s)", MATCH_SSAMOSWAP_W|MASK_RL, MASK_SSAMOSWAP_W|MASK_AQRL, match_opcode, INSN_DREF|INSN_4_BYTE },
>> +{"ssamoswap.w.aqrl", 32, INSN_CLASS_ZICFISS, "d,t,0(s)", MATCH_SSAMOSWAP_W|MASK_AQRL, MASK_SSAMOSWAP_W|MASK_AQRL, match_opcode, INSN_DREF|INSN_4_BYTE },
>> +{"ssamoswap.d",      64, INSN_CLASS_ZICFISS, "d,t,0(s)", MATCH_SSAMOSWAP_D, MASK_SSAMOSWAP_D|MASK_AQRL, match_opcode, INSN_DREF|INSN_8_BYTE },
>> +{"ssamoswap.d.aq",   64, INSN_CLASS_ZICFISS, "d,t,0(s)", MATCH_SSAMOSWAP_D|MASK_AQ, MASK_SSAMOSWAP_D|MASK_AQRL, match_opcode, INSN_DREF|INSN_8_BYTE },
>> +{"ssamoswap.d.rl",   64, INSN_CLASS_ZICFISS, "d,t,0(s)", MATCH_SSAMOSWAP_D|MASK_RL, MASK_SSAMOSWAP_D|MASK_AQRL, match_opcode, INSN_DREF|INSN_8_BYTE },
>> +{"ssamoswap.d.aqrl", 64, INSN_CLASS_ZICFISS, "d,t,0(s)", MATCH_SSAMOSWAP_D|MASK_AQRL, MASK_SSAMOSWAP_D|MASK_AQRL, match_opcode, INSN_DREF|INSN_8_BYTE },
>> +
>>  /* Zimop instructions.  */
>>  {"mop.r.0",    0, INSN_CLASS_ZIMOP, "d,s",    MATCH_MOP_R_0,  MASK_MOP_R_0,  match_opcode, 0 },
>>  {"mop.r.1",    0, INSN_CLASS_ZIMOP, "d,s",    MATCH_MOP_R_1,  MASK_MOP_R_1,  match_opcode, 0 },
>> --
>> 2.34.1
>>
  
Nelson Chu Jan. 17, 2025, 4:42 a.m. UTC | #4
Committed v2 two patches, thanks.

Nelson

On Fri, Jan 17, 2025 at 9:53 AM Kito Cheng <kito.cheng@gmail.com> wrote:

> Hi Nelson and Jan:
>
> Thanks for your comments, v2 has addressed all comments I believe :)
>
  

Patch

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index ccece950664..8adb9f3c9d9 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1221,6 +1221,9 @@  static struct riscv_implicit_subset riscv_implicit_subsets[] =
   {"zcmop", "+zca", check_implicit_always},
   {"zcmt", "+zca,+zicsr",	check_implicit_always},
 
+  {"zicfilp", "+zicsr",	check_implicit_always},
+  {"zicfiss", "+zimop,+zicsr",	check_implicit_always},
+
   {"shcounterenw", "+h", check_implicit_always},
   {"shgatpa", "+h", check_implicit_always},
   {"shtvala", "+h", check_implicit_always},
@@ -1354,6 +1357,8 @@  static struct riscv_supported_ext riscv_supported_std_z_ext[] =
   {"zihintpause",	ISA_SPEC_CLASS_DRAFT,		2, 0,  0 },
   {"zihpm",		ISA_SPEC_CLASS_DRAFT,		2, 0,  0 },
   {"zimop",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
+  {"zicfiss",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
+  {"zicfilp",		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 },
@@ -2578,6 +2583,13 @@  riscv_multi_subset_supports (riscv_parse_subset_t *rps,
       return riscv_subset_supports (rps, "zihintpause");
     case INSN_CLASS_ZIMOP:
       return riscv_subset_supports (rps, "zimop");
+    case INSN_CLASS_ZICFISS:
+      return riscv_subset_supports (rps, "zicfiss");
+    case INSN_CLASS_ZICFISS_AND_ZCMOP:
+      return riscv_subset_supports (rps, "zicfiss")
+	     && riscv_subset_supports (rps, "zcmop");
+    case INSN_CLASS_ZICFILP:
+      return riscv_subset_supports (rps, "zicfilp");
     case INSN_CLASS_M:
       return riscv_subset_supports (rps, "m");
     case INSN_CLASS_ZMMUL:
@@ -2824,6 +2836,19 @@  riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
       return "zicsr";
     case INSN_CLASS_ZIFENCEI:
       return "zifencei";
+    case INSN_CLASS_ZICFISS:
+      return "zicfiss";
+    case INSN_CLASS_ZICFISS_AND_ZCMOP:
+      if (!riscv_subset_supports (rps, "zicfiss"))
+	{
+	  if (!riscv_subset_supports (rps, "zcmop"))
+	    return _("zicfiss' and `zcmop");
+	  else
+	    return "zicfiss";
+	}
+      return "zcmop";
+    case INSN_CLASS_ZICFILP:
+      return "zicfilp";
     case INSN_CLASS_ZIHINTNTL:
       return "zihintntl";
     case INSN_CLASS_ZIHINTNTL_AND_C:
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index a915c8b4995..b1670bc5079 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -103,6 +103,7 @@  enum riscv_csr_class
   CSR_CLASS_SSTC_32,		/* Sstc RV32 only */
   CSR_CLASS_SSTC_AND_H_32,	/* Sstc RV32 only (with H) */
   CSR_CLASS_XTHEADVECTOR,	/* xtheadvector only */
+  CSR_CLASS_ZICFISS,		/* Zicfiss */
 };
 
 /* This structure holds all restricted conditions for a CSR.  */
@@ -1155,6 +1156,9 @@  riscv_csr_address (const char *csr_name,
     case CSR_CLASS_XTHEADVECTOR:
       extension = "xtheadvector";
       break;
+    case CSR_CLASS_ZICFISS:
+      extension = "zicfiss";
+      break;
     default:
       as_bad (_("internal: bad RISC-V CSR class (0x%x)"), csr_class);
     }
diff --git a/gas/testsuite/gas/riscv/csr-dw-regnums.d b/gas/testsuite/gas/riscv/csr-dw-regnums.d
index 2d85996ad5c..cebd39818c0 100644
--- a/gas/testsuite/gas/riscv/csr-dw-regnums.d
+++ b/gas/testsuite/gas/riscv/csr-dw-regnums.d
@@ -403,6 +403,7 @@  Contents of the .* section:
   DW_CFA_offset_extended_sf: r4445 \(stimecmph\) at cfa\+1396
   DW_CFA_offset_extended_sf: r4685 \(vstimecmp\) at cfa\+2356
   DW_CFA_offset_extended_sf: r4701 \(vstimecmph\) at cfa\+2420
+  DW_CFA_offset_extended_sf: r4113 \(ssp\) at cfa\+324
   DW_CFA_offset_extended: r4096 \(ustatus\) at cfa\+0
   DW_CFA_offset_extended_sf: r4100 \(uie\) at cfa\+16
   DW_CFA_offset_extended_sf: r4101 \(utvec\) at cfa\+20
diff --git a/gas/testsuite/gas/riscv/csr-dw-regnums.s b/gas/testsuite/gas/riscv/csr-dw-regnums.s
index a4cf56dd799..33f34e0d781 100644
--- a/gas/testsuite/gas/riscv/csr-dw-regnums.s
+++ b/gas/testsuite/gas/riscv/csr-dw-regnums.s
@@ -405,6 +405,8 @@  _start:
 	.cfi_offset stimecmph, 1396
 	.cfi_offset vstimecmp, 2356
 	.cfi_offset vstimecmph, 2420
+	# Zicfiss extension
+	.cfi_offset ssp, 324
 	# dropped
 	.cfi_offset ustatus, 0
 	.cfi_offset uie, 16
diff --git a/gas/testsuite/gas/riscv/csr-version-1p10.d b/gas/testsuite/gas/riscv/csr-version-1p10.d
index f36c7771e05..f9d62681b8f 100644
--- a/gas/testsuite/gas/riscv/csr-version-1p10.d
+++ b/gas/testsuite/gas/riscv/csr-version-1p10.d
@@ -735,6 +735,8 @@  Disassembly of section .text:
 [ 	]+[0-9a-f]+:[ 	]+21459073[ 	]+csrw[ 	]+vsieh,a1
 [ 	]+[0-9a-f]+:[ 	]+25402573[ 	]+csrr[ 	]+a0,vsiph
 [ 	]+[0-9a-f]+:[ 	]+25459073[ 	]+csrw[ 	]+vsiph,a1
+[ 	]+[0-9a-f]+:[ 	]+01102573[ 	]+csrr[ 	]+a0,ssp
+[ 	]+[0-9a-f]+:[ 	]+01159073[ 	]+csrw[ 	]+ssp,a1
 [ 	]+[0-9a-f]+:[ 	]+15002573[ 	]+csrr[ 	]+a0,siselect
 [ 	]+[0-9a-f]+:[ 	]+15059073[ 	]+csrw[ 	]+siselect,a1
 [ 	]+[0-9a-f]+:[ 	]+15102573[ 	]+csrr[ 	]+a0,sireg
diff --git a/gas/testsuite/gas/riscv/csr-version-1p10.l b/gas/testsuite/gas/riscv/csr-version-1p10.l
index 38feb097df0..8fba8212c35 100644
--- a/gas/testsuite/gas/riscv/csr-version-1p10.l
+++ b/gas/testsuite/gas/riscv/csr-version-1p10.l
@@ -1285,6 +1285,10 @@ 
 .*Info: macro .*
 .*Warning: invalid CSR `vsiph', needs `ssaia' extension
 .*Info: macro .*
+.*Warning: invalid CSR `ssp', needs `zicfiss' extension
+.*Info: macro .*
+.*Warning: invalid CSR `ssp', needs `zicfiss' extension
+.*Info: macro .*
 .*Warning: invalid CSR `siselect', needs `ssaia or sscsrind' extension
 .*Info: macro .*
 .*Warning: invalid CSR `siselect', needs `ssaia or sscsrind' extension
diff --git a/gas/testsuite/gas/riscv/csr-version-1p11.d b/gas/testsuite/gas/riscv/csr-version-1p11.d
index 603b17a34ef..76fde614ab0 100644
--- a/gas/testsuite/gas/riscv/csr-version-1p11.d
+++ b/gas/testsuite/gas/riscv/csr-version-1p11.d
@@ -735,6 +735,8 @@  Disassembly of section .text:
 [ 	]+[0-9a-f]+:[ 	]+21459073[ 	]+csrw[ 	]+vsieh,a1
 [ 	]+[0-9a-f]+:[ 	]+25402573[ 	]+csrr[ 	]+a0,vsiph
 [ 	]+[0-9a-f]+:[ 	]+25459073[ 	]+csrw[ 	]+vsiph,a1
+[ 	]+[0-9a-f]+:[ 	]+01102573[ 	]+csrr[ 	]+a0,ssp
+[ 	]+[0-9a-f]+:[ 	]+01159073[ 	]+csrw[ 	]+ssp,a1
 [ 	]+[0-9a-f]+:[ 	]+15002573[ 	]+csrr[ 	]+a0,siselect
 [ 	]+[0-9a-f]+:[ 	]+15059073[ 	]+csrw[ 	]+siselect,a1
 [ 	]+[0-9a-f]+:[ 	]+15102573[ 	]+csrr[ 	]+a0,sireg
diff --git a/gas/testsuite/gas/riscv/csr-version-1p11.l b/gas/testsuite/gas/riscv/csr-version-1p11.l
index 3b0f7825b7f..afd6d83ab0e 100644
--- a/gas/testsuite/gas/riscv/csr-version-1p11.l
+++ b/gas/testsuite/gas/riscv/csr-version-1p11.l
@@ -1281,6 +1281,10 @@ 
 .*Info: macro .*
 .*Warning: invalid CSR `vsiph', needs `ssaia' extension
 .*Info: macro .*
+.*Warning: invalid CSR `ssp', needs `zicfiss' extension
+.*Info: macro .*
+.*Warning: invalid CSR `ssp', needs `zicfiss' extension
+.*Info: macro .*
 .*Warning: invalid CSR `siselect', needs `ssaia or sscsrind' extension
 .*Info: macro .*
 .*Warning: invalid CSR `siselect', needs `ssaia or sscsrind' extension
diff --git a/gas/testsuite/gas/riscv/csr-version-1p12.d b/gas/testsuite/gas/riscv/csr-version-1p12.d
index 862359e1618..58e497a71b4 100644
--- a/gas/testsuite/gas/riscv/csr-version-1p12.d
+++ b/gas/testsuite/gas/riscv/csr-version-1p12.d
@@ -735,6 +735,8 @@  Disassembly of section .text:
 [ 	]+[0-9a-f]+:[ 	]+21459073[ 	]+csrw[ 	]+vsieh,a1
 [ 	]+[0-9a-f]+:[ 	]+25402573[ 	]+csrr[ 	]+a0,vsiph
 [ 	]+[0-9a-f]+:[ 	]+25459073[ 	]+csrw[ 	]+vsiph,a1
+[ 	]+[0-9a-f]+:[ 	]+01102573[ 	]+csrr[ 	]+a0,ssp
+[ 	]+[0-9a-f]+:[ 	]+01159073[ 	]+csrw[ 	]+ssp,a1
 [ 	]+[0-9a-f]+:[ 	]+15002573[ 	]+csrr[ 	]+a0,siselect
 [ 	]+[0-9a-f]+:[ 	]+15059073[ 	]+csrw[ 	]+siselect,a1
 [ 	]+[0-9a-f]+:[ 	]+15102573[ 	]+csrr[ 	]+a0,sireg
diff --git a/gas/testsuite/gas/riscv/csr-version-1p12.l b/gas/testsuite/gas/riscv/csr-version-1p12.l
index 88b27f39745..c5c4756d823 100644
--- a/gas/testsuite/gas/riscv/csr-version-1p12.l
+++ b/gas/testsuite/gas/riscv/csr-version-1p12.l
@@ -1005,6 +1005,10 @@ 
 .*Info: macro .*
 .*Warning: invalid CSR `vsiph', needs `ssaia' extension
 .*Info: macro .*
+.*Warning: invalid CSR `ssp', needs `zicfiss' extension
+.*Info: macro .*
+.*Warning: invalid CSR `ssp', needs `zicfiss' extension
+.*Info: macro .*
 .*Warning: invalid CSR `siselect', needs `ssaia or sscsrind' extension
 .*Info: macro .*
 .*Warning: invalid CSR `siselect', needs `ssaia or sscsrind' extension
diff --git a/gas/testsuite/gas/riscv/csr.s b/gas/testsuite/gas/riscv/csr.s
index d1c4cf6261d..b1885c65a51 100644
--- a/gas/testsuite/gas/riscv/csr.s
+++ b/gas/testsuite/gas/riscv/csr.s
@@ -416,6 +416,9 @@ 
 	csr vsieh
 	csr vsiph
 
+	# Zicfiss
+	csr ssp
+
 	# Sscsrind
 	csr siselect
 	csr sireg
diff --git a/gas/testsuite/gas/riscv/march-help.l b/gas/testsuite/gas/riscv/march-help.l
index fd1174059e5..0692ff15b18 100644
--- a/gas/testsuite/gas/riscv/march-help.l
+++ b/gas/testsuite/gas/riscv/march-help.l
@@ -26,6 +26,8 @@  All available -march extensions for RISC-V:
 	zihintpause                             2.0
 	zihpm                                   2.0
 	zimop                                   1.0
+	zicfiss                                 1.0
+	zicfilp                                 1.0
 	zmmul                                   1.0
 	za64rs                                  1.0
 	za128rs                                 1.0
diff --git a/gas/testsuite/gas/riscv/march-imply-zicfilp.d b/gas/testsuite/gas/riscv/march-imply-zicfilp.d
new file mode 100644
index 00000000000..753da438121
--- /dev/null
+++ b/gas/testsuite/gas/riscv/march-imply-zicfilp.d
@@ -0,0 +1,6 @@ 
+#as: -march=rv32i_zicfilp -march-attr
+#readelf: -A
+#source: empty.s
+Attribute Section: riscv
+File Attributes
+  Tag_RISCV_arch: "rv32i2p1_zicfilp1p0_zicsr2p0"
diff --git a/gas/testsuite/gas/riscv/march-imply-zicfiss.d b/gas/testsuite/gas/riscv/march-imply-zicfiss.d
new file mode 100644
index 00000000000..f3b6bb68636
--- /dev/null
+++ b/gas/testsuite/gas/riscv/march-imply-zicfiss.d
@@ -0,0 +1,6 @@ 
+#as: -march=rv32i_zicfiss -march-attr
+#readelf: -A
+#source: empty.s
+Attribute Section: riscv
+File Attributes
+  Tag_RISCV_arch: "rv32i2p1_zicfiss1p0_zicsr2p0_zimop1p0"
diff --git a/gas/testsuite/gas/riscv/zicfisslp-32.d b/gas/testsuite/gas/riscv/zicfisslp-32.d
new file mode 100644
index 00000000000..360dc0cecd3
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zicfisslp-32.d
@@ -0,0 +1,27 @@ 
+#as: -march=rv32gc_zicfiss_zicfilp
+#objdump: -dr
+
+.*:[    ]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[ 	]+[0-9a-f]+:[ 	]+ce104073[ 	]+sspush[ 	]+ra
+[ 	]+[0-9a-f]+:[ 	]+ce504073[ 	]+sspush[ 	]+t0
+[ 	]+[0-9a-f]+:[ 	]+cdc0c073[ 	]+sspopchk[ 	]+ra
+[ 	]+[0-9a-f]+:[ 	]+cdc2c073[ 	]+sspopchk[ 	]+t0
+[ 	]+[0-9a-f]+:[ 	]+cdc04573[ 	]+ssrdp[ 	]+a0
+[ 	]+[0-9a-f]+:[ 	]+48a5252f[ 	]+ssamoswap.w[ 	]+a0,a0,\(a0\)
+[ 	]+[0-9a-f]+:[ 	]+48a5252f[ 	]+ssamoswap.w[ 	]+a0,a0,\(a0\)
+[ 	]+[0-9a-f]+:[ 	]+4ca5252f[ 	]+ssamoswap.w.aq[ 	]+a0,a0,\(a0\)
+[ 	]+[0-9a-f]+:[ 	]+4ca5252f[ 	]+ssamoswap.w.aq[ 	]+a0,a0,\(a0\)
+[ 	]+[0-9a-f]+:[ 	]+4aa5252f[ 	]+ssamoswap.w.rl[ 	]+a0,a0,\(a0\)
+[ 	]+[0-9a-f]+:[ 	]+4aa5252f[ 	]+ssamoswap.w.rl[ 	]+a0,a0,\(a0\)
+[ 	]+[0-9a-f]+:[ 	]+4ea5252f[ 	]+ssamoswap.w.aqrl[ 	]+a0,a0,\(a0\)
+[ 	]+[0-9a-f]+:[ 	]+4ea5252f[ 	]+ssamoswap.w.aqrl[ 	]+a0,a0,\(a0\)
+[ 	]+[0-9a-f]+:[ 	]+6081[ 	]+sspush[ 	]+ra
+[ 	]+[0-9a-f]+:[ 	]+6081[ 	]+sspush[ 	]+ra
+[ 	]+[0-9a-f]+:[ 	]+6281[ 	]+sspopchk[ 	]+t0
+[ 	]+[0-9a-f]+:[ 	]+6281[ 	]+sspopchk[ 	]+t0
+[ 	]+[0-9a-f]+:[ 	]+00111017[ 	]+lpad[ 	]+0x111
diff --git a/gas/testsuite/gas/riscv/zicfisslp-32.s b/gas/testsuite/gas/riscv/zicfisslp-32.s
new file mode 100644
index 00000000000..c13a8a523df
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zicfisslp-32.s
@@ -0,0 +1,32 @@ 
+	# Zicfiss
+.option push
+.option arch, rv32i_zicfiss
+	sspush x1
+	sspush x5
+	sspopchk x1
+	sspopchk x5
+	ssrdp a0
+        ssamoswap.w     a0,a0,(a0)
+        ssamoswap.w     a0,a0,0(a0)
+        ssamoswap.w.aq  a0,a0,(a0)
+        ssamoswap.w.aq  a0,a0,0(a0)
+        ssamoswap.w.rl  a0,a0,(a0)
+        ssamoswap.w.rl  a0,a0,0(a0)
+        ssamoswap.w.aqrl        a0,a0,(a0)
+        ssamoswap.w.aqrl        a0,a0,0(a0)
+.option pop
+
+	# Zicfiss and Zcmop
+.option push
+.option arch, rv32ic_zicfiss_zcmop
+	sspush x1
+	c.sspush x1
+	sspopchk x5
+	c.sspopchk x5
+.option pop
+
+	# Zicfilp
+.option push
+.option arch, rv32ic_zicfilp
+	lpad 0x111
+.option pop
diff --git a/gas/testsuite/gas/riscv/zicfisslp-64.d b/gas/testsuite/gas/riscv/zicfisslp-64.d
new file mode 100644
index 00000000000..0eb1b87ab8d
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zicfisslp-64.d
@@ -0,0 +1,27 @@ 
+#as: -march=rv64gc_zicfiss_zicfilp
+#objdump: -dr
+
+.*:[    ]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[ 	]+[0-9a-f]+:[ 	]+ce104073[ 	]+sspush[ 	]+ra
+[ 	]+[0-9a-f]+:[ 	]+ce504073[ 	]+sspush[ 	]+t0
+[ 	]+[0-9a-f]+:[ 	]+cdc0c073[ 	]+sspopchk[ 	]+ra
+[ 	]+[0-9a-f]+:[ 	]+cdc2c073[ 	]+sspopchk[ 	]+t0
+[ 	]+[0-9a-f]+:[ 	]+cdc04573[ 	]+ssrdp[ 	]+a0
+[ 	]+[0-9a-f]+:[ 	]+48a5352f[ 	]+ssamoswap.d[ 	]+a0,a0,\(a0\)
+[ 	]+[0-9a-f]+:[ 	]+48a5352f[ 	]+ssamoswap.d[ 	]+a0,a0,\(a0\)
+[ 	]+[0-9a-f]+:[ 	]+4ca5352f[ 	]+ssamoswap.d.aq[ 	]+a0,a0,\(a0\)
+[ 	]+[0-9a-f]+:[ 	]+4ca5352f[ 	]+ssamoswap.d.aq[ 	]+a0,a0,\(a0\)
+[ 	]+[0-9a-f]+:[ 	]+4aa5352f[ 	]+ssamoswap.d.rl[ 	]+a0,a0,\(a0\)
+[ 	]+[0-9a-f]+:[ 	]+4aa5352f[ 	]+ssamoswap.d.rl[ 	]+a0,a0,\(a0\)
+[ 	]+[0-9a-f]+:[ 	]+4ea5352f[ 	]+ssamoswap.d.aqrl[ 	]+a0,a0,\(a0\)
+[ 	]+[0-9a-f]+:[ 	]+4ea5352f[ 	]+ssamoswap.d.aqrl[ 	]+a0,a0,\(a0\)
+[ 	]+[0-9a-f]+:[ 	]+6081[ 	]+sspush[ 	]+ra
+[ 	]+[0-9a-f]+:[ 	]+6081[ 	]+sspush[ 	]+ra
+[ 	]+[0-9a-f]+:[ 	]+6281[ 	]+sspopchk[ 	]+t0
+[ 	]+[0-9a-f]+:[ 	]+6281[ 	]+sspopchk[ 	]+t0
+[ 	]+[0-9a-f]+:[ 	]+00111017[ 	]+lpad[ 	]+0x111
diff --git a/gas/testsuite/gas/riscv/zicfisslp-64.s b/gas/testsuite/gas/riscv/zicfisslp-64.s
new file mode 100644
index 00000000000..844b1221ed5
--- /dev/null
+++ b/gas/testsuite/gas/riscv/zicfisslp-64.s
@@ -0,0 +1,32 @@ 
+	# Zicfiss
+.option push
+.option arch, rv64i_zicfiss
+	sspush x1
+	sspush x5
+	sspopchk x1
+	sspopchk x5
+	ssrdp a0
+        ssamoswap.d       a0, a0, 0(a0)
+        ssamoswap.d       a0, a0, (a0)
+        ssamoswap.d.aq    a0, a0, 0(a0)
+        ssamoswap.d.aq    a0, a0, (a0)
+        ssamoswap.d.rl    a0, a0, 0(a0)
+        ssamoswap.d.rl    a0, a0, (a0)
+        ssamoswap.d.aqrl  a0, a0, 0(a0)
+        ssamoswap.d.aqrl  a0, a0, (a0)
+.option pop
+
+	# Zicfiss and Zcmop
+.option push
+.option arch, rv64ic_zicfiss_zcmop
+	sspush x1
+	c.sspush x1
+	sspopchk x5
+	c.sspopchk x5
+.option pop
+
+	# Zicfilp
+.option push
+.option arch, rv64ic_zicfilp
+	lpad 0x111
+.option pop
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index 166424226aa..5b2e0f15124 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -2352,6 +2352,24 @@ 
 #define MASK_HSV_W 0xfe007fff
 #define MATCH_HSV_D 0x6e004073
 #define MASK_HSV_D 0xfe007fff
+/* Zicfiss instructions.  */
+#define MATCH_SSPUSH 0xce004073
+#define MASK_SSPUSH 0xfe0fffff
+#define MATCH_SSPOPCHK 0xcdc04073
+#define MASK_SSPOPCHK 0xfff07fff
+#define MATCH_SSRDP 0xcdc04073
+#define MASK_SSRDP 0xfffff07f
+#define MATCH_SSAMOSWAP_W 0x4800202f
+#define MASK_SSAMOSWAP_W 0xf800707f
+#define MATCH_SSAMOSWAP_D 0x4800302f
+#define MASK_SSAMOSWAP_D 0xf800707f
+#define MATCH_C_SSPUSH 0x6081
+#define MASK_C_SSPUSH 0xffff
+#define MATCH_C_SSPOPCHK 0x6281
+#define MASK_C_SSPOPCHK 0xffff
+/* Zicfilp instructions.  */
+#define MATCH_LPAD 0x17
+#define MASK_LPAD  0xfff
 /* Zicbop hint instructions. */
 #define MATCH_PREFETCH_I 0x6013
 #define MASK_PREFETCH_I 0x1f07fff
@@ -4196,6 +4214,8 @@ 
 #define CSR_STIMECMPH 0x15d
 #define CSR_VSTIMECMP 0x24d
 #define CSR_VSTIMECMPH 0x25d
+/* Zicfissp extension */
+#define CSR_SSP 0x011
 /* Unprivileged Floating-Point CSR addresses.  */
 #define CSR_FFLAGS 0x1
 #define CSR_FRM 0x2
@@ -4884,6 +4904,17 @@  DECLARE_INSN(th_sync_s, MATCH_TH_SYNC_S, MASK_TH_SYNC_S)
 /* XVentanaCondOps instructions. */
 DECLARE_INSN(vt_maskc, MATCH_VT_MASKC, MASK_VT_MASKC)
 DECLARE_INSN(vt_maskcn, MATCH_VT_MASKCN, MASK_VT_MASKCN)
+
+/* Zicfiss instructions.  */
+DECLARE_INSN(sspush, MATCH_SSPUSH, MASK_SSPUSH)
+DECLARE_INSN(sspopchk, MATCH_SSPOPCHK, MASK_SSPOPCHK)
+DECLARE_INSN(c_sspush, MATCH_C_SSPUSH, MASK_C_SSPUSH)
+DECLARE_INSN(c_sspopchk, MATCH_C_SSPOPCHK, MASK_C_SSPOPCHK)
+DECLARE_INSN(ssrdp, MATCH_SSRDP, MASK_SSRDP)
+DECLARE_INSN(ssamoswap_w, MATCH_SSAMOSWAP_W, MASK_SSAMOSWAP_W)
+DECLARE_INSN(ssamoswap_d, MATCH_SSAMOSWAP_D, MASK_SSAMOSWAP_D)
+/* Zicfilp instructions.  */
+DECLARE_INSN(lpad, MATCH_LPAD, MASK_LPAD)
 #endif /* DECLARE_INSN */
 #ifdef DECLARE_CSR
 /* Unprivileged Counter/Timers CSRs.  */
@@ -5304,6 +5335,8 @@  DECLARE_CSR(stimecmp, CSR_STIMECMP, CSR_CLASS_SSTC, PRIV_SPEC_CLASS_NONE, PRIV_S
 DECLARE_CSR(stimecmph, CSR_STIMECMPH, CSR_CLASS_SSTC_32, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
 DECLARE_CSR(vstimecmp, CSR_VSTIMECMP, CSR_CLASS_SSTC_AND_H, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
 DECLARE_CSR(vstimecmph, CSR_VSTIMECMPH, CSR_CLASS_SSTC_AND_H_32, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
+/* Zicfiss extension */
+DECLARE_CSR(ssp, CSR_SSP, CSR_CLASS_ZICFISS, PRIV_SPEC_CLASS_NONE, PRIV_SPEC_CLASS_NONE)
 /* Dropped CSRs.  */
 DECLARE_CSR(ustatus, CSR_USTATUS, CSR_CLASS_I, PRIV_SPEC_CLASS_1P10, PRIV_SPEC_CLASS_1P12)
 DECLARE_CSR(uie, CSR_UIE, CSR_CLASS_I, PRIV_SPEC_CLASS_1P10, PRIV_SPEC_CLASS_1P12)
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index de4c13fb6db..86d995ed97c 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -133,6 +133,12 @@  static inline unsigned int riscv_insn_length (insn_t insn)
 #define EXTRACT_CV_SIMD_UIMM6(x) \
   ((RV_X(x, 25, 1)) | (RV_X(x, 20, 5) << 1))
 
+#define EXTRACT_ZICFISS_UIMM5(x) \
+  (RV_X(x, 15, 5))
+
+#define EXTRACT_C_MOP_N(x) \
+  (RV_X(x, 7, 4))
+
 #define ENCODE_ITYPE_IMM(x) \
   (RV_X(x, 0, 12) << 20)
 #define ENCODE_STYPE_IMM(x) \
@@ -201,6 +207,9 @@  static inline unsigned int riscv_insn_length (insn_t insn)
 #define ENCODE_CV_SIMD_UIMM6(x) \
   ((RV_X(x, 0, 1) << 25) | (RV_X(x, 1, 5) << 20))
 
+#define ENCODE_ZICFISS_UIMM5(x) \
+  (RV_X(x, 0, 5) << 15)
+
 #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))
 #define VALID_BTYPE_IMM(x) (EXTRACT_BTYPE_IMM(ENCODE_BTYPE_IMM(x)) == (x))
@@ -229,6 +238,10 @@  static inline unsigned int riscv_insn_length (insn_t insn)
 #define VALID_ZCB_HALFWORD_UIMM(x) (EXTRACT_ZCB_HALFWORD_UIMM(ENCODE_ZCB_HALFWORD_UIMM(x)) == (x))
 #define VALID_ZCMP_SPIMM(x) (EXTRACT_ZCMP_SPIMM(ENCODE_ZCMP_SPIMM(x)) == (x))
 
+/* Zicfiss extension.  */
+#define VALID_ZICFISS_UIMM5(x) (EXTRACT_ZICFISS_UIMM5(ENCODE_ZICFISS_UIMM5(x)) != 0 \
+                               && EXTRACT_ZICFISS_UIMM5(ENCODE_ZICFISS_UIMM5(x)) == (x))
+
 #define RISCV_RTYPE(insn, rd, rs1, rs2) \
   ((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2))
 #define RISCV_ITYPE(insn, rd, rs1, imm) \
@@ -374,6 +387,10 @@  static inline unsigned int riscv_insn_length (insn_t insn)
 #define OP_MASK_SREG2		0x7
 #define OP_SH_SREG2		2
 
+/* Zicfiss fields.  */
+#define OP_MASK_ZICFISS_UIMM5 0x1f
+#define OP_SH_ZICFISS_UIMM5 15
+
 #define NVECR 32
 #define NVECM 1
 
@@ -515,6 +532,9 @@  enum riscv_insn_class
   INSN_CLASS_ZVKNHA_OR_ZVKNHB,
   INSN_CLASS_ZVKSED,
   INSN_CLASS_ZVKSH,
+  INSN_CLASS_ZICFISS,
+  INSN_CLASS_ZICFISS_AND_ZCMOP,
+  INSN_CLASS_ZICFILP,
   INSN_CLASS_ZCB,
   INSN_CLASS_ZCB_AND_ZBA,
   INSN_CLASS_ZCB_AND_ZBB,
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 5680f6f96d6..948125800db 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -381,15 +381,46 @@  match_cm_jalt (const struct riscv_opcode *op, insn_t insn)
     && EXTRACT_ZCMT_INDEX (insn) < 256;
 }
 
-/* The order of overloaded instructions matters.  Label arguments and
-   register arguments look the same. Instructions that can have either
-   for arguments must apear in the correct order in this table for the
-   assembler to pick the right one. In other words, entries with
-   immediate operands must apear after the same instruction with
-   registers.
 
-   Because of the lookup algorithm used, entries with the same opcode
-   name must be contiguous.  */
+static int
+match_rs1_x1x5_opcode (const struct riscv_opcode *op,
+                      insn_t insn)
+{
+  int rs1 = (insn & MASK_RS1) >> OP_SH_RS1;
+  return match_opcode (op, insn) && (rs1 == 1 || rs1 == 5);
+}
+
+static int
+match_rs2_x1x5_opcode (const struct riscv_opcode *op,
+                      insn_t insn)
+{
+  int rs2 = (insn & MASK_RS2) >> OP_SH_RS2;
+  return match_opcode (op, insn) && (rs2 == 1 || rs2 == 5);
+}
+
+static int
+match_c_mop_1 (const struct riscv_opcode *op,
+               insn_t insn)
+{
+  int n = EXTRACT_C_MOP_N (insn) ;
+  return match_opcode (op, insn) && n == 1;
+}
+
+static int
+match_c_mop_5 (const struct riscv_opcode *op,
+               insn_t insn)
+{
+  int n = EXTRACT_C_MOP_N (insn) ;
+  return match_opcode (op, insn) && n == 5;
+}
+
+static int
+match_rd_x1x5_opcode (const struct riscv_opcode *op,
+                     insn_t insn)
+{
+  int rd = (insn & MASK_RD) >> OP_SH_RD;
+  return match_opcode (op, insn) && (rd == 1 || rd == 5);
+}
 
 const struct riscv_opcode riscv_opcodes[] =
 {
@@ -546,6 +577,10 @@  const struct riscv_opcode riscv_opcodes[] =
 {"or",          0, INSN_CLASS_C, "Cs,Cw,Ct",  MATCH_C_OR, MASK_C_OR, match_opcode, INSN_ALIAS },
 {"or",          0, INSN_CLASS_C, "Cs,Ct,Cw",  MATCH_C_OR, MASK_C_OR, match_opcode, INSN_ALIAS },
 {"or",          0, INSN_CLASS_I, "d,s,t",     MATCH_OR, MASK_OR, match_opcode, 0 },
+
+/* Zicfilp instructions.  */
+{"lpad",        0, INSN_CLASS_ZICFILP, "u", MATCH_LPAD, MASK_LPAD, match_opcode, 0 },
+
 {"auipc",       0, INSN_CLASS_I, "d,u",       MATCH_AUIPC, MASK_AUIPC, match_opcode, 0 },
 {"seqz",        0, INSN_CLASS_I, "d,s",       MATCH_SLTIU|ENCODE_ITYPE_IMM (1), MASK_SLTIU | MASK_IMM, match_opcode, INSN_ALIAS },
 {"snez",        0, INSN_CLASS_I, "d,t",       MATCH_SLTU, MASK_SLTU|MASK_RS1, match_opcode, INSN_ALIAS },
@@ -1150,6 +1185,23 @@  const struct riscv_opcode riscv_opcodes[] =
 {"czero.eqz",  0, INSN_CLASS_ZICOND, "d,s,t", MATCH_CZERO_EQZ, MASK_CZERO_EQZ, match_opcode, 0 },
 {"czero.nez",  0, INSN_CLASS_ZICOND, "d,s,t", MATCH_CZERO_NEZ, MASK_CZERO_NEZ, match_opcode, 0 },
 
+/* Zicfiss instructions.  */
+{"sspush",    0, INSN_CLASS_ZICFISS_AND_ZCMOP, "d", MATCH_C_SSPUSH, MASK_C_SSPUSH, match_rd_x1x5_opcode, INSN_ALIAS },
+{"sspush",    0, INSN_CLASS_ZICFISS, "t", MATCH_SSPUSH, MASK_SSPUSH, match_rs2_x1x5_opcode, 0 },
+{"sspopchk",  0, INSN_CLASS_ZICFISS_AND_ZCMOP, "d", MATCH_C_SSPOPCHK, MASK_C_SSPOPCHK, match_rd_x1x5_opcode, INSN_ALIAS },
+{"sspopchk",  0, INSN_CLASS_ZICFISS, "s", MATCH_SSPOPCHK, MASK_SSPOPCHK, match_rs1_x1x5_opcode, 0 },
+{"c.sspush",    0, INSN_CLASS_ZICFISS_AND_ZCMOP, "d", MATCH_C_SSPUSH, MASK_C_SSPUSH, match_rd_x1x5_opcode, 0 },
+{"c.sspopchk",  0, INSN_CLASS_ZICFISS_AND_ZCMOP, "d", MATCH_C_SSPOPCHK, MASK_C_SSPOPCHK, match_rd_x1x5_opcode, 0 },
+{"ssrdp",     0, INSN_CLASS_ZICFISS, "d", MATCH_SSRDP, MASK_SSRDP, match_opcode, 0 },
+{"ssamoswap.w",      32, INSN_CLASS_ZICFISS, "d,t,0(s)", MATCH_SSAMOSWAP_W, MASK_SSAMOSWAP_W|MASK_AQRL, match_opcode, INSN_DREF|INSN_4_BYTE },
+{"ssamoswap.w.aq",   32, INSN_CLASS_ZICFISS, "d,t,0(s)", MATCH_SSAMOSWAP_W|MASK_AQ, MASK_SSAMOSWAP_W|MASK_AQRL, match_opcode, INSN_DREF|INSN_4_BYTE },
+{"ssamoswap.w.rl",   32, INSN_CLASS_ZICFISS, "d,t,0(s)", MATCH_SSAMOSWAP_W|MASK_RL, MASK_SSAMOSWAP_W|MASK_AQRL, match_opcode, INSN_DREF|INSN_4_BYTE },
+{"ssamoswap.w.aqrl", 32, INSN_CLASS_ZICFISS, "d,t,0(s)", MATCH_SSAMOSWAP_W|MASK_AQRL, MASK_SSAMOSWAP_W|MASK_AQRL, match_opcode, INSN_DREF|INSN_4_BYTE },
+{"ssamoswap.d",      64, INSN_CLASS_ZICFISS, "d,t,0(s)", MATCH_SSAMOSWAP_D, MASK_SSAMOSWAP_D|MASK_AQRL, match_opcode, INSN_DREF|INSN_8_BYTE },
+{"ssamoswap.d.aq",   64, INSN_CLASS_ZICFISS, "d,t,0(s)", MATCH_SSAMOSWAP_D|MASK_AQ, MASK_SSAMOSWAP_D|MASK_AQRL, match_opcode, INSN_DREF|INSN_8_BYTE },
+{"ssamoswap.d.rl",   64, INSN_CLASS_ZICFISS, "d,t,0(s)", MATCH_SSAMOSWAP_D|MASK_RL, MASK_SSAMOSWAP_D|MASK_AQRL, match_opcode, INSN_DREF|INSN_8_BYTE },
+{"ssamoswap.d.aqrl", 64, INSN_CLASS_ZICFISS, "d,t,0(s)", MATCH_SSAMOSWAP_D|MASK_AQRL, MASK_SSAMOSWAP_D|MASK_AQRL, match_opcode, INSN_DREF|INSN_8_BYTE },
+
 /* Zimop instructions.  */
 {"mop.r.0",    0, INSN_CLASS_ZIMOP, "d,s",    MATCH_MOP_R_0,  MASK_MOP_R_0,  match_opcode, 0 },
 {"mop.r.1",    0, INSN_CLASS_ZIMOP, "d,s",    MATCH_MOP_R_1,  MASK_MOP_R_1,  match_opcode, 0 },