From: Nelson Chu Date: Thu, 22 Jul 2021 05:47:07 +0000 (+0800) Subject: RISC-V: Support svinval extensions. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=867d7a79f4e5db92f2653530cdde0caa301c7d81;p=thirdparty%2Fbinutils-gdb.git RISC-V: Support svinval extensions. 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, 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 0011011 rs2 rs1 000 00000 11100 11 hinval.gvma 0111011 rs2 rs1 000 00000 11100 11 bfd/ * elfxx-riscv.c (riscv_supported_std_s_ext): Added svinval. gas/ * config/tc-riscv.c (riscv_extended_subset_supports): Handle INSN_CLASS_SVINVAL. * testsuite/gas/riscv/extended/extended.exp: Updated. * testsuite/gas/riscv/extended/svinval.d: Mew testcases. * testsuite/gas/riscv/extended/svinval.s: Likewise. include/ * opcode/riscv-opc-extended.h: Added encodings for svinval. * opcode/riscv.h (riscv_extended_insn_class): Added INSN_CLASS_SVINVAL. opcodes/ * riscv-opc.c (riscv_draft_opcodes): Added svinval instructions. --- diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index 154b306ec4f..03d6017d534 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -1156,6 +1156,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, 0, 1, 0 }, /* draft. */ {NULL, 0, 0, 0, 0} }; diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index e29c00de97e..885e0f362e9 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -288,6 +288,10 @@ riscv_extended_subset_supports (int insn_class) return riscv_subset_supports ("d") && riscv_subset_supports ("zfh"); case INSN_CLASS_Q_AND_ZFH: return riscv_subset_supports ("q") && riscv_subset_supports ("zfh"); + + case INSN_CLASS_SVINVAL: + return riscv_subset_supports ("svinval"); + default: as_fatal ("internal: unknown INSN_CLASS (0x%x)", insn_class); return false; diff --git a/gas/testsuite/gas/riscv/extended/extended.exp b/gas/testsuite/gas/riscv/extended/extended.exp index 78ea0743e22..8bf23015ce5 100644 --- a/gas/testsuite/gas/riscv/extended/extended.exp +++ b/gas/testsuite/gas/riscv/extended/extended.exp @@ -34,6 +34,7 @@ if [istarget riscv*-*-*] { run_dump_tests "fp-zfh-insns" run_dump_tests "float16-le" run_dump_tests "float16-be" + run_dump_tests "svinval" run_dump_tests "extended-csr" } diff --git a/gas/testsuite/gas/riscv/extended/svinval.d b/gas/testsuite/gas/riscv/extended/svinval.d new file mode 100644 index 00000000000..26ba2108db2 --- /dev/null +++ b/gas/testsuite/gas/riscv/extended/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:[ ]+18000073[ ]+sfence.w.inval +[ ]+8:[ ]+18100073[ ]+sfence.inval.ir +[ ]+c:[ ]+36b50073[ ]+hinval.vvma[ ]+a0,a1 +[ ]+10:[ ]+76b50073[ ]+hinval.gvma[ ]+a0,a1 diff --git a/gas/testsuite/gas/riscv/extended/svinval.s b/gas/testsuite/gas/riscv/extended/svinval.s new file mode 100644 index 00000000000..629d5ef51b4 --- /dev/null +++ b/gas/testsuite/gas/riscv/extended/svinval.s @@ -0,0 +1,5 @@ + sinval.vma a0, a1 + sfence.w.inval + sfence.inval.ir + hinval.vvma a0, a1 + hinval.gvma a0, a1 diff --git a/include/opcode/riscv-opc-extended.h b/include/opcode/riscv-opc-extended.h index 72fcaf4bbc5..6f664ed9de9 100644 --- a/include/opcode/riscv-opc-extended.h +++ b/include/opcode/riscv-opc-extended.h @@ -1447,6 +1447,17 @@ #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 0x36000073 +#define MASK_HINVAL_VVMA 0xfe007fff +#define MATCH_HINVAL_GVMA 0x76000073 +#define MASK_HINVAL_GVMA 0xfe007fff #endif /* RISCV_EXTENDED_ENCODING_H */ #ifdef DECLARE_INSN DECLARE_INSN(fadd_h, MATCH_FADD_H, MASK_FADD_H) @@ -1485,6 +1496,11 @@ DECLARE_INSN(fmadd_h, MATCH_FMADD_H, MASK_FMADD_H) DECLARE_INSN(fmsub_h, MATCH_FMSUB_H, MASK_FMSUB_H) DECLARE_INSN(fnmsub_h, MATCH_FNMSUB_H, MASK_FNMSUB_H) DECLARE_INSN(fnmadd_h, MATCH_FNMADD_H, MASK_FNMADD_H) +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 /* Unprivileged extended CSR addresses. */ diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h index 2d9c6650d44..4c85ac13227 100644 --- a/include/opcode/riscv.h +++ b/include/opcode/riscv.h @@ -504,6 +504,7 @@ enum riscv_extended_insn_class INSN_CLASS_ZFH, INSN_CLASS_D_AND_ZFH, INSN_CLASS_Q_AND_ZFH, + INSN_CLASS_SVINVAL, }; /* This is a list of macro expanded instructions for extended diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c index 5962624cbe4..df59d939a05 100644 --- a/opcodes/riscv-opc.c +++ b/opcodes/riscv-opc.c @@ -2227,6 +2227,13 @@ const struct riscv_opcode riscv_draft_opcodes[] = {"vmv4r.v", 0, INSN_CLASS_V, "Vd,Vt", MATCH_VMV4RV, MASK_VMV4RV, match_vmv_nf_rv, 0}, {"vmv8r.v", 0, INSN_CLASS_V, "Vd,Vt", MATCH_VMV8RV, MASK_VMV8RV, match_vmv_nf_rv, 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 }, };