Skip to content

Commit 656188d

Browse files
committed
[RISCV] Add vendor-defined XTHeadBs (single-bit) extension
The vendor-defined XTHeadBs (predating the standard Zbs extension) extension adds a bit-test instruction (th.tst) with similar semantics as bexti from Zbs. 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 XTHeadBs is available from: 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=8254c3d2c94ae5458095ea6c25446ba89134b9da Depends on D143394 Differential Revision: https://reviews.llvm.org/D143036
1 parent 3304d51 commit 656188d

15 files changed

+439
-8
lines changed

llvm/docs/RISCVUsage.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,9 @@ The current vendor extensions supported are:
172172
``XTHeadBa``
173173
LLVM implements `the THeadBa (address-generation) vendor-defined instructions specified in <https://github.com/T-head-Semi/thead-extension-spec/releases/download/2.2.2/xthead-2023-01-30-2.2.2.pdf>`_ by T-HEAD of Alibaba. Instructions are prefixed with `th.` as described in the specification.
174174

175+
``XTHeadBs``
176+
LLVM implements `the THeadBs (single-bit operations) vendor-defined instructions specified in <https://github.com/T-head-Semi/thead-extension-spec/releases/download/2.2.2/xthead-2023-01-30-2.2.2.pdf>`_ by T-HEAD of Alibaba. Instructions are prefixed with `th.` as described in the specification.
177+
175178
``XTHeadVdot``
176179
LLVM implements `version 1.0.0 of the THeadV-family custom instructions specification <https://github.com/T-head-Semi/thead-extension-spec/releases/download/2.2.0/xthead-2022-12-04-2.2.0.pdf>`_ by T-HEAD of Alibaba. All instructions are prefixed with `th.` as described in the specification, and the riscv-toolchain-convention document linked above.
177180

llvm/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ Changes to the RISC-V Backend
109109
* vsetvli intrinsics no longer have side effects. They may now be combined,
110110
moved, deleted, etc. by optimizations.
111111
* Adds support for the vendor-defined XTHeadBa (address-generation) extension.
112+
* Adds support for the vendor-defined XTHeadBs (single-bit) extension.
112113

113114
Changes to the WebAssembly Backend
114115
----------------------------------

llvm/lib/Support/RISCVISAInfo.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ static const RISCVSupportedExtension SupportedExtensions[] = {
110110

111111
// vendor-defined ('X') extensions
112112
{"xtheadba", RISCVExtensionVersion{1, 0}},
113+
{"xtheadbs", RISCVExtensionVersion{1, 0}},
113114
{"xtheadvdot", RISCVExtensionVersion{1, 0}},
114115
{"xventanacondops", RISCVExtensionVersion{1, 0}},
115116
};

llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,13 @@ DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
478478
if (Result != MCDisassembler::Fail)
479479
return Result;
480480
}
481+
if (STI.getFeatureBits()[RISCV::FeatureVendorXTHeadBs]) {
482+
LLVM_DEBUG(dbgs() << "Trying XTHeadBs custom opcode table:\n");
483+
Result = decodeInstruction(DecoderTableTHeadBs32, MI, Insn, Address, this,
484+
STI);
485+
if (Result != MCDisassembler::Fail)
486+
return Result;
487+
}
481488
if (STI.getFeatureBits()[RISCV::FeatureVendorXTHeadVdot]) {
482489
LLVM_DEBUG(dbgs() << "Trying XTHeadVdot custom opcode table:\n");
483490
Result =

llvm/lib/Target/RISCV/RISCVFeatures.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,13 @@ def HasVendorXTHeadBa : Predicate<"Subtarget->hasVendorXTHeadBa()">,
470470
AssemblerPredicate<(all_of FeatureVendorXTHeadBa),
471471
"'xtheadba' (T-Head address calculation instructions)">;
472472

473+
def FeatureVendorXTHeadBs
474+
: SubtargetFeature<"xtheadbs", "HasVendorXTHeadBs", "true",
475+
"'xtheadbs' (T-Head single-bit instructions)">;
476+
def HasVendorXTHeadBs : Predicate<"Subtarget->hasVendorXTHeadBs()">,
477+
AssemblerPredicate<(all_of FeatureVendorXTHeadBs),
478+
"'xtheadbs' (T-Head single-bit instructions)">;
479+
473480
def FeatureVendorXTHeadVdot
474481
: SubtargetFeature<"xtheadvdot", "HasVendorXTHeadVdot", "true",
475482
"'xtheadvdot' (T-Head Vector Extensions for Dot)",

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -834,14 +834,17 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
834834
if (!N0.hasOneUse())
835835
break;
836836

837-
// If C2 is (1 << ShAmt) use bexti if possible.
838-
if (Subtarget->hasStdExtZbs() && ShAmt + 1 == TrailingOnes) {
839-
SDNode *BEXTI =
840-
CurDAG->getMachineNode(RISCV::BEXTI, DL, VT, N0->getOperand(0),
841-
CurDAG->getTargetConstant(ShAmt, DL, VT));
837+
// If C2 is (1 << ShAmt) use bexti or th.tst if possible.
838+
bool HasBitTest =
839+
Subtarget->hasStdExtZbs() || Subtarget->hasVendorXTHeadBs();
840+
if (HasBitTest && ShAmt + 1 == TrailingOnes) {
841+
SDNode *BEXTI = CurDAG->getMachineNode(
842+
Subtarget->hasStdExtZbs() ? RISCV::BEXTI : RISCV::TH_TST, DL, VT,
843+
N0->getOperand(0), CurDAG->getTargetConstant(ShAmt, DL, VT));
842844
ReplaceNode(Node, BEXTI);
843845
return;
844846
}
847+
845848
unsigned LShAmt = Subtarget->getXLen() - TrailingOnes;
846849
SDNode *SLLI =
847850
CurDAG->getMachineNode(RISCV::SLLI, DL, VT, N0->getOperand(0),
@@ -963,8 +966,9 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
963966
bool Skip = Subtarget->hasStdExtZba() && Leading == 32 &&
964967
X.getOpcode() == ISD::SIGN_EXTEND_INREG &&
965968
cast<VTSDNode>(X.getOperand(1))->getVT() == MVT::i32;
966-
// Also Skip if we can use bexti.
969+
// Also Skip if we can use bexti or th.tst.
967970
Skip |= Subtarget->hasStdExtZbs() && Leading == XLen - 1;
971+
Skip |= Subtarget->hasVendorXTHeadBs() && Leading == XLen - 1;
968972
if (OneUseOrZExtW && !Skip) {
969973
SDNode *SLLI = CurDAG->getMachineNode(
970974
RISCV::SLLI, DL, VT, X,

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,7 +1223,7 @@ bool RISCVTargetLowering::isMaskAndCmp0FoldingBeneficial(
12231223
// on the basis that it's possible the sinking+duplication of the AND in
12241224
// CodeGenPrepare triggered by this hook wouldn't decrease the instruction
12251225
// count and would increase code size (e.g. ANDI+BNEZ => BEXTI+BNEZ).
1226-
if (!Subtarget.hasStdExtZbs())
1226+
if (!Subtarget.hasStdExtZbs() && !Subtarget.hasVendorXTHeadBs())
12271227
return false;
12281228
ConstantInt *Mask = dyn_cast<ConstantInt>(AndI.getOperand(1));
12291229
if (!Mask)
@@ -1246,8 +1246,11 @@ bool RISCVTargetLowering::hasBitTest(SDValue X, SDValue Y) const {
12461246
// Zbs provides BEXT[_I], which can be used with SEQZ/SNEZ as a bit test.
12471247
if (Subtarget.hasStdExtZbs())
12481248
return X.getValueType().isScalarInteger();
1249-
// We can use ANDI+SEQZ/SNEZ as a bit test. Y contains the bit position.
12501249
auto *C = dyn_cast<ConstantSDNode>(Y);
1250+
// XTheadBs provides th.tst (similar to bexti), if Y is a constant
1251+
if (Subtarget.hasVendorXTHeadBs())
1252+
return C != nullptr;
1253+
// We can use ANDI+SEQZ/SNEZ as a bit test. Y contains the bit position.
12511254
return C && C->getAPIntValue().ule(10);
12521255
}
12531256

llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ def TH_ADDSL : THShiftALU_rri<0b001, "th.addsl">,
7575
Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;
7676
} // Predicates = [HasVendorXTHeadBa]
7777

78+
let Predicates = [HasVendorXTHeadBs], DecoderNamespace = "THeadBs" in {
79+
let IsSignExtendingOpW = 1 in
80+
def TH_TST : RVBShift_ri<0b10001, 0b001, OPC_CUSTOM_0, "th.tst">,
81+
Sched<[WriteSingleBitImm, ReadSingleBitImm]>;
82+
} // Predicates = [HasVendorXTHeadBs]
83+
7884
let Predicates = [HasVendorXTHeadVdot],
7985
Constraints = "@earlyclobber $vd",
8086
RVVConstraint = WidenV in {
@@ -163,6 +169,14 @@ def : Pat<(add sh3add_op:$rs1, non_imm12:$rs2),
163169
(TH_ADDSL GPR:$rs2, sh3add_op:$rs1, 3)>;
164170
} // Predicates = [HasVendorXTHeadBa]
165171

172+
let Predicates = [HasVendorXTHeadBs] in {
173+
def : Pat<(and (srl GPR:$rs1, uimmlog2xlen:$shamt), 1),
174+
(TH_TST GPR:$rs1, uimmlog2xlen:$shamt)>;
175+
def : Pat<(seteq (and GPR:$rs1, SingleBitSetMask:$mask), 0),
176+
(TH_TST (XORI GPR:$rs1, -1), SingleBitSetMask:$mask)>;
177+
} // Predicates = [HasVendorXTHeadBs]
178+
179+
166180
defm PseudoTHVdotVMAQA : VPseudoVMAQA_VV_VX;
167181
defm PseudoTHVdotVMAQAU : VPseudoVMAQA_VV_VX;
168182
defm PseudoTHVdotVMAQASU : VPseudoVMAQA_VV_VX;

llvm/test/CodeGen/RISCV/attributes.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
; RUN: llc -mtriple=riscv64 -mattr=+svinval %s -o - | FileCheck --check-prefix=RV64SVINVAL %s
8888
; RUN: llc -mtriple=riscv64 -mattr=+xventanacondops %s -o - | FileCheck --check-prefix=RV64XVENTANACONDOPS %s
8989
; RUN: llc -mtriple=riscv64 -mattr=+xtheadba %s -o - | FileCheck --check-prefix=RV64XTHEADBA %s
90+
; RUN: llc -mtriple=riscv64 -mattr=+xtheadbs %s -o - | FileCheck --check-prefix=RV64XTHEADBS %s
9091
; RUN: llc -mtriple=riscv64 -mattr=+xtheadvdot %s -o - | FileCheck --check-prefix=RV64XTHEADVDOT %s
9192
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zawrs %s -o - | FileCheck --check-prefix=RV64ZAWRS %s
9293
; RUN: llc -mtriple=riscv64 -mattr=+experimental-ztso %s -o - | FileCheck --check-prefix=RV64ZTSO %s
@@ -182,6 +183,7 @@
182183
; RV64SVINVAL: .attribute 5, "rv64i2p0_svinval1p0"
183184
; RV64XVENTANACONDOPS: .attribute 5, "rv64i2p0_xventanacondops1p0"
184185
; RV64XTHEADBA: .attribute 5, "rv64i2p0_xtheadba1p0"
186+
; RV64XTHEADBS: .attribute 5, "rv64i2p0_xtheadbs1p0"
185187
; RV64XTHEADVDOT: .attribute 5, "rv64i2p0_f2p0_d2p0_v1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0_xtheadvdot1p0"
186188
; RV64ZTSO: .attribute 5, "rv64i2p0_ztso0p1"
187189
; RV64ZCA: .attribute 5, "rv64i2p0_zca1p0"

0 commit comments

Comments
 (0)