[v2] RISC-V: Add SiFive cease extension v1.0

Message ID 20240611042754.2538704-1-hau.hsu@sifive.com
State New
Headers
Series [v2] RISC-V: Add SiFive cease extension v1.0 |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Testing 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

Hau Hsu June 11, 2024, 4:27 a.m. UTC
  Add SiFive vender cease extension.
This aligns LLVM:
https://llvm.org/docs/RISCVUsage.html

bfd/ChangeLog:

    * bfd/elfxx-riscv.c (riscv_supported_vendor_x_ext): Add support for 'xsfcease'.
    (riscv_multi_subset_supports): Handle INSN_CLASS_XSFCEASE.
    (riscv_multi_subset_supports_ext): Handle INSN_CLASS_XSFCEASE.

gas/ChangeLog:

    * gas/testsuite/gas/riscv/march-help.l: Add 'xsfcease' to the list of supported -march extensions.
    * gas/testsuite/gas/riscv/sifive-insns.d: Add test case for 'sf.cease'.
    * gas/testsuite/gas/riscv/sifive-insns.s: Add assembly and disassembly test for 'sf.cease'.

include/ChangeLog:

    * include/opcode/riscv-opc.h (MATCH_SF_CEASE, MASK_SF_CEASE): Define match and mask for 'sf.cease'.
    * include/opcode/riscv.h (INSN_CLASS_XSFCEASE): Add new instruction class for 'xsfcease'.

opcodes/ChangeLog:

    * opcodes/riscv-opc.c (riscv_opcodes): Add opcode entry for 'sf.cease'.
---
 bfd/elfxx-riscv.c                      | 5 +++++
 gas/testsuite/gas/riscv/march-help.l   | 1 +
 gas/testsuite/gas/riscv/sifive-insns.d | 1 +
 gas/testsuite/gas/riscv/sifive-insns.s | 6 ++++++
 include/opcode/riscv-opc.h             | 3 +++
 include/opcode/riscv.h                 | 1 +
 opcodes/riscv-opc.c                    | 3 +++
 7 files changed, 20 insertions(+)
  

Comments

Tsukasa OI June 11, 2024, 7:05 a.m. UTC | #1
Hi Hau (and all),

This patch itself is self-explanatory and looks good except this part:

> +    case INSN_CLASS_XSFCEASE:
> +      return _("xsfcease");

I'll make this part to:
> +      return "xsfcease";
, not using the "_" macro.

Wrapping with gettext is necessary only if we need to return complex
error message containing English words (plain extension names don't need
localization).

I first could not confirm whether this extension name is valid but...
oh, you are a SiFive employee, good.  I was preparing a pretty long
explanation to defend this extension name 'XSfcease' but it seems...
that was not necessary.

Then let me cut to the chase and I'll just link to an LLVM contribution
(also by a SiFive employee, Craig Toppler) to help further discussion by
other reviewers.

https://github.com/llvm/llvm-project/pull/83896

Thanks,
Tsukasa

On 2024/06/11 13:27, Hau Hsu wrote:
> Add SiFive vender cease extension.
> This aligns LLVM:
> https://llvm.org/docs/RISCVUsage.html
> 
> bfd/ChangeLog:
> 
>     * bfd/elfxx-riscv.c (riscv_supported_vendor_x_ext): Add support for 'xsfcease'.
>     (riscv_multi_subset_supports): Handle INSN_CLASS_XSFCEASE.
>     (riscv_multi_subset_supports_ext): Handle INSN_CLASS_XSFCEASE.
> 
> gas/ChangeLog:
> 
>     * gas/testsuite/gas/riscv/march-help.l: Add 'xsfcease' to the list of supported -march extensions.
>     * gas/testsuite/gas/riscv/sifive-insns.d: Add test case for 'sf.cease'.
>     * gas/testsuite/gas/riscv/sifive-insns.s: Add assembly and disassembly test for 'sf.cease'.
> 
> include/ChangeLog:
> 
>     * include/opcode/riscv-opc.h (MATCH_SF_CEASE, MASK_SF_CEASE): Define match and mask for 'sf.cease'.
>     * include/opcode/riscv.h (INSN_CLASS_XSFCEASE): Add new instruction class for 'xsfcease'.
> 
> opcodes/ChangeLog:
> 
>     * opcodes/riscv-opc.c (riscv_opcodes): Add opcode entry for 'sf.cease'.
> ---
>  bfd/elfxx-riscv.c                      | 5 +++++
>  gas/testsuite/gas/riscv/march-help.l   | 1 +
>  gas/testsuite/gas/riscv/sifive-insns.d | 1 +
>  gas/testsuite/gas/riscv/sifive-insns.s | 6 ++++++
>  include/opcode/riscv-opc.h             | 3 +++
>  include/opcode/riscv.h                 | 1 +
>  opcodes/riscv-opc.c                    | 3 +++
>  7 files changed, 20 insertions(+)
> 
> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
> index dfacb87eda0..c69a000a46e 100644
> --- a/bfd/elfxx-riscv.c
> +++ b/bfd/elfxx-riscv.c
> @@ -1470,6 +1470,7 @@ static struct riscv_supported_ext riscv_supported_vendor_x_ext[] =
>    {"xtheadzvamo",	ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
>    {"xventanacondops",	ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
>    {"xsfvcp",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0},
> +  {"xsfcease",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
>    {NULL, 0, 0, 0, 0}
>  };
>  
> @@ -2706,6 +2707,8 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
>        return riscv_subset_supports (rps, "xventanacondops");
>      case INSN_CLASS_XSFVCP:
>        return riscv_subset_supports (rps, "xsfvcp");
> +    case INSN_CLASS_XSFCEASE:
> +      return riscv_subset_supports (rps, "xsfcease");
>      default:
>        rps->error_handler
>          (_("internal: unreachable INSN_CLASS_*"));
> @@ -2960,6 +2963,8 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
>        return "xtheadvector";
>      case INSN_CLASS_XTHEADZVAMO:
>        return "xtheadzvamo";
> +    case INSN_CLASS_XSFCEASE:
> +      return _("xsfcease");
>      default:
>        rps->error_handler
>          (_("internal: unreachable INSN_CLASS_*"));
> diff --git a/gas/testsuite/gas/riscv/march-help.l b/gas/testsuite/gas/riscv/march-help.l
> index c5754837e05..b30790bb980 100644
> --- a/gas/testsuite/gas/riscv/march-help.l
> +++ b/gas/testsuite/gas/riscv/march-help.l
> @@ -121,3 +121,4 @@ All available -march extensions for RISC-V:
>  	xtheadzvamo                             1.0
>  	xventanacondops                         1.0
>  	xsfvcp                                  1.0
> +	xsfcease                                1.0
> diff --git a/gas/testsuite/gas/riscv/sifive-insns.d b/gas/testsuite/gas/riscv/sifive-insns.d
> index f7d63d1bce0..610f62588b3 100644
> --- a/gas/testsuite/gas/riscv/sifive-insns.d
> +++ b/gas/testsuite/gas/riscv/sifive-insns.d
> @@ -35,3 +35,4 @@ Disassembly of section .text:
>  [ 	]+[0-9a-f]+:[ 	]+fc25c05b[ 	]+sf.vc.v.xvw[ 	]+0x3,v0,v2,a1
>  [ 	]+[0-9a-f]+:[ 	]+fc27b05b[ 	]+sf.vc.v.ivw[ 	]+0x3,v0,v2,15
>  [ 	]+[0-9a-f]+:[ 	]+fc25d05b[ 	]+sf.vc.v.fvw[ 	]+0x1,v0,v2,fa1
> +[ 	]+[0-9a-f]+:[ 	]+30500073[ 	]+sf.cease
> diff --git a/gas/testsuite/gas/riscv/sifive-insns.s b/gas/testsuite/gas/riscv/sifive-insns.s
> index d593692c5c0..cdf90c1b3ba 100644
> --- a/gas/testsuite/gas/riscv/sifive-insns.s
> +++ b/gas/testsuite/gas/riscv/sifive-insns.s
> @@ -31,3 +31,9 @@
>  	sf.vc.v.ivw 0x3, v0, v2, 15
>  	sf.vc.v.fvw 0x1, v0, v2, fa1
>  	.option pop
> +
> +	# xscease
> +	.option push
> +	.option arch, +xsfcease1p0
> +	sf.cease
> +	.option pop
> diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
> index ae14e14d427..d2d08c6526d 100644
> --- a/include/opcode/riscv-opc.h
> +++ b/include/opcode/riscv-opc.h
> @@ -3076,6 +3076,9 @@
>  #define MASK_SF_VC_FVW 0xfa00707f
>  #define MATCH_SF_VC_V_FVW 0xf800505b
>  #define MASK_SF_VC_V_FVW 0xfa00707f
> +/* Vendor-specific (SiFive) cease instruction.  */
> +#define MATCH_SF_CEASE 0x30500073
> +#define MASK_SF_CEASE 0xffffffff
>  /* Unprivileged Counter/Timers CSR addresses.  */
>  #define CSR_CYCLE 0xc00
>  #define CSR_TIME 0xc01
> diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
> index 5f516a1026e..d6081caa0dd 100644
> --- a/include/opcode/riscv.h
> +++ b/include/opcode/riscv.h
> @@ -505,6 +505,7 @@ enum riscv_insn_class
>    INSN_CLASS_XTHEADZVAMO,
>    INSN_CLASS_XVENTANACONDOPS,
>    INSN_CLASS_XSFVCP,
> +  INSN_CLASS_XSFCEASE,
>  };
>  
>  /* This structure holds information for a particular instruction.  */
> diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
> index 1ef4eaddf4d..01ced23d657 100644
> --- a/opcodes/riscv-opc.c
> +++ b/opcodes/riscv-opc.c
> @@ -3041,6 +3041,9 @@ const struct riscv_opcode riscv_opcodes[] =
>  {"sf.vc.fvw",   0, INSN_CLASS_XSFVCP, "XsO1,Vd,Vt,S",  MATCH_SF_VC_FVW, MASK_SF_VC_FVW, match_opcode, 0 },
>  {"sf.vc.v.fvw", 0, INSN_CLASS_XSFVCP, "XsO1,Vd,Vt,S",  MATCH_SF_VC_V_FVW, MASK_SF_VC_V_FVW, match_opcode, 0 },
>  
> +/* Vendor-specific (SiFive) cease instruction.  */
> +{"sf.cease", 0, INSN_CLASS_XSFCEASE, "", MATCH_SF_CEASE, MASK_SF_CEASE, match_opcode, 0 },
> +
>  /* Terminate the list.  */
>  {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
>  };
  
Hau Hsu June 11, 2024, 7:52 a.m. UTC | #2
Hi Tsukasa,

Thanks for the comment. For the use of "_" macro, I guess I just copied the code from other switch-case and modify the content :p.
I guess in this function (riscv_multi_subset_supports_ext), '_' is only needed for messages contains "and", "or".
Like return _("zihintntl' and `c', or `zihintntl' and `zca");
Maybe some clean-up in the future, since some simple strings uses "_", say return _("zvbb");

I'd be happy to send v3 to remove it along with other suggestions (if any).

Thanks!

Hau


> On Jun 11, 2024, at 3:05 PM, Tsukasa OI <research_trasio@irq.a4lg.com> wrote:
> 
> Hi Hau (and all),
> 
> This patch itself is self-explanatory and looks good except this part:
> 
>> +    case INSN_CLASS_XSFCEASE:
>> +      return _("xsfcease");
> 
> I'll make this part to:
>> +      return "xsfcease";
> , not using the "_" macro.
> 
> Wrapping with gettext is necessary only if we need to return complex
> error message containing English words (plain extension names don't need
> localization).
> 
> I first could not confirm whether this extension name is valid but...
> oh, you are a SiFive employee, good.  I was preparing a pretty long
> explanation to defend this extension name 'XSfcease' but it seems...
> that was not necessary.
> 
> Then let me cut to the chase and I'll just link to an LLVM contribution
> (also by a SiFive employee, Craig Toppler) to help further discussion by
> other reviewers.
> 
> https://github.com/llvm/llvm-project/pull/83896
> 
> Thanks,
> Tsukasa
> 
> On 2024/06/11 13:27, Hau Hsu wrote:
>> Add SiFive vender cease extension.
>> This aligns LLVM:
>> https://llvm.org/docs/RISCVUsage.html
>> 
>> bfd/ChangeLog:
>> 
>>    * bfd/elfxx-riscv.c (riscv_supported_vendor_x_ext): Add support for 'xsfcease'.
>>    (riscv_multi_subset_supports): Handle INSN_CLASS_XSFCEASE.
>>    (riscv_multi_subset_supports_ext): Handle INSN_CLASS_XSFCEASE.
>> 
>> gas/ChangeLog:
>> 
>>    * gas/testsuite/gas/riscv/march-help.l: Add 'xsfcease' to the list of supported -march extensions.
>>    * gas/testsuite/gas/riscv/sifive-insns.d: Add test case for 'sf.cease'.
>>    * gas/testsuite/gas/riscv/sifive-insns.s: Add assembly and disassembly test for 'sf.cease'.
>> 
>> include/ChangeLog:
>> 
>>    * include/opcode/riscv-opc.h (MATCH_SF_CEASE, MASK_SF_CEASE): Define match and mask for 'sf.cease'.
>>    * include/opcode/riscv.h (INSN_CLASS_XSFCEASE): Add new instruction class for 'xsfcease'.
>> 
>> opcodes/ChangeLog:
>> 
>>    * opcodes/riscv-opc.c (riscv_opcodes): Add opcode entry for 'sf.cease'.
>> ---
>> bfd/elfxx-riscv.c                      | 5 +++++
>> gas/testsuite/gas/riscv/march-help.l   | 1 +
>> gas/testsuite/gas/riscv/sifive-insns.d | 1 +
>> gas/testsuite/gas/riscv/sifive-insns.s | 6 ++++++
>> include/opcode/riscv-opc.h             | 3 +++
>> include/opcode/riscv.h                 | 1 +
>> opcodes/riscv-opc.c                    | 3 +++
>> 7 files changed, 20 insertions(+)
>> 
>> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
>> index dfacb87eda0..c69a000a46e 100644
>> --- a/bfd/elfxx-riscv.c
>> +++ b/bfd/elfxx-riscv.c
>> @@ -1470,6 +1470,7 @@ static struct riscv_supported_ext riscv_supported_vendor_x_ext[] =
>>   {"xtheadzvamo",	ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
>>   {"xventanacondops",	ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
>>   {"xsfvcp",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0},
>> +  {"xsfcease",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
>>   {NULL, 0, 0, 0, 0}
>> };
>> 
>> @@ -2706,6 +2707,8 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
>>       return riscv_subset_supports (rps, "xventanacondops");
>>     case INSN_CLASS_XSFVCP:
>>       return riscv_subset_supports (rps, "xsfvcp");
>> +    case INSN_CLASS_XSFCEASE:
>> +      return riscv_subset_supports (rps, "xsfcease");
>>     default:
>>       rps->error_handler
>>         (_("internal: unreachable INSN_CLASS_*"));
>> @@ -2960,6 +2963,8 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
>>       return "xtheadvector";
>>     case INSN_CLASS_XTHEADZVAMO:
>>       return "xtheadzvamo";
>> +    case INSN_CLASS_XSFCEASE:
>> +      return _("xsfcease");
>>     default:
>>       rps->error_handler
>>         (_("internal: unreachable INSN_CLASS_*"));
>> diff --git a/gas/testsuite/gas/riscv/march-help.l b/gas/testsuite/gas/riscv/march-help.l
>> index c5754837e05..b30790bb980 100644
>> --- a/gas/testsuite/gas/riscv/march-help.l
>> +++ b/gas/testsuite/gas/riscv/march-help.l
>> @@ -121,3 +121,4 @@ All available -march extensions for RISC-V:
>> 	xtheadzvamo                             1.0
>> 	xventanacondops                         1.0
>> 	xsfvcp                                  1.0
>> +	xsfcease                                1.0
>> diff --git a/gas/testsuite/gas/riscv/sifive-insns.d b/gas/testsuite/gas/riscv/sifive-insns.d
>> index f7d63d1bce0..610f62588b3 100644
>> --- a/gas/testsuite/gas/riscv/sifive-insns.d
>> +++ b/gas/testsuite/gas/riscv/sifive-insns.d
>> @@ -35,3 +35,4 @@ Disassembly of section .text:
>> [ 	]+[0-9a-f]+:[ 	]+fc25c05b[ 	]+sf.vc.v.xvw[ 	]+0x3,v0,v2,a1
>> [ 	]+[0-9a-f]+:[ 	]+fc27b05b[ 	]+sf.vc.v.ivw[ 	]+0x3,v0,v2,15
>> [ 	]+[0-9a-f]+:[ 	]+fc25d05b[ 	]+sf.vc.v.fvw[ 	]+0x1,v0,v2,fa1
>> +[ 	]+[0-9a-f]+:[ 	]+30500073[ 	]+sf.cease
>> diff --git a/gas/testsuite/gas/riscv/sifive-insns.s b/gas/testsuite/gas/riscv/sifive-insns.s
>> index d593692c5c0..cdf90c1b3ba 100644
>> --- a/gas/testsuite/gas/riscv/sifive-insns.s
>> +++ b/gas/testsuite/gas/riscv/sifive-insns.s
>> @@ -31,3 +31,9 @@
>> 	sf.vc.v.ivw 0x3, v0, v2, 15
>> 	sf.vc.v.fvw 0x1, v0, v2, fa1
>> 	.option pop
>> +
>> +	# xscease
>> +	.option push
>> +	.option arch, +xsfcease1p0
>> +	sf.cease
>> +	.option pop
>> diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
>> index ae14e14d427..d2d08c6526d 100644
>> --- a/include/opcode/riscv-opc.h
>> +++ b/include/opcode/riscv-opc.h
>> @@ -3076,6 +3076,9 @@
>> #define MASK_SF_VC_FVW 0xfa00707f
>> #define MATCH_SF_VC_V_FVW 0xf800505b
>> #define MASK_SF_VC_V_FVW 0xfa00707f
>> +/* Vendor-specific (SiFive) cease instruction.  */
>> +#define MATCH_SF_CEASE 0x30500073
>> +#define MASK_SF_CEASE 0xffffffff
>> /* Unprivileged Counter/Timers CSR addresses.  */
>> #define CSR_CYCLE 0xc00
>> #define CSR_TIME 0xc01
>> diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
>> index 5f516a1026e..d6081caa0dd 100644
>> --- a/include/opcode/riscv.h
>> +++ b/include/opcode/riscv.h
>> @@ -505,6 +505,7 @@ enum riscv_insn_class
>>   INSN_CLASS_XTHEADZVAMO,
>>   INSN_CLASS_XVENTANACONDOPS,
>>   INSN_CLASS_XSFVCP,
>> +  INSN_CLASS_XSFCEASE,
>> };
>> 
>> /* This structure holds information for a particular instruction.  */
>> diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
>> index 1ef4eaddf4d..01ced23d657 100644
>> --- a/opcodes/riscv-opc.c
>> +++ b/opcodes/riscv-opc.c
>> @@ -3041,6 +3041,9 @@ const struct riscv_opcode riscv_opcodes[] =
>> {"sf.vc.fvw",   0, INSN_CLASS_XSFVCP, "XsO1,Vd,Vt,S",  MATCH_SF_VC_FVW, MASK_SF_VC_FVW, match_opcode, 0 },
>> {"sf.vc.v.fvw", 0, INSN_CLASS_XSFVCP, "XsO1,Vd,Vt,S",  MATCH_SF_VC_V_FVW, MASK_SF_VC_V_FVW, match_opcode, 0 },
>> 
>> +/* Vendor-specific (SiFive) cease instruction.  */
>> +{"sf.cease", 0, INSN_CLASS_XSFCEASE, "", MATCH_SF_CEASE, MASK_SF_CEASE, match_opcode, 0 },
>> +
>> /* Terminate the list.  */
>> {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
>> };
  

Patch

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index dfacb87eda0..c69a000a46e 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1470,6 +1470,7 @@  static struct riscv_supported_ext riscv_supported_vendor_x_ext[] =
   {"xtheadzvamo",	ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
   {"xventanacondops",	ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
   {"xsfvcp",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0},
+  {"xsfcease",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
   {NULL, 0, 0, 0, 0}
 };
 
@@ -2706,6 +2707,8 @@  riscv_multi_subset_supports (riscv_parse_subset_t *rps,
       return riscv_subset_supports (rps, "xventanacondops");
     case INSN_CLASS_XSFVCP:
       return riscv_subset_supports (rps, "xsfvcp");
+    case INSN_CLASS_XSFCEASE:
+      return riscv_subset_supports (rps, "xsfcease");
     default:
       rps->error_handler
         (_("internal: unreachable INSN_CLASS_*"));
@@ -2960,6 +2963,8 @@  riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
       return "xtheadvector";
     case INSN_CLASS_XTHEADZVAMO:
       return "xtheadzvamo";
+    case INSN_CLASS_XSFCEASE:
+      return _("xsfcease");
     default:
       rps->error_handler
         (_("internal: unreachable INSN_CLASS_*"));
diff --git a/gas/testsuite/gas/riscv/march-help.l b/gas/testsuite/gas/riscv/march-help.l
index c5754837e05..b30790bb980 100644
--- a/gas/testsuite/gas/riscv/march-help.l
+++ b/gas/testsuite/gas/riscv/march-help.l
@@ -121,3 +121,4 @@  All available -march extensions for RISC-V:
 	xtheadzvamo                             1.0
 	xventanacondops                         1.0
 	xsfvcp                                  1.0
+	xsfcease                                1.0
diff --git a/gas/testsuite/gas/riscv/sifive-insns.d b/gas/testsuite/gas/riscv/sifive-insns.d
index f7d63d1bce0..610f62588b3 100644
--- a/gas/testsuite/gas/riscv/sifive-insns.d
+++ b/gas/testsuite/gas/riscv/sifive-insns.d
@@ -35,3 +35,4 @@  Disassembly of section .text:
 [ 	]+[0-9a-f]+:[ 	]+fc25c05b[ 	]+sf.vc.v.xvw[ 	]+0x3,v0,v2,a1
 [ 	]+[0-9a-f]+:[ 	]+fc27b05b[ 	]+sf.vc.v.ivw[ 	]+0x3,v0,v2,15
 [ 	]+[0-9a-f]+:[ 	]+fc25d05b[ 	]+sf.vc.v.fvw[ 	]+0x1,v0,v2,fa1
+[ 	]+[0-9a-f]+:[ 	]+30500073[ 	]+sf.cease
diff --git a/gas/testsuite/gas/riscv/sifive-insns.s b/gas/testsuite/gas/riscv/sifive-insns.s
index d593692c5c0..cdf90c1b3ba 100644
--- a/gas/testsuite/gas/riscv/sifive-insns.s
+++ b/gas/testsuite/gas/riscv/sifive-insns.s
@@ -31,3 +31,9 @@ 
 	sf.vc.v.ivw 0x3, v0, v2, 15
 	sf.vc.v.fvw 0x1, v0, v2, fa1
 	.option pop
+
+	# xscease
+	.option push
+	.option arch, +xsfcease1p0
+	sf.cease
+	.option pop
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index ae14e14d427..d2d08c6526d 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -3076,6 +3076,9 @@ 
 #define MASK_SF_VC_FVW 0xfa00707f
 #define MATCH_SF_VC_V_FVW 0xf800505b
 #define MASK_SF_VC_V_FVW 0xfa00707f
+/* Vendor-specific (SiFive) cease instruction.  */
+#define MATCH_SF_CEASE 0x30500073
+#define MASK_SF_CEASE 0xffffffff
 /* Unprivileged Counter/Timers CSR addresses.  */
 #define CSR_CYCLE 0xc00
 #define CSR_TIME 0xc01
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index 5f516a1026e..d6081caa0dd 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -505,6 +505,7 @@  enum riscv_insn_class
   INSN_CLASS_XTHEADZVAMO,
   INSN_CLASS_XVENTANACONDOPS,
   INSN_CLASS_XSFVCP,
+  INSN_CLASS_XSFCEASE,
 };
 
 /* This structure holds information for a particular instruction.  */
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 1ef4eaddf4d..01ced23d657 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -3041,6 +3041,9 @@  const struct riscv_opcode riscv_opcodes[] =
 {"sf.vc.fvw",   0, INSN_CLASS_XSFVCP, "XsO1,Vd,Vt,S",  MATCH_SF_VC_FVW, MASK_SF_VC_FVW, match_opcode, 0 },
 {"sf.vc.v.fvw", 0, INSN_CLASS_XSFVCP, "XsO1,Vd,Vt,S",  MATCH_SF_VC_V_FVW, MASK_SF_VC_V_FVW, match_opcode, 0 },
 
+/* Vendor-specific (SiFive) cease instruction.  */
+{"sf.cease", 0, INSN_CLASS_XSFCEASE, "", MATCH_SF_CEASE, MASK_SF_CEASE, match_opcode, 0 },
+
 /* Terminate the list.  */
 {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
 };