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>
static struct riscv_supported_ext riscv_supported_vendor_x_ext[] =
{
+ {"xtheadcmo", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{NULL, 0, 0, 0, 0}
};
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_*"));
return "svinval";
case INSN_CLASS_H:
return _("h");
+ case INSN_CLASS_XTHEADCMO:
+ return "xtheadcmo";
default:
rps->error_handler
(_("internal: unreachable INSN_CLASS_*"));
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
--- /dev/null
+#as: -march=rv64i_xtheadcmo
+#source: x-thead-cmo-fail.s
+#error_output: x-thead-cmo-fail.l
--- /dev/null
+.*: 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'
--- /dev/null
+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
--- /dev/null
+#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
--- /dev/null
+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
#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
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. */
INSN_CLASS_ZICBOP,
INSN_CLASS_ZICBOZ,
INSN_CLASS_H,
+ INSN_CLASS_XTHEADCMO,
};
/* This structure holds information for a particular instruction. */
{"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}
};