[PATCH] RISC-V: Support svinval extension.
Nelson Chu
nelson.chu@sifive.com
Thu Jul 22 06:48:52 GMT 2021
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
More information about the Binutils
mailing list