RISC-V: Support svinval extension with frozen version 1.0.
authorNelson Chu <nelson.chu@sifive.com>
Thu, 22 Jul 2021 05:47:07 +0000 (13:47 +0800)
committerNelson Chu <nelson.chu@sifive.com>
Thu, 16 Dec 2021 08:04:53 +0000 (16:04 +0800)
According to the privileged spec, there are five new instructions for
svinval extension.  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  00000  000    00000  11100 11
sfence.inval.ir 0001100 00001  00000  000    00000  11100 11
hinval.vvma     0010011 rs2    rs1    000    00000  11100 11
hinval.gvma     0110011 rs2    rs1    000    00000  11100 11

This patch is cherry-picked from the riscv integration branch since the
svinval extension is frozen for now.  Besides, we fix the funct7 encodings
of hinval.vvma and hinval.gvma, from 0x0011011 and 0x0111011 to 0x0010011
and 0x0110011.

bfd/
* elfxx-riscv.c (riscv_supported_std_s_ext): Added svinval.
(riscv_multi_subset_supports): Handle INSN_CLASS_SVINVAL.
gas/
* testsuite/gas/riscv/svinval.d: New testcase.
* testsuite/gas/riscv/svinval.s: Likewise.
include/
* opcode/riscv-opc.h: Added encodings for svinval.
* opcode/riscv.h (enum riscv_insn_class): Added INSN_CLASS_SVINVAL.
opcodes/
* riscv-opc.c (riscv_opcodes): Added svinval instructions.

bfd/elfxx-riscv.c
gas/testsuite/gas/riscv/svinval.d [new file with mode: 0644]
gas/testsuite/gas/riscv/svinval.s [new file with mode: 0644]
include/opcode/riscv-opc.h
include/opcode/riscv.h
opcodes/riscv-opc.c

index 8c44c4a36bcda707056dc207e1bf84ba9af8d50e..c575ab093f962e92a1174c3ca257ca2e4279a8f5 100644 (file)
@@ -1227,6 +1227,7 @@ static struct riscv_supported_ext riscv_supported_std_z_ext[] =
 
 static struct riscv_supported_ext riscv_supported_std_s_ext[] =
 {
+  {"svinval",          ISA_SPEC_CLASS_DRAFT,           1, 0, 0 },
   {NULL, 0, 0, 0, 0}
 };
 
@@ -2403,6 +2404,8 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps,
              || riscv_subset_supports (rps, "zve64d")
              || riscv_subset_supports (rps, "zve64f")
              || riscv_subset_supports (rps, "zve32f"));
+    case INSN_CLASS_SVINVAL:
+      return riscv_subset_supports (rps, "svinval");
     default:
       rps->error_handler
         (_("internal: unreachable INSN_CLASS_*"));
diff --git a/gas/testsuite/gas/riscv/svinval.d b/gas/testsuite/gas/riscv/svinval.d
new file mode 100644 (file)
index 0000000..e159f16
--- /dev/null
@@ -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:[   ]+18000073[     ]+sfence.w.inval
+[      ]+8:[   ]+18100073[     ]+sfence.inval.ir
+[      ]+c:[   ]+26b50073[     ]+hinval.vvma[  ]+a0,a1
+[      ]+10:[  ]+66b50073[     ]+hinval.gvma[  ]+a0,a1
diff --git a/gas/testsuite/gas/riscv/svinval.s b/gas/testsuite/gas/riscv/svinval.s
new file mode 100644 (file)
index 0000000..629d5ef
--- /dev/null
@@ -0,0 +1,5 @@
+       sinval.vma      a0, a1
+       sfence.w.inval
+       sfence.inval.ir
+       hinval.vvma     a0, a1
+       hinval.gvma     a0, a1
index 41c8ef163c4234e18461ccc289452b417d858191..a6ece366fa4892fa66f65d67dd04b1e6c5602f3b 100644 (file)
 #define MASK_VDOTUVV  0xfc00707f
 #define MATCH_VFDOTVV  0xe4001057
 #define MASK_VFDOTVV  0xfc00707f
+/* Svinval instruction.  */
+#define MATCH_SINVAL_VMA 0x16000073
+#define MASK_SINVAL_VMA 0xfe007fff
+#define MATCH_SFENCE_W_INVAL 0x18000073
+#define MASK_SFENCE_W_INVAL 0xffffffff
+#define MATCH_SFENCE_INVAL_IR 0x18100073
+#define MASK_SFENCE_INVAL_IR 0xffffffff
+#define MATCH_HINVAL_VVMA 0x26000073
+#define MASK_HINVAL_VVMA 0xfe007fff
+#define MATCH_HINVAL_GVMA 0x66000073
+#define MASK_HINVAL_GVMA 0xfe007fff
 /* Privileged CSR addresses.  */
 #define CSR_USTATUS 0x0
 #define CSR_UIE 0x4
@@ -2549,6 +2560,11 @@ DECLARE_INSN(c_sd, MATCH_C_SD, MASK_C_SD)
 DECLARE_INSN(c_addiw, MATCH_C_ADDIW, MASK_C_ADDIW)
 DECLARE_INSN(c_ldsp, MATCH_C_LDSP, MASK_C_LDSP)
 DECLARE_INSN(c_sdsp, MATCH_C_SDSP, MASK_C_SDSP)
+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)
 #endif /* DECLARE_INSN */
 #ifdef DECLARE_CSR
 /* Privileged CSRs.  */
index 14889972abcee2e0d0801f6c4c0c7346fabc9cd1..cbc90b00008f61cad6e5b0126c776dd465dae55e 100644 (file)
@@ -387,6 +387,7 @@ enum riscv_insn_class
   INSN_CLASS_ZKND_OR_ZKNE,
   INSN_CLASS_V,
   INSN_CLASS_ZVEF,
+  INSN_CLASS_SVINVAL,
 };
 
 /* This structure holds information for a particular instruction.  */
index 40037db83c05f435071d82f7cf2e741f9a9715d6..f220006fc93f35fd61b2663d7accc70b27c674c2 100644 (file)
@@ -1725,6 +1725,13 @@ const struct riscv_opcode riscv_opcodes[] =
 {"vmv4r.v",    0, INSN_CLASS_V, "Vd,Vt", MATCH_VMV4RV, MASK_VMV4RV, match_opcode, 0},
 {"vmv8r.v",    0, INSN_CLASS_V, "Vd,Vt", MATCH_VMV8RV, MASK_VMV8RV, 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, "",    MATCH_SFENCE_W_INVAL, MASK_SFENCE_W_INVAL, match_opcode, 0 },
+{"sfence.inval.ir", 0, INSN_CLASS_SVINVAL, "",    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 },
+
 /* Terminate the list.  */
 {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0}
 };