From 16a6cf6a99c247375f2f95a922d59da81de81a2c Mon Sep 17 00:00:00 2001 From: Manolis Tsamis Date: Wed, 22 Feb 2023 10:58:50 +0100 Subject: [PATCH] [RISCV] Add vendor-defined XTheadSync (Multi-core synchronization) extension The vendor-defined XTheadSync (no comparable standard extension exists at the time of writing) extension adds multi-core synchronization instructions. It is supported by the C9xx cores (e.g., found in the wild in the Allwinner D1) by Alibaba T-Head. The current (as of this commit) public documentation for this extension is available at: https://github.com/T-head-Semi/thead-extension-spec/releases/download/2.2.2/xthead-2023-01-30-2.2.2.pdf Support for these instructions has already landed in GNU Binutils: https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=547c18d9bb95571261dbd17f4767194037eb82bd Depends on D144496 Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D144501 --- llvm/docs/RISCVUsage.rst | 3 ++ llvm/docs/ReleaseNotes.rst | 1 + llvm/lib/Support/RISCVISAInfo.cpp | 1 + .../RISCV/Disassembler/RISCVDisassembler.cpp | 7 +++++ llvm/lib/Target/RISCV/RISCVFeatures.td | 7 +++++ llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td | 15 ++++++++++ llvm/test/CodeGen/RISCV/attributes.ll | 4 +++ llvm/test/MC/RISCV/xtheadsync-invalid.s | 8 +++++ llvm/test/MC/RISCV/xtheadsync-valid.s | 30 +++++++++++++++++++ 9 files changed, 76 insertions(+) create mode 100644 llvm/test/MC/RISCV/xtheadsync-invalid.s create mode 100644 llvm/test/MC/RISCV/xtheadsync-valid.s diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst index 4e17ecc042094..57512112b554a 100644 --- a/llvm/docs/RISCVUsage.rst +++ b/llvm/docs/RISCVUsage.rst @@ -195,6 +195,9 @@ The current vendor extensions supported are: ``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 index 981f57e6a8185..677342407586a 100644 --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -116,6 +116,7 @@ Changes to the RISC-V Backend 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 index bffd3220c1789..e051585d7a3e0 100644 --- a/llvm/lib/Support/RISCVISAInfo.cpp +++ b/llvm/lib/Support/RISCVISAInfo.cpp @@ -119,6 +119,7 @@ static const RISCVSupportedExtension SupportedExtensions[] = { {"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 index d7c7fcca05735..e278edc062b2a 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -541,6 +541,13 @@ DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 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 index d8c52b3fbd027..5107f0d7ef7a9 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -526,6 +526,13 @@ def HasVendorXTHeadMemPair : Predicate<"Subtarget->hasVendorXTHeadMemPair()">, 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 index c191ef9695abe..3ff9978ab0c0d 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td @@ -149,6 +149,13 @@ class THCacheInst_r funct5, string opcodestr> 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_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">; } + +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 index bd1467e2dd5f9..352b73ff15cd0 100644 --- 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 index 0000000000000..cb54da054f4e9 --- /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 index 0000000000000..da2ee8a2bf0bc --- /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