RISC-V: Support svinval extension.

Message ID 20210722064852.6708-1-nelson.chu@sifive.com
State New
Headers show
Series
  • RISC-V: Support svinval extension.
Related show

Commit Message

Nelson Chu July 22, 2021, 6:48 a.m.
https://github.com/riscv/riscv-isa-manual/pull/668/files

There are five new instructions for svinval extension.  According to
the above draft spec, two of them (HINVAL.VVMA and HINVAL.GVMA) need
to enable the hypervisor extension.  But there is no implementation
of hypervisor extension in mainline for now, so let's consider the
related issues later.

                31..25  24..20 19..15 14..12 11...7 6..2  1..0
sinval.vma      0001011 rs2    rs1    000    00000  11100 11
sfence.w.inval  0001100 00000  rs1    000    00000  11100 11
sfence.inval.ir 0001100 00001  rs1    000    00000  11100 11
hinval.vvma     0011011 rs2    rs1    000    00000  11100 11
hinval.gvma     0111011 rs2    rs1    000    00000  11100 11

Note: This is still draft extension, so the patch may be changed, and
will be committed until the extension is forzen or becomes standard.

bfd/
	* elfxx-riscv.c (riscv_std_z_ext_strtab): Added svinval.
gas/
	* config/tc-riscv.c (ext_version_table): Added draft 0.1.
	(riscv_multi_subset_supports): Handle INSN_CLASS_SVINVAL.
	* testsuite/gas/riscv/svinval.d: New testcase.
	* gas/testsuite/gas/riscv/svinval.s: Likewise.
include/
	* opcode/riscv-opc.h: Added encodings of svinval instructions.
	* opcode/riscv.h (enum riscv_insn_class): Added INSN_CLASS_SVINVAL.
opcodes/
	* riscv-opc.c (riscv_opcodes): Added svinval instructions.
---
 bfd/elfxx-riscv.c                 |  2 +-
 gas/config/tc-riscv.c             |  8 +++++---
 gas/testsuite/gas/riscv/svinval.d | 15 +++++++++++++++
 gas/testsuite/gas/riscv/svinval.s |  5 +++++
 include/opcode/riscv-opc.h        | 15 +++++++++++++++
 include/opcode/riscv.h            |  1 +
 opcodes/riscv-opc.c               |  9 ++++++++-
 7 files changed, 50 insertions(+), 5 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/svinval.d
 create mode 100644 gas/testsuite/gas/riscv/svinval.s

-- 
2.30.2

Comments

Nelson Chu July 22, 2021, 8:05 a.m. | #1
Or we can commit this patch to the integration branch, before the
svinval extension is frozen or becoming standard, if the
implementation is correct.

Thanks
Nelson

On Thu, Jul 22, 2021 at 2:48 PM Nelson Chu <nelson.chu@sifive.com> wrote:
>

> https://github.com/riscv/riscv-isa-manual/pull/668/files

>

> There are five new instructions for svinval extension.  According to

> the above draft spec, two of them (HINVAL.VVMA and HINVAL.GVMA) need

> to enable the hypervisor extension.  But there is no implementation

> of hypervisor extension in mainline for now, so let's consider the

> related issues later.

>

>                 31..25  24..20 19..15 14..12 11...7 6..2  1..0

> sinval.vma      0001011 rs2    rs1    000    00000  11100 11

> sfence.w.inval  0001100 00000  rs1    000    00000  11100 11

> sfence.inval.ir 0001100 00001  rs1    000    00000  11100 11

> hinval.vvma     0011011 rs2    rs1    000    00000  11100 11

> hinval.gvma     0111011 rs2    rs1    000    00000  11100 11

>

> Note: This is still draft extension, so the patch may be changed, and

> will be committed until the extension is forzen or becomes standard.

>

> bfd/

>         * elfxx-riscv.c (riscv_std_z_ext_strtab): Added svinval.

> gas/

>         * config/tc-riscv.c (ext_version_table): Added draft 0.1.

>         (riscv_multi_subset_supports): Handle INSN_CLASS_SVINVAL.

>         * testsuite/gas/riscv/svinval.d: New testcase.

>         * gas/testsuite/gas/riscv/svinval.s: Likewise.

> include/

>         * opcode/riscv-opc.h: Added encodings of svinval instructions.

>         * opcode/riscv.h (enum riscv_insn_class): Added INSN_CLASS_SVINVAL.

> opcodes/

>         * riscv-opc.c (riscv_opcodes): Added svinval instructions.

> ---

>  bfd/elfxx-riscv.c                 |  2 +-

>  gas/config/tc-riscv.c             |  8 +++++---

>  gas/testsuite/gas/riscv/svinval.d | 15 +++++++++++++++

>  gas/testsuite/gas/riscv/svinval.s |  5 +++++

>  include/opcode/riscv-opc.h        | 15 +++++++++++++++

>  include/opcode/riscv.h            |  1 +

>  opcodes/riscv-opc.c               |  9 ++++++++-

>  7 files changed, 50 insertions(+), 5 deletions(-)

>  create mode 100644 gas/testsuite/gas/riscv/svinval.d

>  create mode 100644 gas/testsuite/gas/riscv/svinval.s

>

> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c

> index 2b8f60caf32..dcd804c2a30 100644

> --- a/bfd/elfxx-riscv.c

> +++ b/bfd/elfxx-riscv.c

> @@ -1082,7 +1082,7 @@ static const char * const riscv_std_z_ext_strtab[] =

>

>  static const char * const riscv_std_s_ext_strtab[] =

>  {

> -  NULL

> +  "svinval", NULL

>  };

>

>  static const char * const riscv_std_h_ext_strtab[] =

> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c

> index 460667e4349..333809e1bd7 100644

> --- a/gas/config/tc-riscv.c

> +++ b/gas/config/tc-riscv.c

> @@ -143,6 +143,8 @@ static const struct riscv_ext_version ext_version_table[] =

>    {"zba",   ISA_SPEC_CLASS_DRAFT, 0, 93},

>    {"zbc",   ISA_SPEC_CLASS_DRAFT, 0, 93},

>

> +  {"svinval", ISA_SPEC_CLASS_DRAFT, 0, 1},

> +

>    /* Terminate the list.  */

>    {NULL, 0, 0, 0}

>  };

> @@ -333,16 +335,16 @@ riscv_multi_subset_supports (enum riscv_insn_class insn_class)

>        return riscv_subset_supports ("zifencei");

>      case INSN_CLASS_ZIHINTPAUSE:

>        return riscv_subset_supports ("zihintpause");

> -

>      case INSN_CLASS_ZBB:

>        return riscv_subset_supports ("zbb");

> -

>      case INSN_CLASS_ZBA:

>        return riscv_subset_supports ("zba");

> -

>      case INSN_CLASS_ZBC:

>        return riscv_subset_supports ("zbc");

>

> +    case INSN_CLASS_SVINVAL:

> +      return riscv_subset_supports ("svinval");

> +

>      default:

>        as_fatal ("internal: unreachable");

>        return false;

> diff --git a/gas/testsuite/gas/riscv/svinval.d b/gas/testsuite/gas/riscv/svinval.d

> new file mode 100644

> index 00000000000..4b0aec1146d

> --- /dev/null

> +++ b/gas/testsuite/gas/riscv/svinval.d

> @@ -0,0 +1,15 @@

> +#as: -march=rv32i_svinval

> +#source: svinval.s

> +#objdump: -d

> +

> +.*:[   ]+file format .*

> +

> +

> +Disassembly of section .text:

> +

> +0+000 <.text>:

> +[      ]+0:[   ]+16b50073[     ]+sinval.vma[   ]+a0,a1

> +[      ]+4:[   ]+18050073[     ]+sfence.w.inval[       ]+a0

> +[      ]+8:[   ]+18150073[     ]+sfence.inval.ir[      ]+a0

> +[      ]+c:[   ]+36b50073[     ]+hinval.vvma[  ]+a0,a1

> +[      ]+10:[  ]+76b50073[     ]+hinval.gvma[  ]+a0,a1

> diff --git a/gas/testsuite/gas/riscv/svinval.s b/gas/testsuite/gas/riscv/svinval.s

> new file mode 100644

> index 00000000000..5435916ac7c

> --- /dev/null

> +++ b/gas/testsuite/gas/riscv/svinval.s

> @@ -0,0 +1,5 @@

> +       sinval.vma      a0, a1

> +       sfence.w.inval  a0

> +       sfence.inval.ir a0

> +       hinval.vvma     a0, a1

> +       hinval.gvma     a0, a1

> diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h

> index 9999da6241a..d54d0820757 100644

> --- a/include/opcode/riscv-opc.h

> +++ b/include/opcode/riscv-opc.h

> @@ -531,6 +531,16 @@

>  #define MASK_FNMSUB_Q  0x600007f

>  #define MATCH_FNMADD_Q 0x600004f

>  #define MASK_FNMADD_Q  0x600007f

> +#define MATCH_SINVAL_VMA 0x16000073

> +#define MASK_SINVAL_VMA  0xfe007fff

> +#define MATCH_SFENCE_W_INVAL 0x18000073

> +#define MASK_SFENCE_W_INVAL  0xfff07fff

> +#define MATCH_SFENCE_INVAL_IR 0x18100073

> +#define MASK_SFENCE_INVAL_IR  0xfff07fff

> +#define MATCH_HINVAL_VVMA 0x36000073

> +#define MASK_HINVAL_VVMA  0xfe007fff

> +#define MATCH_HINVAL_GVMA 0x76000073

> +#define MASK_HINVAL_GVMA  0xfe007fff

>  #define MATCH_C_ADDI4SPN 0x0

>  #define MASK_C_ADDI4SPN  0xe003

>  #define MATCH_C_FLD 0x2000

> @@ -1120,6 +1130,11 @@ DECLARE_INSN(fmadd_q, MATCH_FMADD_Q, MASK_FMADD_Q)

>  DECLARE_INSN(fmsub_q, MATCH_FMSUB_Q, MASK_FMSUB_Q)

>  DECLARE_INSN(fnmsub_q, MATCH_FNMSUB_Q, MASK_FNMSUB_Q)

>  DECLARE_INSN(fnmadd_q, MATCH_FNMADD_Q, MASK_FNMADD_Q)

> +DECLARE_INSN(sinval_vma, MATCH_SINVAL_VMA, MASK_SINVAL_VMA)

> +DECLARE_INSN(sfence_w_inval, MATCH_SFENCE_W_INVAL, MASK_SFENCE_W_INVAL)

> +DECLARE_INSN(sfence_inval_ir, MATCH_SFENCE_INVAL_IR, MASK_SFENCE_INVAL_IR)

> +DECLARE_INSN(hinval_vvma, MATCH_HINVAL_VVMA, MASK_HINVAL_VVMA)

> +DECLARE_INSN(hinval_gvma, MATCH_HINVAL_GVMA, MASK_HINVAL_GVMA)

>  DECLARE_INSN(c_addi4spn, MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN)

>  DECLARE_INSN(c_fld, MATCH_C_FLD, MASK_C_FLD)

>  DECLARE_INSN(c_lw, MATCH_C_LW, MASK_C_LW)

> diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h

> index fdf3df4f5c1..b01a02e13ce 100644

> --- a/include/opcode/riscv.h

> +++ b/include/opcode/riscv.h

> @@ -319,6 +319,7 @@ enum riscv_insn_class

>    INSN_CLASS_ZBA,

>    INSN_CLASS_ZBB,

>    INSN_CLASS_ZBC,

> +  INSN_CLASS_SVINVAL,

>  };

>

>  /* This structure holds information for a particular instruction.  */

> diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c

> index f55a01b071c..60c5da45e98 100644

> --- a/opcodes/riscv-opc.c

> +++ b/opcodes/riscv-opc.c

> @@ -782,6 +782,14 @@ const struct riscv_opcode riscv_opcodes[] =

>  {"sfence.vma", 0, INSN_CLASS_I,    "s",        MATCH_SFENCE_VMA, MASK_SFENCE_VMA|MASK_RS2, match_opcode, INSN_ALIAS },

>  {"sfence.vma", 0, INSN_CLASS_I,    "s,t",      MATCH_SFENCE_VMA, MASK_SFENCE_VMA, match_opcode, 0 },

>  {"wfi",        0, INSN_CLASS_I,    "",         MATCH_WFI, MASK_WFI, match_opcode, 0 },

> +

> +/* Svinval instructions.  */

> +{"sinval.vma",      0, INSN_CLASS_SVINVAL, "s,t",  MATCH_SINVAL_VMA, MASK_SINVAL_VMA, match_opcode, 0 },

> +{"sfence.w.inval",  0, INSN_CLASS_SVINVAL, "s",    MATCH_SFENCE_W_INVAL, MASK_SFENCE_W_INVAL, match_opcode, 0 },

> +{"sfence.inval.ir", 0, INSN_CLASS_SVINVAL, "s",    MATCH_SFENCE_INVAL_IR, MASK_SFENCE_INVAL_IR, match_opcode, 0 },

> +{"hinval.vvma",     0, INSN_CLASS_SVINVAL, "s,t",  MATCH_HINVAL_VVMA, MASK_HINVAL_VVMA, match_opcode, 0 },

> +{"hinval.gvma",     0, INSN_CLASS_SVINVAL, "s,t",  MATCH_HINVAL_GVMA, MASK_HINVAL_GVMA, match_opcode, 0 },

> +

>  {"clz",        0, INSN_CLASS_ZBB,  "d,s",   MATCH_CLZ, MASK_CLZ, match_opcode, 0 },

>  {"ctz",        0, INSN_CLASS_ZBB,  "d,s",   MATCH_CTZ, MASK_CTZ, match_opcode, 0 },

>  {"cpop",       0, INSN_CLASS_ZBB,  "d,s",   MATCH_CPOP, MASK_CPOP, match_opcode, 0 },

> @@ -827,7 +835,6 @@ const struct riscv_opcode riscv_opcodes[] =

>  {"clmulh",     0, INSN_CLASS_ZBC,  "d,s,t", MATCH_CLMULH, MASK_CLMULH, match_opcode, 0 },

>  {"clmulr",     0, INSN_CLASS_ZBC,  "d,s,t", MATCH_CLMULR, MASK_CLMULR, match_opcode, 0 },

>

> -

>  /* Terminate the list.  */

>  {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}

>  };

> --

> 2.30.2

>

Patch

diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 2b8f60caf32..dcd804c2a30 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -1082,7 +1082,7 @@  static const char * const riscv_std_z_ext_strtab[] =
 
 static const char * const riscv_std_s_ext_strtab[] =
 {
-  NULL
+  "svinval", NULL
 };
 
 static const char * const riscv_std_h_ext_strtab[] =
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 460667e4349..333809e1bd7 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -143,6 +143,8 @@  static const struct riscv_ext_version ext_version_table[] =
   {"zba",   ISA_SPEC_CLASS_DRAFT, 0, 93},
   {"zbc",   ISA_SPEC_CLASS_DRAFT, 0, 93},
 
+  {"svinval", ISA_SPEC_CLASS_DRAFT, 0, 1},
+
   /* Terminate the list.  */
   {NULL, 0, 0, 0}
 };
@@ -333,16 +335,16 @@  riscv_multi_subset_supports (enum riscv_insn_class insn_class)
       return riscv_subset_supports ("zifencei");
     case INSN_CLASS_ZIHINTPAUSE:
       return riscv_subset_supports ("zihintpause");
-
     case INSN_CLASS_ZBB:
       return riscv_subset_supports ("zbb");
-
     case INSN_CLASS_ZBA:
       return riscv_subset_supports ("zba");
-
     case INSN_CLASS_ZBC:
       return riscv_subset_supports ("zbc");
 
+    case INSN_CLASS_SVINVAL:
+      return riscv_subset_supports ("svinval");
+
     default:
       as_fatal ("internal: unreachable");
       return false;
diff --git a/gas/testsuite/gas/riscv/svinval.d b/gas/testsuite/gas/riscv/svinval.d
new file mode 100644
index 00000000000..4b0aec1146d
--- /dev/null
+++ b/gas/testsuite/gas/riscv/svinval.d
@@ -0,0 +1,15 @@ 
+#as: -march=rv32i_svinval
+#source: svinval.s
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[ 	]+0:[ 	]+16b50073[ 	]+sinval.vma[ 	]+a0,a1
+[ 	]+4:[ 	]+18050073[ 	]+sfence.w.inval[ 	]+a0
+[ 	]+8:[ 	]+18150073[ 	]+sfence.inval.ir[ 	]+a0
+[ 	]+c:[ 	]+36b50073[ 	]+hinval.vvma[ 	]+a0,a1
+[ 	]+10:[ 	]+76b50073[ 	]+hinval.gvma[ 	]+a0,a1
diff --git a/gas/testsuite/gas/riscv/svinval.s b/gas/testsuite/gas/riscv/svinval.s
new file mode 100644
index 00000000000..5435916ac7c
--- /dev/null
+++ b/gas/testsuite/gas/riscv/svinval.s
@@ -0,0 +1,5 @@ 
+	sinval.vma	a0, a1
+	sfence.w.inval	a0
+	sfence.inval.ir	a0
+	hinval.vvma	a0, a1
+	hinval.gvma	a0, a1
diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h
index 9999da6241a..d54d0820757 100644
--- a/include/opcode/riscv-opc.h
+++ b/include/opcode/riscv-opc.h
@@ -531,6 +531,16 @@ 
 #define MASK_FNMSUB_Q  0x600007f
 #define MATCH_FNMADD_Q 0x600004f
 #define MASK_FNMADD_Q  0x600007f
+#define MATCH_SINVAL_VMA 0x16000073
+#define MASK_SINVAL_VMA  0xfe007fff
+#define MATCH_SFENCE_W_INVAL 0x18000073
+#define MASK_SFENCE_W_INVAL  0xfff07fff
+#define MATCH_SFENCE_INVAL_IR 0x18100073
+#define MASK_SFENCE_INVAL_IR  0xfff07fff
+#define MATCH_HINVAL_VVMA 0x36000073
+#define MASK_HINVAL_VVMA  0xfe007fff
+#define MATCH_HINVAL_GVMA 0x76000073
+#define MASK_HINVAL_GVMA  0xfe007fff
 #define MATCH_C_ADDI4SPN 0x0
 #define MASK_C_ADDI4SPN  0xe003
 #define MATCH_C_FLD 0x2000
@@ -1120,6 +1130,11 @@  DECLARE_INSN(fmadd_q, MATCH_FMADD_Q, MASK_FMADD_Q)
 DECLARE_INSN(fmsub_q, MATCH_FMSUB_Q, MASK_FMSUB_Q)
 DECLARE_INSN(fnmsub_q, MATCH_FNMSUB_Q, MASK_FNMSUB_Q)
 DECLARE_INSN(fnmadd_q, MATCH_FNMADD_Q, MASK_FNMADD_Q)
+DECLARE_INSN(sinval_vma, MATCH_SINVAL_VMA, MASK_SINVAL_VMA)
+DECLARE_INSN(sfence_w_inval, MATCH_SFENCE_W_INVAL, MASK_SFENCE_W_INVAL)
+DECLARE_INSN(sfence_inval_ir, MATCH_SFENCE_INVAL_IR, MASK_SFENCE_INVAL_IR)
+DECLARE_INSN(hinval_vvma, MATCH_HINVAL_VVMA, MASK_HINVAL_VVMA)
+DECLARE_INSN(hinval_gvma, MATCH_HINVAL_GVMA, MASK_HINVAL_GVMA)
 DECLARE_INSN(c_addi4spn, MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN)
 DECLARE_INSN(c_fld, MATCH_C_FLD, MASK_C_FLD)
 DECLARE_INSN(c_lw, MATCH_C_LW, MASK_C_LW)
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index fdf3df4f5c1..b01a02e13ce 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -319,6 +319,7 @@  enum riscv_insn_class
   INSN_CLASS_ZBA,
   INSN_CLASS_ZBB,
   INSN_CLASS_ZBC,
+  INSN_CLASS_SVINVAL,
 };
 
 /* This structure holds information for a particular instruction.  */
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index f55a01b071c..60c5da45e98 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -782,6 +782,14 @@  const struct riscv_opcode riscv_opcodes[] =
 {"sfence.vma", 0, INSN_CLASS_I,    "s",        MATCH_SFENCE_VMA, MASK_SFENCE_VMA|MASK_RS2, match_opcode, INSN_ALIAS },
 {"sfence.vma", 0, INSN_CLASS_I,    "s,t",      MATCH_SFENCE_VMA, MASK_SFENCE_VMA, match_opcode, 0 },
 {"wfi",        0, INSN_CLASS_I,    "",         MATCH_WFI, MASK_WFI, match_opcode, 0 },
+
+/* Svinval instructions.  */
+{"sinval.vma",      0, INSN_CLASS_SVINVAL, "s,t",  MATCH_SINVAL_VMA, MASK_SINVAL_VMA, match_opcode, 0 },
+{"sfence.w.inval",  0, INSN_CLASS_SVINVAL, "s",    MATCH_SFENCE_W_INVAL, MASK_SFENCE_W_INVAL, match_opcode, 0 },
+{"sfence.inval.ir", 0, INSN_CLASS_SVINVAL, "s",    MATCH_SFENCE_INVAL_IR, MASK_SFENCE_INVAL_IR, match_opcode, 0 },
+{"hinval.vvma",     0, INSN_CLASS_SVINVAL, "s,t",  MATCH_HINVAL_VVMA, MASK_HINVAL_VVMA, match_opcode, 0 },
+{"hinval.gvma",     0, INSN_CLASS_SVINVAL, "s,t",  MATCH_HINVAL_GVMA, MASK_HINVAL_GVMA, match_opcode, 0 },
+
 {"clz",        0, INSN_CLASS_ZBB,  "d,s",   MATCH_CLZ, MASK_CLZ, match_opcode, 0 },
 {"ctz",        0, INSN_CLASS_ZBB,  "d,s",   MATCH_CTZ, MASK_CTZ, match_opcode, 0 },
 {"cpop",       0, INSN_CLASS_ZBB,  "d,s",   MATCH_CPOP, MASK_CPOP, match_opcode, 0 },
@@ -827,7 +835,6 @@  const struct riscv_opcode riscv_opcodes[] =
 {"clmulh",     0, INSN_CLASS_ZBC,  "d,s,t", MATCH_CLMULH, MASK_CLMULH, match_opcode, 0 },
 {"clmulr",     0, INSN_CLASS_ZBC,  "d,s,t", MATCH_CLMULR, MASK_CLMULR, match_opcode, 0 },
 
-
 /* Terminate the list.  */
 {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
 };