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 <lifang_xia@linux.alibaba.com>
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
This commit is contained in:
Christoph Müllner
2022-06-28 17:43:20 +02:00
committed by Philipp Tomsich
parent fb1737381d
commit a9ba8bc2d3
10 changed files with 199 additions and 0 deletions

View File

@ -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_*"));

View File

@ -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

View File

@ -0,0 +1,3 @@
#as: -march=rv64i_xtheadcmo
#source: x-thead-cmo-fail.s
#error_output: x-thead-cmo-fail.l

View File

@ -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'

View File

@ -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

View File

@ -0,0 +1,30 @@
#as: -march=rv64i_xtheadcmo
#source: x-thead-cmo.s
#objdump: -dr
.*:[ ]+file format .*
Disassembly of section .text:
0+000 <target>:
[ ]+[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

View File

@ -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

View File

@ -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. */

View File

@ -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. */

View File

@ -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}
};