Skip to content

Commit

Permalink
[RISCV] Add vendor-defined XTheadCondMov (conditional move) extension
Browse files Browse the repository at this point in the history
The vendor-defined XTheadCondMov (somewhat related to the upcoming
Zicond and XVentanaCondOps) extension add conditional move
instructions with $rd being an input and an ouput 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=73442230966a22b3238b2074691a71d7b4ed914a

Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D144681
  • Loading branch information
ptomsich committed Feb 24, 2023
1 parent bfeef8b commit f68f04d
Show file tree
Hide file tree
Showing 13 changed files with 1,197 additions and 688 deletions.
3 changes: 3 additions & 0 deletions llvm/docs/RISCVUsage.rst
Expand Up @@ -186,6 +186,9 @@ The current vendor extensions supported are:
``XTHeadBs``
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.

``XTHeadCondMov``
LLVM implements `the THeadCondMov (conditional move) 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.

``XTHeadCmo``
LLVM implements `the THeadCmo (cache management 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.

Expand Down
1 change: 1 addition & 0 deletions llvm/docs/ReleaseNotes.rst
Expand Up @@ -114,6 +114,7 @@ Changes to the RISC-V Backend
* Adds support for the vendor-defined XTHeadBa (address-generation) extension.
* Adds support for the vendor-defined XTHeadBb (basic bit-manipulation) extension.
* Adds support for the vendor-defined XTHeadBs (single-bit) extension.
* Adds support for the vendor-defined XTHeadCondMov (conditional move) extension.
* Adds support for the vendor-defined XTHeadMac (multiply-accumulate instructions) extension.
* Added support for the vendor-defined XTHeadMemPair (two-GPR memory operations)
extension disassembler/assembler.
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Support/RISCVISAInfo.cpp
Expand Up @@ -117,6 +117,7 @@ static const RISCVSupportedExtension SupportedExtensions[] = {
{"xtheadbb", RISCVExtensionVersion{1, 0}},
{"xtheadbs", RISCVExtensionVersion{1, 0}},
{"xtheadcmo", RISCVExtensionVersion{1, 0}},
{"xtheadcondmov", RISCVExtensionVersion{1, 0}},
{"xtheadfmemidx", RISCVExtensionVersion{1, 0}},
{"xtheadmac", RISCVExtensionVersion{1, 0}},
{"xtheadmemidx", RISCVExtensionVersion{1, 0}},
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
Expand Up @@ -520,6 +520,13 @@ DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
if (Result != MCDisassembler::Fail)
return Result;
}
if (STI.hasFeature(RISCV::FeatureVendorXTHeadCondMov)) {
LLVM_DEBUG(dbgs() << "Trying XTHeadCondMov custom opcode table:\n");
Result = decodeInstruction(DecoderTableTHeadCondMov32, MI, Insn, Address,
this, STI);
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,
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Target/RISCV/RISCVFeatures.td
Expand Up @@ -505,6 +505,13 @@ def HasVendorXTHeadBs : Predicate<"Subtarget->hasVendorXTHeadBs()">,
AssemblerPredicate<(all_of FeatureVendorXTHeadBs),
"'xtheadbs' (T-Head single-bit instructions)">;

def FeatureVendorXTHeadCondMov
: SubtargetFeature<"xtheadcondmov", "HasVendorXTHeadCondMov", "true",
"'xtheadcondmov' (T-Head conditional move instructions)">;
def HasVendorXTHeadCondMov : Predicate<"Subtarget->hasVendorXTHeadCondMov()">,
AssemblerPredicate<(all_of FeatureVendorXTHeadCondMov),
"'xtheadcondmov' (T-Head conditional move instructions)">;

def FeatureVendorXTHeadCmo
: SubtargetFeature<"xtheadcmo", "HasVendorXTHeadCmo", "true",
"'xtheadcmo' (T-Head cache management instructions)">;
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Expand Up @@ -323,7 +323,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
if (Subtarget.is64Bit())
setOperationAction(ISD::ABS, MVT::i32, Custom);

if (!Subtarget.hasVendorXVentanaCondOps())
if (!Subtarget.hasVendorXVentanaCondOps() &&
!Subtarget.hasVendorXTHeadCondMov())
setOperationAction(ISD::SELECT, XLenVT, Custom);

static const unsigned FPLegalNodeTypes[] = {
Expand Down
17 changes: 17 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
Expand Up @@ -2102,6 +2102,15 @@ bool RISCVInstrInfo::findCommutedOpIndices(const MachineInstr &MI,
return false;

switch (MI.getOpcode()) {
case RISCV::TH_MVEQZ:
case RISCV::TH_MVNEZ:
// We can't commute operands if operand 2 (i.e., rs1 in
// mveqz/mvnez rd,rs1,rs2) is the zero-register (as it is
// not valid as the in/out-operand 1).
if (MI.getOperand(2).getReg() == RISCV::X0)
return false;
// Operands 1 and 2 are commutable, if we switch the opcode.
return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 2);
case RISCV::TH_MULA:
case RISCV::TH_MULAW:
case RISCV::TH_MULAH:
Expand Down Expand Up @@ -2258,6 +2267,14 @@ MachineInstr *RISCVInstrInfo::commuteInstructionImpl(MachineInstr &MI,
};

switch (MI.getOpcode()) {
case RISCV::TH_MVEQZ:
case RISCV::TH_MVNEZ: {
auto &WorkingMI = cloneIfNew(MI);
WorkingMI.setDesc(get(MI.getOpcode() == RISCV::TH_MVEQZ ? RISCV::TH_MVNEZ
: RISCV::TH_MVEQZ));
return TargetInstrInfo::commuteInstructionImpl(WorkingMI, false, OpIdx1,
OpIdx2);
}
case RISCV::PseudoCCMOVGPR: {
// CCMOV can be commuted by inverting the condition.
auto CC = static_cast<RISCVCC::CondCode>(MI.getOperand(3).getImm());
Expand Down
28 changes: 28 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td
Expand Up @@ -106,6 +106,14 @@ class THShiftW_ri<bits<7> funct7, bits<3> funct3, string opcodestr>
(ins GPR:$rs1, uimm5:$shamt),
opcodestr, "$rd, $rs1, $shamt">;

let Predicates = [HasVendorXTHeadCondMov], DecoderNamespace = "THeadCondMov",
hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCommutable = 1 in
class THCondMov_rr<bits<7> funct7, string opcodestr>
: RVInstR<funct7, 0b001, OPC_CUSTOM_0, (outs GPR:$rd_wb),
(ins GPR:$rd, GPR:$rs1, GPR:$rs2),
opcodestr, "$rd, $rs1, $rs2"> {
let Constraints = "$rd_wb = $rd";
}

let Predicates = [HasVendorXTHeadMac], DecoderNamespace = "THeadMac",
hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCommutable = 1 in
Expand Down Expand Up @@ -250,6 +258,11 @@ def TH_TST : RVBShift_ri<0b10001, 0b001, OPC_CUSTOM_0, "th.tst">,
Sched<[WriteSingleBitImm, ReadSingleBitImm]>;
} // Predicates = [HasVendorXTHeadBs]

let Predicates = [HasVendorXTHeadCondMov] in {
def TH_MVEQZ : THCondMov_rr<0b0100000, "th.mveqz">;
def TH_MVNEZ : THCondMov_rr<0b0100001, "th.mvnez">;
} // Predicates = [HasVendorXTHeadCondMov]

let Predicates = [HasVendorXTHeadMac] in {
def TH_MULA : THMulAccumulate_rr<0b0010000, "th.mula">;
def TH_MULS : THMulAccumulate_rr<0b0010001, "th.muls">;
Expand Down Expand Up @@ -625,6 +638,21 @@ def : Pat<(seteq (and GPR:$rs1, SingleBitSetMask:$mask), 0),
(TH_TST (XORI GPR:$rs1, -1), SingleBitSetMask:$mask)>;
} // Predicates = [HasVendorXTHeadBs]

let Predicates = [HasVendorXTHeadCondMov] in {
def : Pat<(select invcondop:$cond, GPR:$a, GPR:$b),
(TH_MVNEZ $a, $b, $cond)>;
def : Pat<(select condop:$cond, GPR:$a, GPR:$b),
(TH_MVEQZ $a, $b, $cond)>;
def : Pat<(select invcondop:$cond, GPR:$a, (XLenVT 0)),
(TH_MVNEZ $a, X0, $cond)>;
def : Pat<(select condop:$cond, GPR:$a, (XLenVT 0)),
(TH_MVEQZ $a, X0, $cond)>;
def : Pat<(select invcondop:$cond, (XLenVT 0), GPR:$b),
(TH_MVEQZ $b, X0, $cond)>;
def : Pat<(select condop:$cond, (XLenVT 0), GPR:$b),
(TH_MVNEZ $b, X0, $cond)>;
} // Predicates = [HasVendorXTHeadCondMov]

let Predicates = [HasVendorXTHeadMac] in {
def : Pat<(add GPR:$rd, (mul GPR:$rs1, GPR:$rs2)), (TH_MULA GPR:$rd, GPR:$rs1, GPR:$rs2)>;
def : Pat<(sub GPR:$rd, (mul GPR:$rs1, GPR:$rs2)), (TH_MULS GPR:$rd, GPR:$rs1, GPR:$rs2)>;
Expand Down
4 changes: 4 additions & 0 deletions llvm/test/CodeGen/RISCV/attributes.ll
Expand Up @@ -42,6 +42,7 @@
; 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=+xtheadcondmov %s -o - | FileCheck --check-prefix=RV32XTHEADCONDMOV %s
; RUN: llc -mtriple=riscv32 -mattr=+xtheadfmemidx %s -o - | FileCheck --check-prefix=RV32XTHEADFMEMIDX %s
; RUN: llc -mtriple=riscv32 -mattr=+xtheadmac %s -o - | FileCheck --check-prefixes=CHECK,RV32XTHEADMAC %s
; RUN: llc -mtriple=riscv32 -mattr=+xtheadmemidx %s -o - | FileCheck --check-prefix=RV32XTHEADMEMIDX %s
Expand Down Expand Up @@ -101,6 +102,7 @@
; 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=+xtheadcondmov %s -o - | FileCheck --check-prefix=RV64XTHEADCONDMOV %s
; RUN: llc -mtriple=riscv64 -mattr=+xtheadfmemidx %s -o - | FileCheck --check-prefix=RV64XTHEADFMEMIDX %s
; RUN: llc -mtriple=riscv64 -mattr=+xtheadmac %s -o - | FileCheck --check-prefixes=CHECK,RV64XTHEADMAC %s
; RUN: llc -mtriple=riscv64 -mattr=+xtheadmemidx %s -o - | FileCheck --check-prefix=RV64XTHEADMEMIDX %s
Expand Down Expand Up @@ -159,6 +161,7 @@
; RV32SVPBMT: .attribute 5, "rv32i2p0_svpbmt1p0"
; RV32SVINVAL: .attribute 5, "rv32i2p0_svinval1p0"
; RV32XTHEADCMO: .attribute 5, "rv32i2p0_xtheadcmo1p0"
; RV32XTHEADCONDMOV: .attribute 5, "rv32i2p0_xtheadcondmov1p0"
; RV32XTHEADFMEMIDX: .attribute 5, "rv32i2p0_f2p0_xtheadfmemidx1p0"
; RV32XTHEADMAC: .attribute 5, "rv32i2p0_xtheadmac1p0"
; RV32XTHEADMEMIDX: .attribute 5, "rv32i2p0_xtheadmemidx1p0"
Expand Down Expand Up @@ -218,6 +221,7 @@
; RV64XTHEADBB: .attribute 5, "rv64i2p0_xtheadbb1p0"
; RV64XTHEADBS: .attribute 5, "rv64i2p0_xtheadbs1p0"
; RV64XTHEADCMO: .attribute 5, "rv64i2p0_xtheadcmo1p0"
; RV64XTHEADCONDMOV: .attribute 5, "rv64i2p0_xtheadcondmov1p0"
; RV64XTHEADFMEMIDX: .attribute 5, "rv64i2p0_f2p0_xtheadfmemidx1p0"
; RV64XTHEADMAC: .attribute 5, "rv64i2p0_xtheadmac1p0"
; RV64XTHEADMEMIDX: .attribute 5, "rv64i2p0_xtheadmemidx1p0"
Expand Down

0 comments on commit f68f04d

Please sign in to comment.