CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
254 lines
8.7 KiB
TableGen
254 lines
8.7 KiB
TableGen
//===-- RISCVInstrInfoSFB.td - Pseudos for SFB -------------*- tablegen -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file describes the pseudos for SFB (Short Forward Branch).
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Represents the Opcode for a branch instruction, used by SFB pseudos
|
|
def bcc_opcode : RISCVOp<i32> {
|
|
let OperandType = "OPERAND_BCC_OPCODE";
|
|
}
|
|
|
|
def sfb_rhs : RegisterOperand<GPR> {
|
|
let OperandNamespace = "RISCVOp";
|
|
let OperandType = "OPERAND_SFB_RHS";
|
|
}
|
|
|
|
// cond -> bcc_opcode for reg, reg branches
|
|
def CCtoRISCVBCC : SDNodeXForm<cond, [{
|
|
ISD::CondCode CC = N->get();
|
|
RISCVCC::CondCode RvCC = getRISCVCCForIntCC(CC);
|
|
RvCC = RISCVCC::getInverseBranchCondition(RvCC);
|
|
unsigned BccOpcode = RISCVCC::getBrCond(RvCC);
|
|
return CurDAG->getTargetConstant(BccOpcode, SDLoc(N), MVT::i32);
|
|
}]>;
|
|
|
|
// cond -> bcc_opcode (QC_E_BccI)
|
|
def CCtoQC_E_BccI : SDNodeXForm<cond, [{
|
|
ISD::CondCode CC = N->get();
|
|
RISCVCC::CondCode RvCC = getRISCVCCForIntCC(CC);
|
|
RvCC = RISCVCC::getInverseBranchCondition(RvCC);
|
|
unsigned SelectOpc;
|
|
switch (RvCC) {
|
|
case RISCVCC::COND_LTU:
|
|
case RISCVCC::COND_GEU:
|
|
SelectOpc = RISCV::Select_GPRNoX0_Using_CC_UImm16NonZero_QC;
|
|
break;
|
|
default:
|
|
// EQ/NE/LT/GE treated as signed condition codes
|
|
SelectOpc = RISCV::Select_GPRNoX0_Using_CC_SImm16NonZero_QC;
|
|
break;
|
|
}
|
|
unsigned BccOpcode = RISCVCC::getBrCond(RvCC, SelectOpc);
|
|
return CurDAG->getTargetConstant(BccOpcode, SDLoc(N), MVT::i32);
|
|
}]>;
|
|
|
|
// cond -> bcc_opcode (QC_BeqI)
|
|
def CCtoQC_BccI : SDNodeXForm<cond, [{
|
|
ISD::CondCode CC = N->get();
|
|
RISCVCC::CondCode RvCC = getRISCVCCForIntCC(CC);
|
|
RvCC = RISCVCC::getInverseBranchCondition(RvCC);
|
|
unsigned SelectOpc;
|
|
switch (RvCC) {
|
|
case RISCVCC::COND_LTU:
|
|
case RISCVCC::COND_GEU:
|
|
SelectOpc = RISCV::Select_GPRNoX0_Using_CC_UImm5NonZero_QC;
|
|
break;
|
|
default:
|
|
// EQ/NE/LT/GE treated as signed condition codes
|
|
SelectOpc = RISCV::Select_GPRNoX0_Using_CC_SImm5NonZero_QC;
|
|
break;
|
|
}
|
|
unsigned BccOpcode = RISCVCC::getBrCond(RvCC, SelectOpc);
|
|
return CurDAG->getTargetConstant(BccOpcode, SDLoc(N), MVT::i32);
|
|
}]>;
|
|
|
|
// For each of the short forward branch pseudos, corresponding code for
|
|
// getting correct size of the pseduo is needed in getInstSizeInBytes.
|
|
let Predicates = [HasShortForwardBranchIALU], isSelect = 1,
|
|
Constraints = "$dst = $falsev", isCommutable = 1 in {
|
|
// This instruction moves $truev to $dst when the condition is true. It will
|
|
// be expanded to control flow in RISCVExpandPseudoInsts.
|
|
def PseudoCCMOVGPR : Pseudo<(outs GPR:$dst),
|
|
(ins GPR:$falsev, GPR:$truev, bcc_opcode:$bcc,
|
|
GPR:$lhs, sfb_rhs:$rhs),
|
|
[]>,
|
|
Sched<[WriteSFB, ReadSFBALU, ReadSFBALU,
|
|
ReadSFBJmp, ReadSFBJmp]>;
|
|
}
|
|
|
|
let Predicates = [HasShortForwardBranchIALU] in
|
|
def : Pat<(riscv_selectcc (XLenVT GPR:$lhs), GPR:$rhs, cond:$cc, (XLenVT GPR:$truev), GPR:$falsev),
|
|
(PseudoCCMOVGPR GPR:$falsev, GPR:$truev, (CCtoRISCVBCC $cc), GPR:$lhs, GPR:$rhs)>;
|
|
|
|
// This should always expand to a branch+c.mv so the size is 6 or 4 if the
|
|
// branch is compressible.
|
|
let Predicates = [HasConditionalMoveFusion, NoShortForwardBranch],
|
|
Constraints = "$dst = $falsev", isCommutable = 1 in {
|
|
// This instruction moves $truev to $dst when the condition is true. It will
|
|
// be expanded to control flow in RISCVExpandPseudoInsts.
|
|
// We use GPRNoX0 because c.mv cannot encode X0.
|
|
def PseudoCCMOVGPRNoX0 : Pseudo<(outs GPRNoX0:$dst),
|
|
(ins GPRNoX0:$falsev, GPRNoX0:$truev, bcc_opcode:$bcc,
|
|
GPR:$lhs, sfb_rhs:$rhs),
|
|
[]>,
|
|
Sched<[]>;
|
|
}
|
|
|
|
let Predicates = [HasConditionalMoveFusion, NoShortForwardBranch] in
|
|
def :Pat<(riscv_selectcc (XLenVT GPR:$lhs), GPR:$rhs, cond:$cc, (XLenVT GPRNoX0:$truev), GPRNoX0:$falsev),
|
|
(PseudoCCMOVGPRNoX0 GPRNoX0:$falsev, GPRNoX0:$truev, (CCtoRISCVBCC $cc), GPR:$lhs, GPR:$rhs )>;
|
|
|
|
class SFBALU_rr
|
|
: Pseudo<(outs GPR:$dst),
|
|
(ins GPR:$falsev, GPR:$rs1, GPR:$rs2, bcc_opcode:$bcc,
|
|
GPR:$lhs, sfb_rhs:$rhs), []>,
|
|
Sched<[WriteSFB, ReadSFBALU, ReadSFBALU,
|
|
ReadSFBALU, ReadSFBJmp, ReadSFBJmp]> {
|
|
let hasSideEffects = 0;
|
|
let mayLoad = 0;
|
|
let mayStore = 0;
|
|
let Constraints = "$dst = $falsev";
|
|
}
|
|
|
|
class SFBALU_ri
|
|
: Pseudo<(outs GPR:$dst),
|
|
(ins GPR:$falsev, GPR:$rs1, simm12_lo:$imm, bcc_opcode:$bcc,
|
|
GPR:$lhs, sfb_rhs:$rhs), []>,
|
|
Sched<[WriteSFB, ReadSFBALU, ReadSFBALU, ReadSFBJmp, ReadSFBJmp]> {
|
|
let hasSideEffects = 0;
|
|
let mayLoad = 0;
|
|
let mayStore = 0;
|
|
let Constraints = "$dst = $falsev";
|
|
}
|
|
|
|
class SFBLUI
|
|
: Pseudo<(outs GPR:$dst),
|
|
(ins GPR:$falsev, uimm20_lui:$imm, bcc_opcode:$bcc,
|
|
GPR:$lhs, sfb_rhs:$rhs), []> {
|
|
let hasSideEffects = 0;
|
|
let mayLoad = 0;
|
|
let mayStore = 0;
|
|
let Constraints = "$dst = $falsev";
|
|
}
|
|
|
|
class SFBLoad
|
|
: Pseudo<(outs GPR:$dst),
|
|
(ins GPR:$falsev, GPR:$rs1, simm12_lo:$imm, bcc_opcode:$bcc,
|
|
GPR:$lhs, sfb_rhs:$rhs), []> {
|
|
let hasSideEffects = 0;
|
|
let mayLoad = 1;
|
|
let mayStore = 0;
|
|
let Constraints = "$dst = $falsev";
|
|
}
|
|
|
|
class SFBShift_ri
|
|
: Pseudo<(outs GPR:$dst),
|
|
(ins GPR:$falsev, GPR:$rs1, uimmlog2xlen:$imm, bcc_opcode:$bcc,
|
|
GPR:$lhs, sfb_rhs:$rhs), []>,
|
|
Sched<[WriteSFB, ReadSFBALU, ReadSFBALU, ReadSFBJmp, ReadSFBJmp]> {
|
|
let hasSideEffects = 0;
|
|
let mayLoad = 0;
|
|
let mayStore = 0;
|
|
let Constraints = "$dst = $falsev";
|
|
}
|
|
|
|
class SFBShiftW_ri
|
|
: Pseudo<(outs GPR:$dst),
|
|
(ins GPR:$falsev, GPR:$rs1, uimm5:$imm, bcc_opcode:$bcc,
|
|
GPR:$lhs, sfb_rhs:$rhs), []>,
|
|
Sched<[WriteSFB, ReadSFBALU, ReadSFBALU, ReadSFBJmp, ReadSFBJmp]> {
|
|
let hasSideEffects = 0;
|
|
let mayLoad = 0;
|
|
let mayStore = 0;
|
|
let Constraints = "$dst = $falsev";
|
|
}
|
|
|
|
// Conditional binops, that updates update $dst to (op rs1, rs2) when condition
|
|
// is true. Returns $falsev otherwise. Selected by optimizeSelect.
|
|
// TODO: Can we use DefaultOperands on the regular binop to accomplish this more
|
|
// like how ARM does predication?
|
|
let Predicates = [HasShortForwardBranchIALU] in {
|
|
def PseudoCCADD : SFBALU_rr;
|
|
def PseudoCCSUB : SFBALU_rr;
|
|
def PseudoCCSLL : SFBALU_rr;
|
|
def PseudoCCSRL : SFBALU_rr;
|
|
def PseudoCCSRA : SFBALU_rr;
|
|
def PseudoCCAND : SFBALU_rr;
|
|
def PseudoCCOR : SFBALU_rr;
|
|
def PseudoCCXOR : SFBALU_rr;
|
|
|
|
def PseudoCCADDI : SFBALU_ri;
|
|
def PseudoCCANDI : SFBALU_ri;
|
|
def PseudoCCORI : SFBALU_ri;
|
|
def PseudoCCXORI : SFBALU_ri;
|
|
|
|
def PseudoCCLUI : SFBLUI;
|
|
|
|
def PseudoCCSLLI : SFBShift_ri;
|
|
def PseudoCCSRLI : SFBShift_ri;
|
|
def PseudoCCSRAI : SFBShift_ri;
|
|
|
|
// RV64I instructions
|
|
def PseudoCCADDW : SFBALU_rr;
|
|
def PseudoCCSUBW : SFBALU_rr;
|
|
def PseudoCCSLLW : SFBALU_rr;
|
|
def PseudoCCSRLW : SFBALU_rr;
|
|
def PseudoCCSRAW : SFBALU_rr;
|
|
|
|
def PseudoCCADDIW : SFBALU_ri;
|
|
|
|
def PseudoCCSLLIW : SFBShiftW_ri;
|
|
def PseudoCCSRLIW : SFBShiftW_ri;
|
|
def PseudoCCSRAIW : SFBShiftW_ri;
|
|
|
|
// Zbb/Zbkb instructions
|
|
def PseudoCCANDN : SFBALU_rr;
|
|
def PseudoCCORN : SFBALU_rr;
|
|
def PseudoCCXNOR : SFBALU_rr;
|
|
}
|
|
|
|
// imm -> bcc_opcode for reg, reg branches
|
|
def RISCVCCtoRISCVBCC : SDNodeXForm<imm, [{
|
|
auto CCImm = cast<ConstantSDNode>(N)->getZExtValue();
|
|
auto RvCC = static_cast<RISCVCC::CondCode>(CCImm);
|
|
RvCC = RISCVCC::getInverseBranchCondition(RvCC);
|
|
unsigned BccOpcode = RISCVCC::getBrCond(RvCC);
|
|
return CurDAG->getTargetConstant(BccOpcode, SDLoc(N), MVT::i32);
|
|
}]>;
|
|
|
|
let Predicates = [HasShortForwardBranchIALU] in
|
|
def : Pat<(XLenVT (abs GPR:$rs1)),
|
|
(PseudoCCSUB (XLenVT GPR:$rs1), (XLenVT X0), (XLenVT GPR:$rs1),
|
|
(RISCVCCtoRISCVBCC (i32 /* COND_LT */ 2)),(XLenVT GPR:$rs1), (XLenVT X0))>;
|
|
let Predicates = [HasShortForwardBranchIALU, IsRV64] in
|
|
def : Pat<(sext_inreg (abs 33signbits_node:$rs1), i32),
|
|
(PseudoCCSUBW (i64 GPR:$rs1), (i64 X0), (i64 GPR:$rs1), (RISCVCCtoRISCVBCC (i32 /* COND_LT */ 2)),
|
|
(i64 GPR:$rs1), (i64 X0))>;
|
|
|
|
let Predicates = [HasShortForwardBranchIMinMax] in {
|
|
def PseudoCCMAX : SFBALU_rr;
|
|
def PseudoCCMIN : SFBALU_rr;
|
|
def PseudoCCMAXU : SFBALU_rr;
|
|
def PseudoCCMINU : SFBALU_rr;
|
|
}
|
|
|
|
let Predicates = [HasShortForwardBranchIMul] in
|
|
def PseudoCCMUL : SFBALU_rr;
|
|
|
|
let Predicates = [HasShortForwardBranchILoad] in {
|
|
def PseudoCCLB : SFBLoad;
|
|
def PseudoCCLH : SFBLoad;
|
|
def PseudoCCLW : SFBLoad;
|
|
def PseudoCCLHU : SFBLoad;
|
|
def PseudoCCLBU : SFBLoad;
|
|
def PseudoCCLWU : SFBLoad;
|
|
def PseudoCCLD : SFBLoad;
|
|
}
|