15ffd83dbSDimitry Andric //===---- RISCVISelDAGToDAG.h - A dag to dag inst selector for RISCV ------===// 25ffd83dbSDimitry Andric // 35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65ffd83dbSDimitry Andric // 75ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 85ffd83dbSDimitry Andric // 95ffd83dbSDimitry Andric // This file defines an instruction selector for the RISCV target. 105ffd83dbSDimitry Andric // 115ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 125ffd83dbSDimitry Andric 135ffd83dbSDimitry Andric #ifndef LLVM_LIB_TARGET_RISCV_RISCVISELDAGTODAG_H 145ffd83dbSDimitry Andric #define LLVM_LIB_TARGET_RISCV_RISCVISELDAGTODAG_H 155ffd83dbSDimitry Andric 165ffd83dbSDimitry Andric #include "RISCV.h" 175ffd83dbSDimitry Andric #include "RISCVTargetMachine.h" 185ffd83dbSDimitry Andric #include "llvm/CodeGen/SelectionDAGISel.h" 19*bdd1243dSDimitry Andric #include "llvm/Support/KnownBits.h" 205ffd83dbSDimitry Andric 215ffd83dbSDimitry Andric // RISCV-specific code to select RISCV machine instructions for 225ffd83dbSDimitry Andric // SelectionDAG operations. 235ffd83dbSDimitry Andric namespace llvm { 245ffd83dbSDimitry Andric class RISCVDAGToDAGISel : public SelectionDAGISel { 255ffd83dbSDimitry Andric const RISCVSubtarget *Subtarget = nullptr; 265ffd83dbSDimitry Andric 275ffd83dbSDimitry Andric public: 28*bdd1243dSDimitry Andric static char ID; 29*bdd1243dSDimitry Andric 30*bdd1243dSDimitry Andric RISCVDAGToDAGISel() = delete; 31*bdd1243dSDimitry Andric 3281ad6265SDimitry Andric explicit RISCVDAGToDAGISel(RISCVTargetMachine &TargetMachine, 3381ad6265SDimitry Andric CodeGenOpt::Level OptLevel) 34*bdd1243dSDimitry Andric : SelectionDAGISel(ID, TargetMachine, OptLevel) {} 355ffd83dbSDimitry Andric 365ffd83dbSDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override { 375ffd83dbSDimitry Andric Subtarget = &MF.getSubtarget<RISCVSubtarget>(); 385ffd83dbSDimitry Andric return SelectionDAGISel::runOnMachineFunction(MF); 395ffd83dbSDimitry Andric } 405ffd83dbSDimitry Andric 41fe6060f1SDimitry Andric void PreprocessISelDAG() override; 425ffd83dbSDimitry Andric void PostprocessISelDAG() override; 435ffd83dbSDimitry Andric 445ffd83dbSDimitry Andric void Select(SDNode *Node) override; 455ffd83dbSDimitry Andric 465ffd83dbSDimitry Andric bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, 475ffd83dbSDimitry Andric std::vector<SDValue> &OutOps) override; 485ffd83dbSDimitry Andric 4981ad6265SDimitry Andric bool SelectAddrFrameIndex(SDValue Addr, SDValue &Base, SDValue &Offset); 5081ad6265SDimitry Andric bool SelectFrameAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset); 5181ad6265SDimitry Andric bool SelectAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset); 525ffd83dbSDimitry Andric 53*bdd1243dSDimitry Andric bool tryShrinkShlLogicImm(SDNode *Node); 54*bdd1243dSDimitry Andric 55fe6060f1SDimitry Andric bool selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt); 56fe6060f1SDimitry Andric bool selectShiftMaskXLen(SDValue N, SDValue &ShAmt) { 57fe6060f1SDimitry Andric return selectShiftMask(N, Subtarget->getXLen(), ShAmt); 58fe6060f1SDimitry Andric } 59fe6060f1SDimitry Andric bool selectShiftMask32(SDValue N, SDValue &ShAmt) { 60fe6060f1SDimitry Andric return selectShiftMask(N, 32, ShAmt); 61fe6060f1SDimitry Andric } 62fe6060f1SDimitry Andric 63fe6060f1SDimitry Andric bool selectSExti32(SDValue N, SDValue &Val); 64*bdd1243dSDimitry Andric bool selectZExtBits(SDValue N, unsigned Bits, SDValue &Val); 65*bdd1243dSDimitry Andric template <unsigned Bits> bool selectZExtBits(SDValue N, SDValue &Val) { 66*bdd1243dSDimitry Andric return selectZExtBits(N, Bits, Val); 67*bdd1243dSDimitry Andric } 68e8d8bef9SDimitry Andric 69753f127fSDimitry Andric bool selectSHXADDOp(SDValue N, unsigned ShAmt, SDValue &Val); 70*bdd1243dSDimitry Andric template <unsigned ShAmt> bool selectSHXADDOp(SDValue N, SDValue &Val) { 71*bdd1243dSDimitry Andric return selectSHXADDOp(N, ShAmt, Val); 72753f127fSDimitry Andric } 73753f127fSDimitry Andric 74*bdd1243dSDimitry Andric bool selectSHXADD_UWOp(SDValue N, unsigned ShAmt, SDValue &Val); 75*bdd1243dSDimitry Andric template <unsigned ShAmt> bool selectSHXADD_UWOp(SDValue N, SDValue &Val) { 76*bdd1243dSDimitry Andric return selectSHXADD_UWOp(N, ShAmt, Val); 77*bdd1243dSDimitry Andric } 78*bdd1243dSDimitry Andric 79*bdd1243dSDimitry Andric bool hasAllNBitUsers(SDNode *Node, unsigned Bits, 80*bdd1243dSDimitry Andric const unsigned Depth = 0) const; 81349cc55cSDimitry Andric bool hasAllHUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 16); } 82349cc55cSDimitry Andric bool hasAllWUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 32); } 83349cc55cSDimitry Andric 84d409305fSDimitry Andric bool selectVLOp(SDValue N, SDValue &VL); 85d409305fSDimitry Andric 86e8d8bef9SDimitry Andric bool selectVSplat(SDValue N, SDValue &SplatVal); 87e8d8bef9SDimitry Andric bool selectVSplatSimm5(SDValue N, SDValue &SplatVal); 88e8d8bef9SDimitry Andric bool selectVSplatUimm5(SDValue N, SDValue &SplatVal); 89fe6060f1SDimitry Andric bool selectVSplatSimm5Plus1(SDValue N, SDValue &SplatVal); 90fe6060f1SDimitry Andric bool selectVSplatSimm5Plus1NonZero(SDValue N, SDValue &SplatVal); 91e8d8bef9SDimitry Andric 92fe6060f1SDimitry Andric bool selectRVVSimm5(SDValue N, unsigned Width, SDValue &Imm); 93fe6060f1SDimitry Andric template <unsigned Width> bool selectRVVSimm5(SDValue N, SDValue &Imm) { 94fe6060f1SDimitry Andric return selectRVVSimm5(N, Width, Imm); 95fe6060f1SDimitry Andric } 96fe6060f1SDimitry Andric 97fe6060f1SDimitry Andric void addVectorLoadStoreOperands(SDNode *Node, unsigned SEWImm, 98fe6060f1SDimitry Andric const SDLoc &DL, unsigned CurOp, 99fe6060f1SDimitry Andric bool IsMasked, bool IsStridedOrIndexed, 100fe6060f1SDimitry Andric SmallVectorImpl<SDValue> &Operands, 101349cc55cSDimitry Andric bool IsLoad = false, MVT *IndexVT = nullptr); 102fe6060f1SDimitry Andric 103fe6060f1SDimitry Andric void selectVLSEG(SDNode *Node, bool IsMasked, bool IsStrided); 104fe6060f1SDimitry Andric void selectVLSEGFF(SDNode *Node, bool IsMasked); 105fe6060f1SDimitry Andric void selectVLXSEG(SDNode *Node, bool IsMasked, bool IsOrdered); 106fe6060f1SDimitry Andric void selectVSSEG(SDNode *Node, bool IsMasked, bool IsStrided); 107fe6060f1SDimitry Andric void selectVSXSEG(SDNode *Node, bool IsMasked, bool IsOrdered); 108979e22ffSDimitry Andric 10904eeddc0SDimitry Andric void selectVSETVLI(SDNode *Node); 11004eeddc0SDimitry Andric 111349cc55cSDimitry Andric // Return the RISC-V condition code that matches the given DAG integer 112349cc55cSDimitry Andric // condition code. The CondCode must be one of those supported by the RISC-V 113349cc55cSDimitry Andric // ISA (see translateSetCCForBranch). 114349cc55cSDimitry Andric static RISCVCC::CondCode getRISCVCCForIntCC(ISD::CondCode CC) { 115349cc55cSDimitry Andric switch (CC) { 116349cc55cSDimitry Andric default: 117349cc55cSDimitry Andric llvm_unreachable("Unsupported CondCode"); 118349cc55cSDimitry Andric case ISD::SETEQ: 119349cc55cSDimitry Andric return RISCVCC::COND_EQ; 120349cc55cSDimitry Andric case ISD::SETNE: 121349cc55cSDimitry Andric return RISCVCC::COND_NE; 122349cc55cSDimitry Andric case ISD::SETLT: 123349cc55cSDimitry Andric return RISCVCC::COND_LT; 124349cc55cSDimitry Andric case ISD::SETGE: 125349cc55cSDimitry Andric return RISCVCC::COND_GE; 126349cc55cSDimitry Andric case ISD::SETULT: 127349cc55cSDimitry Andric return RISCVCC::COND_LTU; 128349cc55cSDimitry Andric case ISD::SETUGE: 129349cc55cSDimitry Andric return RISCVCC::COND_GEU; 130349cc55cSDimitry Andric } 131349cc55cSDimitry Andric } 132349cc55cSDimitry Andric 1335ffd83dbSDimitry Andric // Include the pieces autogenerated from the target description. 1345ffd83dbSDimitry Andric #include "RISCVGenDAGISel.inc" 1355ffd83dbSDimitry Andric 1365ffd83dbSDimitry Andric private: 137349cc55cSDimitry Andric bool doPeepholeSExtW(SDNode *Node); 13881ad6265SDimitry Andric bool doPeepholeMaskedRVV(SDNode *Node); 139*bdd1243dSDimitry Andric bool doPeepholeMergeVVMFold(); 140*bdd1243dSDimitry Andric bool performVMergeToVAdd(SDNode *N); 141*bdd1243dSDimitry Andric bool performCombineVMergeAndVOps(SDNode *N, bool IsTA); 1425ffd83dbSDimitry Andric }; 143fe6060f1SDimitry Andric 144fe6060f1SDimitry Andric namespace RISCV { 145fe6060f1SDimitry Andric struct VLSEGPseudo { 146fe6060f1SDimitry Andric uint16_t NF : 4; 147fe6060f1SDimitry Andric uint16_t Masked : 1; 14881ad6265SDimitry Andric uint16_t IsTU : 1; 149fe6060f1SDimitry Andric uint16_t Strided : 1; 150fe6060f1SDimitry Andric uint16_t FF : 1; 151fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 152fe6060f1SDimitry Andric uint16_t LMUL : 3; 153fe6060f1SDimitry Andric uint16_t Pseudo; 154fe6060f1SDimitry Andric }; 155fe6060f1SDimitry Andric 156fe6060f1SDimitry Andric struct VLXSEGPseudo { 157fe6060f1SDimitry Andric uint16_t NF : 4; 158fe6060f1SDimitry Andric uint16_t Masked : 1; 15981ad6265SDimitry Andric uint16_t IsTU : 1; 160fe6060f1SDimitry Andric uint16_t Ordered : 1; 161fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 162fe6060f1SDimitry Andric uint16_t LMUL : 3; 163fe6060f1SDimitry Andric uint16_t IndexLMUL : 3; 164fe6060f1SDimitry Andric uint16_t Pseudo; 165fe6060f1SDimitry Andric }; 166fe6060f1SDimitry Andric 167fe6060f1SDimitry Andric struct VSSEGPseudo { 168fe6060f1SDimitry Andric uint16_t NF : 4; 169fe6060f1SDimitry Andric uint16_t Masked : 1; 170fe6060f1SDimitry Andric uint16_t Strided : 1; 171fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 172fe6060f1SDimitry Andric uint16_t LMUL : 3; 173fe6060f1SDimitry Andric uint16_t Pseudo; 174fe6060f1SDimitry Andric }; 175fe6060f1SDimitry Andric 176fe6060f1SDimitry Andric struct VSXSEGPseudo { 177fe6060f1SDimitry Andric uint16_t NF : 4; 178fe6060f1SDimitry Andric uint16_t Masked : 1; 179fe6060f1SDimitry Andric uint16_t Ordered : 1; 180fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 181fe6060f1SDimitry Andric uint16_t LMUL : 3; 182fe6060f1SDimitry Andric uint16_t IndexLMUL : 3; 183fe6060f1SDimitry Andric uint16_t Pseudo; 184fe6060f1SDimitry Andric }; 185fe6060f1SDimitry Andric 186fe6060f1SDimitry Andric struct VLEPseudo { 187fe6060f1SDimitry Andric uint16_t Masked : 1; 18804eeddc0SDimitry Andric uint16_t IsTU : 1; 189fe6060f1SDimitry Andric uint16_t Strided : 1; 190fe6060f1SDimitry Andric uint16_t FF : 1; 191fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 192fe6060f1SDimitry Andric uint16_t LMUL : 3; 193fe6060f1SDimitry Andric uint16_t Pseudo; 194fe6060f1SDimitry Andric }; 195fe6060f1SDimitry Andric 196fe6060f1SDimitry Andric struct VSEPseudo { 197fe6060f1SDimitry Andric uint16_t Masked :1; 198fe6060f1SDimitry Andric uint16_t Strided : 1; 199fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 200fe6060f1SDimitry Andric uint16_t LMUL : 3; 201fe6060f1SDimitry Andric uint16_t Pseudo; 202fe6060f1SDimitry Andric }; 203fe6060f1SDimitry Andric 204fe6060f1SDimitry Andric struct VLX_VSXPseudo { 205fe6060f1SDimitry Andric uint16_t Masked : 1; 20604eeddc0SDimitry Andric uint16_t IsTU : 1; 207fe6060f1SDimitry Andric uint16_t Ordered : 1; 208fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 209fe6060f1SDimitry Andric uint16_t LMUL : 3; 210fe6060f1SDimitry Andric uint16_t IndexLMUL : 3; 211fe6060f1SDimitry Andric uint16_t Pseudo; 212fe6060f1SDimitry Andric }; 213fe6060f1SDimitry Andric 21481ad6265SDimitry Andric struct RISCVMaskedPseudoInfo { 21581ad6265SDimitry Andric uint16_t MaskedPseudo; 21681ad6265SDimitry Andric uint16_t UnmaskedPseudo; 21781ad6265SDimitry Andric uint16_t UnmaskedTUPseudo; 21881ad6265SDimitry Andric uint8_t MaskOpIdx; 21981ad6265SDimitry Andric }; 22081ad6265SDimitry Andric 221fe6060f1SDimitry Andric #define GET_RISCVVSSEGTable_DECL 222fe6060f1SDimitry Andric #define GET_RISCVVLSEGTable_DECL 223fe6060f1SDimitry Andric #define GET_RISCVVLXSEGTable_DECL 224fe6060f1SDimitry Andric #define GET_RISCVVSXSEGTable_DECL 225fe6060f1SDimitry Andric #define GET_RISCVVLETable_DECL 226fe6060f1SDimitry Andric #define GET_RISCVVSETable_DECL 227fe6060f1SDimitry Andric #define GET_RISCVVLXTable_DECL 228fe6060f1SDimitry Andric #define GET_RISCVVSXTable_DECL 22981ad6265SDimitry Andric #define GET_RISCVMaskedPseudosTable_DECL 230fe6060f1SDimitry Andric #include "RISCVGenSearchableTables.inc" 231fe6060f1SDimitry Andric } // namespace RISCV 232fe6060f1SDimitry Andric 233fe6060f1SDimitry Andric } // namespace llvm 2345ffd83dbSDimitry Andric 2355ffd83dbSDimitry Andric #endif 236