diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst --- a/llvm/docs/RISCVUsage.rst +++ b/llvm/docs/RISCVUsage.rst @@ -195,6 +195,9 @@ ``XTHeadMemPair`` LLVM implements `the THeadMemPair (two-GPR memory operations) vendor-defined instructions specified in `_ by T-HEAD of Alibaba. Instructions are prefixed with `th.` as described in the specification. +``XTHeadSync`` + LLVM implements `the THeadSync (multi-core synchronization instructions) vendor-defined instructions specified in `_ by T-HEAD of Alibaba. Instructions are prefixed with `th.` as described in the specification. + ``XTHeadVdot`` LLVM implements `version 1.0.0 of the THeadV-family custom instructions specification `_ by T-HEAD of Alibaba. All instructions are prefixed with `th.` as described in the specification, and the riscv-toolchain-convention document linked above. diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -116,6 +116,7 @@ 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. +* Adds support for the vendor-defined XTHeadSync (multi-core synchronization instructions) 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 @@ -119,6 +119,7 @@ {"xtheadcmo", RISCVExtensionVersion{1, 0}}, {"xtheadmac", RISCVExtensionVersion{1, 0}}, {"xtheadmempair", RISCVExtensionVersion{1, 0}}, + {"xtheadsync", RISCVExtensionVersion{1, 0}}, {"xtheadvdot", RISCVExtensionVersion{1, 0}}, {"xventanacondops", 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 @@ -541,6 +541,13 @@ if (Result != MCDisassembler::Fail) return Result; } + if (STI.hasFeature(RISCV::FeatureVendorXTHeadSync)) { + LLVM_DEBUG(dbgs() << "Trying XTHeadSync custom opcode table:\n"); + Result = decodeInstruction(DecoderTableTHeadSync32, MI, Insn, Address, + this, STI); + if (Result != MCDisassembler::Fail) + return Result; + } if (STI.hasFeature(RISCV::FeatureVendorXTHeadVdot)) { LLVM_DEBUG(dbgs() << "Trying XTHeadVdot custom opcode table:\n"); Result = 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 @@ -526,6 +526,13 @@ AssemblerPredicate<(all_of FeatureVendorXTHeadMemPair), "'xtheadmempair' (T-Head two-GPR Memory Operations)">; +def FeatureVendorXTHeadSync + : SubtargetFeature<"xtheadsync", "HasVendorXTHeadSync", "true", + "'xtheadsync' (T-Head multicore synchronization instructions)">; +def HasVendorXTHeadSync : Predicate<"Subtarget->hasVendorXTHeadSync()">, + AssemblerPredicate<(all_of FeatureVendorXTHeadSync), + "'xtheadsync' (T-Head multicore synchronization instructions)">; + def FeatureVendorXTHeadVdot : SubtargetFeature<"xtheadvdot", "HasVendorXTHeadVdot", "true", "'xtheadvdot' (T-Head Vector Extensions for Dot)", 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 @@ -149,6 +149,13 @@ let rs2 = funct5; } +let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in +class THCacheInst_rr funct7, string opcodestr> + : RVInstR { + let rd = 0; +} + let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in class THCacheInst_void funct5, string opcodestr> : RVInstR<0b0000000, 0, OPC_CUSTOM_0, (outs), (ins), opcodestr, ""> { @@ -523,3 +530,11 @@ def TH_L2CACHE_IALL : THCacheInst_void<0b10110, "th.l2cache.iall">; def TH_L2CACHE_CIALL : THCacheInst_void<0b10111, "th.l2cache.ciall">; } + +let Predicates = [HasVendorXTHeadSync], DecoderNamespace = "THeadSync" in { +def TH_SFENCE_VMAS : THCacheInst_rr<0b0000010, "th.sfence.vmas">; +def TH_SYNC : THCacheInst_void<0b11000, "th.sync">; +def TH_SYNC_S : THCacheInst_void<0b11001, "th.sync.s">; +def TH_SYNC_I : THCacheInst_void<0b11010, "th.sync.i">; +def TH_SYNC_IS : THCacheInst_void<0b11011, "th.sync.is">; +} 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 @@ -44,6 +44,7 @@ ; 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=+xtheadsync %s -o - | FileCheck --check-prefix=RV32XTHEADSYNC %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zca %s -o - | FileCheck --check-prefixes=CHECK,RV32ZCA %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zcb %s -o - | FileCheck --check-prefixes=CHECK,RV32ZCB %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zcd %s -o - | FileCheck --check-prefixes=CHECK,RV32ZCD %s @@ -100,6 +101,7 @@ ; 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=+xtheadsync %s -o - | FileCheck --check-prefix=RV64XTHEADSYNC %s ; RUN: llc -mtriple=riscv64 -mattr=+xtheadvdot %s -o - | FileCheck --check-prefixes=CHECK,RV64XTHEADVDOT %s ; RUN: llc -mtriple=riscv64 -mattr=+zawrs %s -o - | FileCheck --check-prefixes=CHECK,RV64ZAWRS %s ; RUN: llc -mtriple=riscv64 -mattr=+experimental-ztso %s -o - | FileCheck --check-prefixes=CHECK,RV64ZTSO %s @@ -155,6 +157,7 @@ ; RV32XTHEADCMO: .attribute 5, "rv32i2p0_xtheadcmo1p0" ; RV32XTHEADMAC: .attribute 5, "rv32i2p0_xtheadmac1p0" ; RV32XTHEADMEMPAIR: .attribute 5, "rv32i2p0_xtheadmempair1p0" +; RV32XTHEADSYNC: .attribute 5, "rv32i2p0_xtheadsync1p0" ; RV32ZCA: .attribute 5, "rv32i2p0_zca1p0" ; RV32ZCB: .attribute 5, "rv32i2p0_zca1p0_zcb1p0" ; RV32ZCD: .attribute 5, "rv32i2p0_zcd1p0" @@ -211,6 +214,7 @@ ; RV64XTHEADCMO: .attribute 5, "rv64i2p0_xtheadcmo1p0" ; RV64XTHEADMAC: .attribute 5, "rv64i2p0_xtheadmac1p0" ; RV64XTHEADMEMPAIR: .attribute 5, "rv64i2p0_xtheadmempair1p0" +; RV64XTHEADSYNC: .attribute 5, "rv64i2p0_xtheadsync1p0" ; RV64XTHEADVDOT: .attribute 5, "rv64i2p0_f2p0_d2p0_v1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0_xtheadvdot1p0" ; RV64ZTSO: .attribute 5, "rv64i2p0_ztso0p1" ; RV64ZCA: .attribute 5, "rv64i2p0_zca1p0" diff --git a/llvm/test/MC/RISCV/xtheadsync-invalid.s b/llvm/test/MC/RISCV/xtheadsync-invalid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/xtheadsync-invalid.s @@ -0,0 +1,8 @@ +# RUN: not llvm-mc -triple riscv32 -mattr=+xtheadsync < %s 2>&1 | FileCheck %s +# RUN: not llvm-mc -triple riscv64 -mattr=+xtheadsync < %s 2>&1 | FileCheck %s + +th.sfence.vmas t0 # CHECK: :[[@LINE]]:1: error: too few operands for instruction +th.sync t0 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction +th.sync.s t0 # CHECK: :[[@LINE]]:11: error: invalid operand for instruction +th.sync.i t0 # CHECK: :[[@LINE]]:11: error: invalid operand for instruction +th.sync.is t0 # CHECK: :[[@LINE]]:12: error: invalid operand for instruction diff --git a/llvm/test/MC/RISCV/xtheadsync-valid.s b/llvm/test/MC/RISCV/xtheadsync-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/xtheadsync-valid.s @@ -0,0 +1,30 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+xtheadsync -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+xtheadsync < %s \ +# RUN: | llvm-objdump --mattr=+xtheadsync -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+xtheadsync -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+xtheadsync < %s \ +# RUN: | llvm-objdump --mattr=+xtheadsync -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s + +# CHECK-ASM-AND-OBJ: th.sfence.vmas a0, a1 +# CHECK-ASM: encoding: [0x0b,0x00,0xb5,0x04] +th.sfence.vmas a0, a1 + +# CHECK-ASM-AND-OBJ: th.sync +# CHECK-ASM: encoding: [0x0b,0x00,0x80,0x01] +th.sync + +# CHECK-ASM-AND-OBJ: th.sync.i +# CHECK-ASM: encoding: [0x0b,0x00,0xa0,0x01] +th.sync.i + +# CHECK-ASM-AND-OBJ: th.sync.is +# CHECK-ASM: encoding: [0x0b,0x00,0xb0,0x01] +th.sync.is + +# CHECK-ASM-AND-OBJ: th.sync.s +# CHECK-ASM: encoding: [0x0b,0x00,0x90,0x01] +th.sync.s