diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst --- a/llvm/docs/RISCVUsage.rst +++ b/llvm/docs/RISCVUsage.rst @@ -186,6 +186,9 @@ ``XTHeadBs`` LLVM implements `the THeadBs (single-bit operations) vendor-defined instructions specified in `_ by T-HEAD of Alibaba. Instructions are prefixed with `th.` as described in the specification. +``XTHeadCmo`` + LLVM implements `the THeadCmo (cache management operations) vendor-defined instructions specified in `_ by T-HEAD of Alibaba. Instructions are prefixed with `th.` as described in the specification. + ``XTheadMac`` LLVM implements `the XTheadMac (multiply-accumulate instructions) vendor-defined instructions specified in `_ by T-HEAD of Alibaba. Instructions are prefixed with `th.` as described in the specification. diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -115,6 +115,7 @@ * Added support for the vendor-defined XTHeadMemPair (two-GPR memory operations) extension disassembler/assembler. * Support for the now-ratified Zawrs extension is no longer experimental. +* Adds support for the vendor-defined XTHeadCmo (cache management operations) extension. Changes to the WebAssembly Backend ---------------------------------- diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp --- a/llvm/lib/Support/RISCVISAInfo.cpp +++ b/llvm/lib/Support/RISCVISAInfo.cpp @@ -116,6 +116,7 @@ {"xtheadba", RISCVExtensionVersion{1, 0}}, {"xtheadbb", RISCVExtensionVersion{1, 0}}, {"xtheadbs", RISCVExtensionVersion{1, 0}}, + {"xtheadcmo", RISCVExtensionVersion{1, 0}}, {"xtheadmac", RISCVExtensionVersion{1, 0}}, {"xtheadmempair", RISCVExtensionVersion{1, 0}}, {"xtheadvdot", RISCVExtensionVersion{1, 0}}, diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -520,6 +520,13 @@ if (Result != MCDisassembler::Fail) return Result; } + if (STI.hasFeature(RISCV::FeatureVendorXTHeadCmo)) { + LLVM_DEBUG(dbgs() << "Trying XTHeadCmo custom opcode table:\n"); + Result = decodeInstruction(DecoderTableTHeadCmo32, MI, Insn, Address, + this, STI); + if (Result != MCDisassembler::Fail) + return Result; + } if (STI.hasFeature(RISCV::FeatureVendorXTHeadMac)) { LLVM_DEBUG(dbgs() << "Trying XTHeadMac custom opcode table:\n"); Result = decodeInstruction(DecoderTableTHeadMac32, MI, Insn, Address, diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -505,6 +505,13 @@ AssemblerPredicate<(all_of FeatureVendorXTHeadBs), "'xtheadbs' (T-Head single-bit instructions)">; +def FeatureVendorXTHeadCmo + : SubtargetFeature<"xtheadcmo", "HasVendorXTHeadCmo", "true", + "'xtheadcmo' (T-Head cache management instructions)">; +def HasVendorXTHeadCmo : Predicate<"Subtarget->hasVendorXTHeadCmo()">, + AssemblerPredicate<(all_of FeatureVendorXTHeadCmo), + "'xtheadcmo' (T-Head cache management instructions)">; + def FeatureVendorXTHeadMac : SubtargetFeature<"xtheadmac", "HasVendorXTHeadMac", "true", "'xtheadmac' (T-Head Multiply-Accumulate Instructions)">; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td @@ -141,6 +141,23 @@ let DecoderMethod = "decodeXTHeadMemPair"; } +let Predicates = [HasVendorXTHeadCmo], DecoderNamespace = "THeadCmo", + hasSideEffects = 1, mayLoad = 0, mayStore = 0 in +class THCacheInst_r funct5, string opcodestr> + : RVInstR<0b0000001, 0, OPC_CUSTOM_0, (outs), (ins GPR:$rs1), + opcodestr, "$rs1"> { + let rd = 0; + let rs2 = funct5; +} + +let Predicates = [HasVendorXTHeadCmo], DecoderNamespace = "THeadCmo", + hasSideEffects = 1, mayLoad = 0, mayStore = 0 in +class THCacheInst_void funct5, string opcodestr> + : RVInstR<0b0000000, 0, OPC_CUSTOM_0, (outs), (ins), opcodestr, ""> { + let rd = 0; + let rs1 = 0; + let rs2 = funct5; +} //===----------------------------------------------------------------------===// // Combination of instruction classes. @@ -483,3 +500,28 @@ def : Pat<(th_swd GPR:$rd1, GPR:$rd2, GPR:$rs1, uimm2_3:$uimm2_3), (TH_SWD GPR:$rd1, GPR:$rd2, GPR:$rs1, uimm2_3:$uimm2_3, 3)>; } + +let Predicates = [HasVendorXTHeadCmo] in { +def TH_DCACHE_CSW : THCacheInst_r<0b00001, "th.dcache.csw">; +def TH_DCACHE_ISW : THCacheInst_r<0b00010, "th.dcache.isw">; +def TH_DCACHE_CISW : THCacheInst_r<0b00011, "th.dcache.cisw">; +def TH_DCACHE_CVAL1 : THCacheInst_r<0b00100, "th.dcache.cval1">; +def TH_DCACHE_CVA : THCacheInst_r<0b00101, "th.dcache.cva">; +def TH_DCACHE_IVA : THCacheInst_r<0b00110, "th.dcache.iva">; +def TH_DCACHE_CIVA : THCacheInst_r<0b00111, "th.dcache.civa">; +def TH_DCACHE_CPAL1 : THCacheInst_r<0b01000, "th.dcache.cpal1">; +def TH_DCACHE_CPA : THCacheInst_r<0b01001, "th.dcache.cpa">; +def TH_DCACHE_IPA : THCacheInst_r<0b01010, "th.dcache.ipa">; +def TH_DCACHE_CIPA : THCacheInst_r<0b01011, "th.dcache.cipa">; +def TH_ICACHE_IVA : THCacheInst_r<0b10000, "th.icache.iva">; +def TH_ICACHE_IPA : THCacheInst_r<0b11000, "th.icache.ipa">; + +def TH_DCACHE_CALL : THCacheInst_void<0b00001, "th.dcache.call">; +def TH_DCACHE_IALL : THCacheInst_void<0b00010, "th.dcache.iall">; +def TH_DCACHE_CIALL : THCacheInst_void<0b00011, "th.dcache.ciall">; +def TH_ICACHE_IALL : THCacheInst_void<0b10000, "th.icache.iall">; +def TH_ICACHE_IALLS : THCacheInst_void<0b10001, "th.icache.ialls">; +def TH_L2CACHE_CALL : THCacheInst_void<0b10101, "th.l2cache.call">; +def TH_L2CACHE_IALL : THCacheInst_void<0b10110, "th.l2cache.iall">; +def TH_L2CACHE_CIALL : THCacheInst_void<0b10111, "th.l2cache.ciall">; +} diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll --- a/llvm/test/CodeGen/RISCV/attributes.ll +++ b/llvm/test/CodeGen/RISCV/attributes.ll @@ -41,6 +41,7 @@ ; RUN: llc -mtriple=riscv32 -mattr=+svnapot %s -o - | FileCheck --check-prefixes=CHECK,RV32SVNAPOT %s ; RUN: llc -mtriple=riscv32 -mattr=+svpbmt %s -o - | FileCheck --check-prefixes=CHECK,RV32SVPBMT %s ; RUN: llc -mtriple=riscv32 -mattr=+svinval %s -o - | FileCheck --check-prefixes=CHECK,RV32SVINVAL %s +; RUN: llc -mtriple=riscv32 -mattr=+xtheadcmo %s -o - | FileCheck --check-prefix=RV32XTHEADCMO %s ; RUN: llc -mtriple=riscv32 -mattr=+xtheadmac %s -o - | FileCheck --check-prefixes=CHECK,RV32XTHEADMAC %s ; RUN: llc -mtriple=riscv32 -mattr=+xtheadmempair %s -o - | FileCheck --check-prefix=RV32XTHEADMEMPAIR %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zca %s -o - | FileCheck --check-prefixes=CHECK,RV32ZCA %s @@ -96,6 +97,7 @@ ; RUN: llc -mtriple=riscv64 -mattr=+xtheadba %s -o - | FileCheck --check-prefixes=CHECK,RV64XTHEADBA %s ; RUN: llc -mtriple=riscv64 -mattr=+xtheadbb %s -o - | FileCheck --check-prefixes=CHECK,RV64XTHEADBB %s ; RUN: llc -mtriple=riscv64 -mattr=+xtheadbs %s -o - | FileCheck --check-prefixes=CHECK,RV64XTHEADBS %s +; RUN: llc -mtriple=riscv64 -mattr=+xtheadcmo %s -o - | FileCheck --check-prefix=RV64XTHEADCMO %s ; RUN: llc -mtriple=riscv64 -mattr=+xtheadmac %s -o - | FileCheck --check-prefixes=CHECK,RV64XTHEADMAC %s ; RUN: llc -mtriple=riscv64 -mattr=+xtheadmempair %s -o - | FileCheck --check-prefix=RV64XTHEADMEMPAIR %s ; RUN: llc -mtriple=riscv64 -mattr=+xtheadvdot %s -o - | FileCheck --check-prefixes=CHECK,RV64XTHEADVDOT %s @@ -150,6 +152,7 @@ ; RV32SVNAPOT: .attribute 5, "rv32i2p0_svnapot1p0" ; RV32SVPBMT: .attribute 5, "rv32i2p0_svpbmt1p0" ; RV32SVINVAL: .attribute 5, "rv32i2p0_svinval1p0" +; RV32XTHEADCMO: .attribute 5, "rv32i2p0_xtheadcmo1p0" ; RV32XTHEADMAC: .attribute 5, "rv32i2p0_xtheadmac1p0" ; RV32XTHEADMEMPAIR: .attribute 5, "rv32i2p0_xtheadmempair1p0" ; RV32ZCA: .attribute 5, "rv32i2p0_zca1p0" @@ -205,6 +208,7 @@ ; RV64XTHEADBA: .attribute 5, "rv64i2p0_xtheadba1p0" ; RV64XTHEADBB: .attribute 5, "rv64i2p0_xtheadbb1p0" ; RV64XTHEADBS: .attribute 5, "rv64i2p0_xtheadbs1p0" +; RV64XTHEADCMO: .attribute 5, "rv64i2p0_xtheadcmo1p0" ; RV64XTHEADMAC: .attribute 5, "rv64i2p0_xtheadmac1p0" ; RV64XTHEADMEMPAIR: .attribute 5, "rv64i2p0_xtheadmempair1p0" ; RV64XTHEADVDOT: .attribute 5, "rv64i2p0_f2p0_d2p0_v1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0_xtheadvdot1p0" diff --git a/llvm/test/MC/RISCV/xtheadcmo-invalid.s b/llvm/test/MC/RISCV/xtheadcmo-invalid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/xtheadcmo-invalid.s @@ -0,0 +1,25 @@ +# RUN: not llvm-mc -triple riscv32 -mattr=+xtheadcmo < %s 2>&1 | FileCheck %s +# RUN: not llvm-mc -triple riscv64 -mattr=+xtheadcmo < %s 2>&1 | FileCheck %s + +th.dcache.csw # CHECK: :[[@LINE]]:1: error: too few operands for instruction +th.dcache.isw # CHECK: :[[@LINE]]:1: error: too few operands for instruction +th.dcache.cisw # CHECK: :[[@LINE]]:1: error: too few operands for instruction +th.dcache.cval1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction +th.dcache.cva # CHECK: :[[@LINE]]:1: error: too few operands for instruction +th.dcache.iva # CHECK: :[[@LINE]]:1: error: too few operands for instruction +th.dcache.civa # CHECK: :[[@LINE]]:1: error: too few operands for instruction +th.dcache.cpal1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction +th.dcache.cpa # CHECK: :[[@LINE]]:1: error: too few operands for instruction +th.dcache.ipa # CHECK: :[[@LINE]]:1: error: too few operands for instruction +th.dcache.cipa # CHECK: :[[@LINE]]:1: error: too few operands for instruction +th.icache.iva # CHECK: :[[@LINE]]:1: error: too few operands for instruction +th.icache.ipa # CHECK: :[[@LINE]]:1: error: too few operands for instruction + +th.dcache.call t0 # CHECK: :[[@LINE]]:16: error: invalid operand for instruction +th.dcache.iall t0 # CHECK: :[[@LINE]]:16: error: invalid operand for instruction +th.dcache.ciall t0 # CHECK: :[[@LINE]]:17: error: invalid operand for instruction +th.icache.iall t0 # CHECK: :[[@LINE]]:16: error: invalid operand for instruction +th.icache.ialls t0 # CHECK: :[[@LINE]]:17: error: invalid operand for instruction +th.l2cache.call t0 # CHECK: :[[@LINE]]:17: error: invalid operand for instruction +th.l2cache.iall t0 # CHECK: :[[@LINE]]:17: error: invalid operand for instruction +th.l2cache.ciall t0 # CHECK: :[[@LINE]]:18: error: invalid operand for instruction diff --git a/llvm/test/MC/RISCV/xtheadcmo-valid.s b/llvm/test/MC/RISCV/xtheadcmo-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/xtheadcmo-valid.s @@ -0,0 +1,94 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+xtheadcmo -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+xtheadcmo < %s \ +# RUN: | llvm-objdump --mattr=+xtheadcmo -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+xtheadcmo -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+xtheadcmo < %s \ +# RUN: | llvm-objdump --mattr=+xtheadcmo -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s + +# CHECK-ASM-AND-OBJ: th.dcache.csw a6 +# CHECK-ASM: encoding: [0x0b,0x00,0x18,0x02] +th.dcache.csw a6 + +# CHECK-ASM-AND-OBJ: th.dcache.isw t0 +# CHECK-ASM: encoding: [0x0b,0x80,0x22,0x02] +th.dcache.isw t0 + +# CHECK-ASM-AND-OBJ: th.dcache.cisw a7 +# CHECK-ASM: encoding: [0x0b,0x80,0x38,0x02] +th.dcache.cisw a7 + +# CHECK-ASM-AND-OBJ: th.dcache.cval1 t2 +# CHECK-ASM: encoding: [0x0b,0x80,0x43,0x02] +th.dcache.cval1 t2 + +# CHECK-ASM-AND-OBJ: th.dcache.cva a3 +# CHECK-ASM: encoding: [0x0b,0x80,0x56,0x02] +th.dcache.cva a3 + +# CHECK-ASM-AND-OBJ: th.dcache.iva a5 +# CHECK-ASM: encoding: [0x0b,0x80,0x67,0x02] +th.dcache.iva a5 + +# CHECK-ASM-AND-OBJ: th.dcache.civa a4 +# CHECK-ASM: encoding: [0x0b,0x00,0x77,0x02] +th.dcache.civa a4 + +# CHECK-ASM-AND-OBJ: th.dcache.cpal1 t1 +# CHECK-ASM: encoding: [0x0b,0x00,0x83,0x02] +th.dcache.cpal1 t1 + +# CHECK-ASM-AND-OBJ: th.dcache.cpa a0 +# CHECK-ASM: encoding: [0x0b,0x00,0x95,0x02] +th.dcache.cpa a0 + +# CHECK-ASM-AND-OBJ: th.dcache.ipa a2 +# CHECK-ASM: encoding: [0x0b,0x00,0xa6,0x02] +th.dcache.ipa a2 + +# CHECK-ASM-AND-OBJ: th.dcache.cipa a1 +# CHECK-ASM: encoding: [0x0b,0x80,0xb5,0x02] +th.dcache.cipa a1 + +# CHECK-ASM-AND-OBJ: th.icache.iva t4 +# CHECK-ASM: encoding: [0x0b,0x80,0x0e,0x03] +th.icache.iva t4 + +# CHECK-ASM-AND-OBJ: th.icache.ipa t3 +# CHECK-ASM: encoding: [0x0b,0x00,0x8e,0x03] +th.icache.ipa t3 + +# CHECK-ASM-AND-OBJ: th.dcache.call +# CHECK-ASM: encoding: [0x0b,0x00,0x10,0x00] +th.dcache.call + +# CHECK-ASM-AND-OBJ: th.dcache.iall +# CHECK-ASM: encoding: [0x0b,0x00,0x20,0x00] +th.dcache.iall + +# CHECK-ASM-AND-OBJ: th.dcache.ciall +# CHECK-ASM: encoding: [0x0b,0x00,0x30,0x00] +th.dcache.ciall + +# CHECK-ASM-AND-OBJ: th.icache.iall +# CHECK-ASM: encoding: [0x0b,0x00,0x00,0x01] +th.icache.iall + +# CHECK-ASM-AND-OBJ: th.icache.ialls +# CHECK-ASM: encoding: [0x0b,0x00,0x10,0x01] +th.icache.ialls + +# CHECK-ASM-AND-OBJ: th.l2cache.call +# CHECK-ASM: encoding: [0x0b,0x00,0x50,0x01] +th.l2cache.call + +# CHECK-ASM-AND-OBJ: th.l2cache.iall +# CHECK-ASM: encoding: [0x0b,0x00,0x60,0x01] +th.l2cache.iall + +# CHECK-ASM-AND-OBJ: th.l2cache.ciall +# CHECK-ASM: encoding: [0x0b,0x00,0x70,0x01] +th.l2cache.ciall