From: Christoph Müllner Date: Tue, 28 Jun 2022 15:43:20 +0000 (+0200) Subject: RISC-V: Add T-Head CMO vendor extension X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a9ba8bc2d396fb8ae2b892f3bc6be8cdfe4b555c;p=binutils-gdb.git RISC-V: Add T-Head CMO vendor extension T-Head has a range of vendor-specific instructions. Therefore it makes sense to group them into smaller chunks in form of vendor extensions. This patch adds the XTheadCmo extension, a collection of T-Head specific cache management operations. The 'th' prefix and the "XTheadCmo" extension are documented in a PR for the RISC-V toolchain conventions ([1]). In total XTheadCmo introduces the following 21 instructions: * DCACHE.{C,CI,I}ALL * DCACHE.{C,CI,I}{PA,VA,SW} rs1 * DCACHE.C{PAL1,VAL1} rs1 * ICACHE.I{ALL,ALLS} * ICACHE.I{PA,VA} rs1 * L2CACHE.{C,CI,I}ALL Contrary to Zicbom, the XTheadCmo instructions don't have a constant displacement, therefore we have a different syntax for the arguments. To clarify this is intended behaviour, there is a set of negative test for Zicbom-style arguments in x-thead-cmo-fail.s. [1] https://github.com/riscv-non-isa/riscv-toolchain-conventions/pull/19 v2: - Add missing DECLARE_INSN() list - Fix ordering Co-developed-by: Lifang Xia Signed-off-by: Christoph Müllner --- diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index cb3a980936d..82891f3747e 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -1224,6 +1224,7 @@ static struct riscv_supported_ext riscv_supported_std_zxm_ext[] = static struct riscv_supported_ext riscv_supported_vendor_x_ext[] = { + {"xtheadcmo", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 }, {NULL, 0, 0, 0, 0} }; @@ -2386,6 +2387,8 @@ riscv_multi_subset_supports (riscv_parse_subset_t *rps, return riscv_subset_supports (rps, "svinval"); case INSN_CLASS_H: return riscv_subset_supports (rps, "h"); + case INSN_CLASS_XTHEADCMO: + return riscv_subset_supports (rps, "xtheadcmo"); default: rps->error_handler (_("internal: unreachable INSN_CLASS_*")); @@ -2513,6 +2516,8 @@ riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps, return "svinval"; case INSN_CLASS_H: return _("h"); + case INSN_CLASS_XTHEADCMO: + return "xtheadcmo"; default: rps->error_handler (_("internal: unreachable INSN_CLASS_*")); diff --git a/gas/doc/c-riscv.texi b/gas/doc/c-riscv.texi index 30afd200b7d..10e9429c83e 100644 --- a/gas/doc/c-riscv.texi +++ b/gas/doc/c-riscv.texi @@ -704,5 +704,9 @@ extensions supported and provides the location of their publicly-released documentation: @table @r +@item XTheadCmo +The XTheadCmo extension provides instructions for cache management. + +It is documented in @url{https://github.com/T-head-Semi/thead-extension-spec/releases/download/2.0.0/xthead-2022-09-05-2.0.0.pdf}. @end table diff --git a/gas/testsuite/gas/riscv/x-thead-cmo-fail.d b/gas/testsuite/gas/riscv/x-thead-cmo-fail.d new file mode 100644 index 00000000000..de794ea5837 --- /dev/null +++ b/gas/testsuite/gas/riscv/x-thead-cmo-fail.d @@ -0,0 +1,3 @@ +#as: -march=rv64i_xtheadcmo +#source: x-thead-cmo-fail.s +#error_output: x-thead-cmo-fail.l diff --git a/gas/testsuite/gas/riscv/x-thead-cmo-fail.l b/gas/testsuite/gas/riscv/x-thead-cmo-fail.l new file mode 100644 index 00000000000..4381fe19a99 --- /dev/null +++ b/gas/testsuite/gas/riscv/x-thead-cmo-fail.l @@ -0,0 +1,22 @@ +.*: Assembler messages: +.*: Error: illegal operands `th.dcache.call x1' +.*: Error: illegal operands `th.dcache.ciall x1' +.*: Error: illegal operands `th.dcache.iall x1' +.*: Error: illegal operands `th.dcache.cpa 0\(x1\)' +.*: Error: illegal operands `th.dcache.cipa 0\(x1\)' +.*: Error: illegal operands `th.dcache.ipa 0\(x1\)' +.*: Error: illegal operands `th.dcache.cva 0\(x1\)' +.*: Error: illegal operands `th.dcache.civa 0\(x1\)' +.*: Error: illegal operands `th.dcache.iva 0\(x1\)' +.*: Error: illegal operands `th.dcache.csw 0\(x1\)' +.*: Error: illegal operands `th.dcache.cisw 0\(x1\)' +.*: Error: illegal operands `th.dcache.isw 0\(x1\)' +.*: Error: illegal operands `th.dcache.cpal1 0\(x1\)' +.*: Error: illegal operands `th.dcache.cval1 0\(x1\)' +.*: Error: illegal operands `th.icache.iall x1' +.*: Error: illegal operands `th.icache.ialls x1' +.*: Error: illegal operands `th.icache.ipa 0\(x1\)' +.*: Error: illegal operands `th.icache.iva 0\(x1\)' +.*: Error: illegal operands `th.l2cache.call x1' +.*: Error: illegal operands `th.l2cache.ciall x1' +.*: Error: illegal operands `th.l2cache.iall x1' diff --git a/gas/testsuite/gas/riscv/x-thead-cmo-fail.s b/gas/testsuite/gas/riscv/x-thead-cmo-fail.s new file mode 100644 index 00000000000..591d982eae5 --- /dev/null +++ b/gas/testsuite/gas/riscv/x-thead-cmo-fail.s @@ -0,0 +1,22 @@ +target: + th.dcache.call x1 + th.dcache.ciall x1 + th.dcache.iall x1 + th.dcache.cpa 0(x1) + th.dcache.cipa 0(x1) + th.dcache.ipa 0(x1) + th.dcache.cva 0(x1) + th.dcache.civa 0(x1) + th.dcache.iva 0(x1) + th.dcache.csw 0(x1) + th.dcache.cisw 0(x1) + th.dcache.isw 0(x1) + th.dcache.cpal1 0(x1) + th.dcache.cval1 0(x1) + th.icache.iall x1 + th.icache.ialls x1 + th.icache.ipa 0(x1) + th.icache.iva 0(x1) + th.l2cache.call x1 + th.l2cache.ciall x1 + th.l2cache.iall x1 diff --git a/gas/testsuite/gas/riscv/x-thead-cmo.d b/gas/testsuite/gas/riscv/x-thead-cmo.d new file mode 100644 index 00000000000..f482ddcbc28 --- /dev/null +++ b/gas/testsuite/gas/riscv/x-thead-cmo.d @@ -0,0 +1,30 @@ +#as: -march=rv64i_xtheadcmo +#source: x-thead-cmo.s +#objdump: -dr + +.*:[ ]+file format .* + +Disassembly of section .text: + +0+000 : +[ ]+[0-9a-f]+:[ ]+0010000b[ ]+th.dcache.call +[ ]+[0-9a-f]+:[ ]+0030000b[ ]+th.dcache.ciall +[ ]+[0-9a-f]+:[ ]+0020000b[ ]+th.dcache.iall +[ ]+[0-9a-f]+:[ ]+0295000b[ ]+th.dcache.cpa[ ]+a0 +[ ]+[0-9a-f]+:[ ]+02b5800b[ ]+th.dcache.cipa[ ]+a1 +[ ]+[0-9a-f]+:[ ]+02a6000b[ ]+th.dcache.ipa[ ]+a2 +[ ]+[0-9a-f]+:[ ]+0256800b[ ]+th.dcache.cva[ ]+a3 +[ ]+[0-9a-f]+:[ ]+0277000b[ ]+th.dcache.civa[ ]+a4 +[ ]+[0-9a-f]+:[ ]+0267800b[ ]+th.dcache.iva[ ]+a5 +[ ]+[0-9a-f]+:[ ]+0218000b[ ]+th.dcache.csw[ ]+a6 +[ ]+[0-9a-f]+:[ ]+0238800b[ ]+th.dcache.cisw[ ]+a7 +[ ]+[0-9a-f]+:[ ]+0222800b[ ]+th.dcache.isw[ ]+t0 +[ ]+[0-9a-f]+:[ ]+0283000b[ ]+th.dcache.cpal1[ ]+t1 +[ ]+[0-9a-f]+:[ ]+0243800b[ ]+th.dcache.cval1[ ]+t2 +[ ]+[0-9a-f]+:[ ]+0100000b[ ]+th.icache.iall +[ ]+[0-9a-f]+:[ ]+0110000b[ ]+th.icache.ialls +[ ]+[0-9a-f]+:[ ]+038e000b[ ]+th.icache.ipa[ ]+t3 +[ ]+[0-9a-f]+:[ ]+030e800b[ ]+th.icache.iva[ ]+t4 +[ ]+[0-9a-f]+:[ ]+0150000b[ ]+th.l2cache.call +[ ]+[0-9a-f]+:[ ]+0170000b[ ]+th.l2cache.ciall +[ ]+[0-9a-f]+:[ ]+0160000b[ ]+th.l2cache.iall diff --git a/gas/testsuite/gas/riscv/x-thead-cmo.s b/gas/testsuite/gas/riscv/x-thead-cmo.s new file mode 100644 index 00000000000..2a4b54a941b --- /dev/null +++ b/gas/testsuite/gas/riscv/x-thead-cmo.s @@ -0,0 +1,22 @@ +target: + th.dcache.call + th.dcache.ciall + th.dcache.iall + th.dcache.cpa a0 + th.dcache.cipa a1 + th.dcache.ipa a2 + th.dcache.cva a3 + th.dcache.civa a4 + th.dcache.iva a5 + th.dcache.csw a6 + th.dcache.cisw a7 + th.dcache.isw t0 + th.dcache.cpal1 t1 + th.dcache.cval1 t2 + th.icache.iall + th.icache.ialls + th.icache.ipa t3 + th.icache.iva t4 + th.l2cache.call + th.l2cache.ciall + th.l2cache.iall diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h index 88b8d7ff595..53b1c224518 100644 --- a/include/opcode/riscv-opc.h +++ b/include/opcode/riscv-opc.h @@ -2113,6 +2113,49 @@ #define MASK_CBO_INVAL 0xfff07fff #define MATCH_CBO_ZERO 0x40200f #define MASK_CBO_ZERO 0xfff07fff +/* Vendor-specific (T-Head) XTheadCmo instructions. */ +#define MATCH_TH_DCACHE_CALL 0x0010000b +#define MASK_TH_DCACHE_CALL 0xffffffff +#define MATCH_TH_DCACHE_CIALL 0x0030000b +#define MASK_TH_DCACHE_CIALL 0xffffffff +#define MATCH_TH_DCACHE_IALL 0x0020000b +#define MASK_TH_DCACHE_IALL 0xffffffff +#define MATCH_TH_DCACHE_CPA 0x0290000b +#define MASK_TH_DCACHE_CPA 0xfff07fff +#define MATCH_TH_DCACHE_CIPA 0x02b0000b +#define MASK_TH_DCACHE_CIPA 0xfff07fff +#define MATCH_TH_DCACHE_IPA 0x02a0000b +#define MASK_TH_DCACHE_IPA 0xfff07fff +#define MATCH_TH_DCACHE_CVA 0x0250000b +#define MASK_TH_DCACHE_CVA 0xfff07fff +#define MATCH_TH_DCACHE_CIVA 0x0270000b +#define MASK_TH_DCACHE_CIVA 0xfff07fff +#define MATCH_TH_DCACHE_IVA 0x0260000b +#define MASK_TH_DCACHE_IVA 0xfff07fff +#define MATCH_TH_DCACHE_CSW 0x0210000b +#define MASK_TH_DCACHE_CSW 0xfff07fff +#define MATCH_TH_DCACHE_CISW 0x0230000b +#define MASK_TH_DCACHE_CISW 0xfff07fff +#define MATCH_TH_DCACHE_ISW 0x0220000b +#define MASK_TH_DCACHE_ISW 0xfff07fff +#define MATCH_TH_DCACHE_CPAL1 0x0280000b +#define MASK_TH_DCACHE_CPAL1 0xfff07fff +#define MATCH_TH_DCACHE_CVAL1 0x0240000b +#define MASK_TH_DCACHE_CVAL1 0xfff07fff +#define MATCH_TH_ICACHE_IALL 0x0100000b +#define MASK_TH_ICACHE_IALL 0xffffffff +#define MATCH_TH_ICACHE_IALLS 0x0110000b +#define MASK_TH_ICACHE_IALLS 0xffffffff +#define MATCH_TH_ICACHE_IPA 0x0380000b +#define MASK_TH_ICACHE_IPA 0xfff07fff +#define MATCH_TH_ICACHE_IVA 0x0300000b +#define MASK_TH_ICACHE_IVA 0xfff07fff +#define MATCH_TH_L2CACHE_CALL 0x0150000b +#define MASK_TH_L2CACHE_CALL 0xffffffff +#define MATCH_TH_L2CACHE_CIALL 0x0170000b +#define MASK_TH_L2CACHE_CIALL 0xffffffff +#define MATCH_TH_L2CACHE_IALL 0x0160000b +#define MASK_TH_L2CACHE_IALL 0xffffffff /* Unprivileged Counter/Timers CSR addresses. */ #define CSR_CYCLE 0xc00 #define CSR_TIME 0xc01 @@ -2852,6 +2895,28 @@ DECLARE_INSN(cbo_clean, MATCH_CBO_CLEAN, MASK_CBO_CLEAN); DECLARE_INSN(cbo_flush, MATCH_CBO_FLUSH, MASK_CBO_FLUSH); DECLARE_INSN(cbo_inval, MATCH_CBO_INVAL, MASK_CBO_INVAL); DECLARE_INSN(cbo_zero, MATCH_CBO_ZERO, MASK_CBO_ZERO); +/* Vendor-specific (T-Head) XTheadCmo instructions. */ +DECLARE_INSN(th_dcache_call, MATCH_TH_DCACHE_CALL, MASK_TH_DCACHE_CALL) +DECLARE_INSN(th_dcache_ciall, MATCH_TH_DCACHE_CIALL, MASK_TH_DCACHE_CIALL) +DECLARE_INSN(th_dcache_iall, MATCH_TH_DCACHE_IALL, MASK_TH_DCACHE_IALL) +DECLARE_INSN(th_dcache_cpa, MATCH_TH_DCACHE_CPA, MASK_TH_DCACHE_CPA) +DECLARE_INSN(th_dcache_cipa, MATCH_TH_DCACHE_CIPA, MASK_TH_DCACHE_CIPA) +DECLARE_INSN(th_dcache_ipa, MATCH_TH_DCACHE_IPA, MASK_TH_DCACHE_IPA) +DECLARE_INSN(th_dcache_cva, MATCH_TH_DCACHE_CVA, MASK_TH_DCACHE_CVA) +DECLARE_INSN(th_dcache_civa, MATCH_TH_DCACHE_CIVA, MASK_TH_DCACHE_CIVA) +DECLARE_INSN(th_dcache_iva, MATCH_TH_DCACHE_IVA, MASK_TH_DCACHE_IVA) +DECLARE_INSN(th_dcache_csw, MATCH_TH_DCACHE_CSW, MASK_TH_DCACHE_CSW) +DECLARE_INSN(th_dcache_cisw, MATCH_TH_DCACHE_CISW, MASK_TH_DCACHE_CISW) +DECLARE_INSN(th_dcache_isw, MATCH_TH_DCACHE_ISW, MASK_TH_DCACHE_ISW) +DECLARE_INSN(th_dcache_cpal1, MATCH_TH_DCACHE_CPAL1, MASK_TH_DCACHE_CPAL1) +DECLARE_INSN(th_dcache_cval1, MATCH_TH_DCACHE_CVAL1, MASK_TH_DCACHE_CVAL1) +DECLARE_INSN(th_icache_iall, MATCH_TH_ICACHE_IALL, MASK_TH_ICACHE_IALL) +DECLARE_INSN(th_icache_ialls, MATCH_TH_ICACHE_IALLS, MASK_TH_ICACHE_IALLS) +DECLARE_INSN(th_icache_ipa, MATCH_TH_ICACHE_IPA, MASK_TH_ICACHE_IPA) +DECLARE_INSN(th_icache_iva, MATCH_TH_ICACHE_IVA, MASK_TH_ICACHE_IVA) +DECLARE_INSN(th_l2cache_call, MATCH_TH_L2CACHE_CALL, MASK_TH_L2CACHE_CALL) +DECLARE_INSN(th_l2cache_ciall, MATCH_TH_L2CACHE_CIALL, MASK_TH_L2CACHE_CIALL) +DECLARE_INSN(th_l2cache_iall, MATCH_TH_L2CACHE_IALL, MASK_TH_L2CACHE_IALL) #endif /* DECLARE_INSN */ #ifdef DECLARE_CSR /* Unprivileged Counter/Timers CSRs. */ diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h index f1dabeaab8e..d36983140a2 100644 --- a/include/opcode/riscv.h +++ b/include/opcode/riscv.h @@ -398,6 +398,7 @@ enum riscv_insn_class INSN_CLASS_ZICBOP, INSN_CLASS_ZICBOZ, INSN_CLASS_H, + INSN_CLASS_XTHEADCMO, }; /* This structure holds information for a particular instruction. */ diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c index 79be78eb367..bf073f20e71 100644 --- a/opcodes/riscv-opc.c +++ b/opcodes/riscv-opc.c @@ -1825,6 +1825,31 @@ const struct riscv_opcode riscv_opcodes[] = {"hsv.w", 0, INSN_CLASS_H, "t,0(s)", MATCH_HSV_W, MASK_HSV_W, match_opcode, INSN_DREF|INSN_4_BYTE }, {"hsv.d", 64, INSN_CLASS_H, "t,0(s)", MATCH_HSV_D, MASK_HSV_D, match_opcode, INSN_DREF|INSN_8_BYTE }, +/* Vendor-specific (T-Head) XTheadCmo instructions. */ +{"th.dcache.call", 0, INSN_CLASS_XTHEADCMO, "", MATCH_TH_DCACHE_CALL, MASK_TH_DCACHE_CALL, match_opcode, 0}, +{"th.dcache.ciall", 0, INSN_CLASS_XTHEADCMO, "", MATCH_TH_DCACHE_CIALL, MASK_TH_DCACHE_CIALL, match_opcode, 0}, +{"th.dcache.iall", 0, INSN_CLASS_XTHEADCMO, "", MATCH_TH_DCACHE_IALL, MASK_TH_DCACHE_IALL, match_opcode, 0}, +{"th.dcache.cpa", 0, INSN_CLASS_XTHEADCMO, "s", MATCH_TH_DCACHE_CPA, MASK_TH_DCACHE_CPA, match_opcode, 0}, +{"th.dcache.cipa", 0, INSN_CLASS_XTHEADCMO, "s", MATCH_TH_DCACHE_CIPA, MASK_TH_DCACHE_CIPA, match_opcode, 0}, +{"th.dcache.ipa", 0, INSN_CLASS_XTHEADCMO, "s", MATCH_TH_DCACHE_IPA, MASK_TH_DCACHE_IPA, match_opcode, 0}, +{"th.dcache.cva", 0, INSN_CLASS_XTHEADCMO, "s", MATCH_TH_DCACHE_CVA, MASK_TH_DCACHE_CVA, match_opcode, 0}, +{"th.dcache.civa", 0, INSN_CLASS_XTHEADCMO, "s", MATCH_TH_DCACHE_CIVA, MASK_TH_DCACHE_CIVA, match_opcode, 0}, +{"th.dcache.iva", 0, INSN_CLASS_XTHEADCMO, "s", MATCH_TH_DCACHE_IVA, MASK_TH_DCACHE_IVA, match_opcode, 0}, +{"th.dcache.csw", 0, INSN_CLASS_XTHEADCMO, "s", MATCH_TH_DCACHE_CSW, MASK_TH_DCACHE_CSW, match_opcode, 0}, +{"th.dcache.cisw", 0, INSN_CLASS_XTHEADCMO, "s", MATCH_TH_DCACHE_CISW, MASK_TH_DCACHE_CISW, match_opcode, 0}, +{"th.dcache.isw", 0, INSN_CLASS_XTHEADCMO, "s", MATCH_TH_DCACHE_ISW, MASK_TH_DCACHE_ISW, match_opcode, 0}, +{"th.dcache.cpal1", 0, INSN_CLASS_XTHEADCMO, "s", MATCH_TH_DCACHE_CPAL1, MASK_TH_DCACHE_CPAL1, match_opcode, 0}, +{"th.dcache.cval1", 0, INSN_CLASS_XTHEADCMO, "s", MATCH_TH_DCACHE_CVAL1, MASK_TH_DCACHE_CVAL1, match_opcode, 0}, + +{"th.icache.iall", 0, INSN_CLASS_XTHEADCMO, "", MATCH_TH_ICACHE_IALL, MASK_TH_ICACHE_IALL, match_opcode, 0}, +{"th.icache.ialls", 0, INSN_CLASS_XTHEADCMO, "", MATCH_TH_ICACHE_IALLS, MASK_TH_ICACHE_IALLS, match_opcode, 0}, +{"th.icache.ipa", 0, INSN_CLASS_XTHEADCMO, "s", MATCH_TH_ICACHE_IPA, MASK_TH_ICACHE_IPA, match_opcode, 0}, +{"th.icache.iva", 0, INSN_CLASS_XTHEADCMO, "s", MATCH_TH_ICACHE_IVA, MASK_TH_ICACHE_IVA, match_opcode, 0}, + +{"th.l2cache.call", 0, INSN_CLASS_XTHEADCMO, "", MATCH_TH_L2CACHE_CALL, MASK_TH_L2CACHE_CALL, match_opcode, 0}, +{"th.l2cache.ciall", 0, INSN_CLASS_XTHEADCMO, "", MATCH_TH_L2CACHE_CIALL, MASK_TH_L2CACHE_CIALL, match_opcode, 0}, +{"th.l2cache.iall", 0, INSN_CLASS_XTHEADCMO, "", MATCH_TH_L2CACHE_IALL, MASK_TH_L2CACHE_IALL, match_opcode, 0}, + /* Terminate the list. */ {0, 0, INSN_CLASS_NONE, 0, 0, 0, 0, 0} };