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" 195ffd83dbSDimitry Andric 205ffd83dbSDimitry Andric // RISCV-specific code to select RISCV machine instructions for 215ffd83dbSDimitry Andric // SelectionDAG operations. 225ffd83dbSDimitry Andric namespace llvm { 235ffd83dbSDimitry Andric class RISCVDAGToDAGISel : public SelectionDAGISel { 245ffd83dbSDimitry Andric const RISCVSubtarget *Subtarget = nullptr; 255ffd83dbSDimitry Andric 265ffd83dbSDimitry Andric public: 2781ad6265SDimitry Andric explicit RISCVDAGToDAGISel(RISCVTargetMachine &TargetMachine, 2881ad6265SDimitry Andric CodeGenOpt::Level OptLevel) 2981ad6265SDimitry Andric : SelectionDAGISel(TargetMachine, OptLevel) {} 305ffd83dbSDimitry Andric 315ffd83dbSDimitry Andric StringRef getPassName() const override { 325ffd83dbSDimitry Andric return "RISCV DAG->DAG Pattern Instruction Selection"; 335ffd83dbSDimitry Andric } 345ffd83dbSDimitry Andric 355ffd83dbSDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override { 365ffd83dbSDimitry Andric Subtarget = &MF.getSubtarget<RISCVSubtarget>(); 375ffd83dbSDimitry Andric return SelectionDAGISel::runOnMachineFunction(MF); 385ffd83dbSDimitry Andric } 395ffd83dbSDimitry Andric 40fe6060f1SDimitry Andric void PreprocessISelDAG() override; 415ffd83dbSDimitry Andric void PostprocessISelDAG() override; 425ffd83dbSDimitry Andric 435ffd83dbSDimitry Andric void Select(SDNode *Node) override; 445ffd83dbSDimitry Andric 455ffd83dbSDimitry Andric bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, 465ffd83dbSDimitry Andric std::vector<SDValue> &OutOps) override; 475ffd83dbSDimitry Andric 4881ad6265SDimitry Andric bool SelectAddrFrameIndex(SDValue Addr, SDValue &Base, SDValue &Offset); 4981ad6265SDimitry Andric bool SelectFrameAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset); 5081ad6265SDimitry Andric bool SelectAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset); 515ffd83dbSDimitry Andric 52fe6060f1SDimitry Andric bool selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt); 53fe6060f1SDimitry Andric bool selectShiftMaskXLen(SDValue N, SDValue &ShAmt) { 54fe6060f1SDimitry Andric return selectShiftMask(N, Subtarget->getXLen(), ShAmt); 55fe6060f1SDimitry Andric } 56fe6060f1SDimitry Andric bool selectShiftMask32(SDValue N, SDValue &ShAmt) { 57fe6060f1SDimitry Andric return selectShiftMask(N, 32, ShAmt); 58fe6060f1SDimitry Andric } 59fe6060f1SDimitry Andric 60fe6060f1SDimitry Andric bool selectSExti32(SDValue N, SDValue &Val); 61fe6060f1SDimitry Andric bool selectZExti32(SDValue N, SDValue &Val); 62e8d8bef9SDimitry Andric 63*753f127fSDimitry Andric bool selectSHXADDOp(SDValue N, unsigned ShAmt, SDValue &Val); 64*753f127fSDimitry Andric bool selectSH1ADDOp(SDValue N, SDValue &Val) { 65*753f127fSDimitry Andric return selectSHXADDOp(N, 1, Val); 66*753f127fSDimitry Andric } 67*753f127fSDimitry Andric bool selectSH2ADDOp(SDValue N, SDValue &Val) { 68*753f127fSDimitry Andric return selectSHXADDOp(N, 2, Val); 69*753f127fSDimitry Andric } 70*753f127fSDimitry Andric bool selectSH3ADDOp(SDValue N, SDValue &Val) { 71*753f127fSDimitry Andric return selectSHXADDOp(N, 3, Val); 72*753f127fSDimitry Andric } 73*753f127fSDimitry Andric 74349cc55cSDimitry Andric bool hasAllNBitUsers(SDNode *Node, unsigned Bits) const; 75349cc55cSDimitry Andric bool hasAllHUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 16); } 76349cc55cSDimitry Andric bool hasAllWUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 32); } 77349cc55cSDimitry Andric 78d409305fSDimitry Andric bool selectVLOp(SDValue N, SDValue &VL); 79d409305fSDimitry Andric 80e8d8bef9SDimitry Andric bool selectVSplat(SDValue N, SDValue &SplatVal); 81e8d8bef9SDimitry Andric bool selectVSplatSimm5(SDValue N, SDValue &SplatVal); 82e8d8bef9SDimitry Andric bool selectVSplatUimm5(SDValue N, SDValue &SplatVal); 83fe6060f1SDimitry Andric bool selectVSplatSimm5Plus1(SDValue N, SDValue &SplatVal); 84fe6060f1SDimitry Andric bool selectVSplatSimm5Plus1NonZero(SDValue N, SDValue &SplatVal); 85e8d8bef9SDimitry Andric 86fe6060f1SDimitry Andric bool selectRVVSimm5(SDValue N, unsigned Width, SDValue &Imm); 87fe6060f1SDimitry Andric template <unsigned Width> bool selectRVVSimm5(SDValue N, SDValue &Imm) { 88fe6060f1SDimitry Andric return selectRVVSimm5(N, Width, Imm); 89fe6060f1SDimitry Andric } 90fe6060f1SDimitry Andric 91fe6060f1SDimitry Andric void addVectorLoadStoreOperands(SDNode *Node, unsigned SEWImm, 92fe6060f1SDimitry Andric const SDLoc &DL, unsigned CurOp, 93fe6060f1SDimitry Andric bool IsMasked, bool IsStridedOrIndexed, 94fe6060f1SDimitry Andric SmallVectorImpl<SDValue> &Operands, 95349cc55cSDimitry Andric bool IsLoad = false, MVT *IndexVT = nullptr); 96fe6060f1SDimitry Andric 97fe6060f1SDimitry Andric void selectVLSEG(SDNode *Node, bool IsMasked, bool IsStrided); 98fe6060f1SDimitry Andric void selectVLSEGFF(SDNode *Node, bool IsMasked); 99fe6060f1SDimitry Andric void selectVLXSEG(SDNode *Node, bool IsMasked, bool IsOrdered); 100fe6060f1SDimitry Andric void selectVSSEG(SDNode *Node, bool IsMasked, bool IsStrided); 101fe6060f1SDimitry Andric void selectVSXSEG(SDNode *Node, bool IsMasked, bool IsOrdered); 102979e22ffSDimitry Andric 10304eeddc0SDimitry Andric void selectVSETVLI(SDNode *Node); 10404eeddc0SDimitry Andric 105349cc55cSDimitry Andric // Return the RISC-V condition code that matches the given DAG integer 106349cc55cSDimitry Andric // condition code. The CondCode must be one of those supported by the RISC-V 107349cc55cSDimitry Andric // ISA (see translateSetCCForBranch). 108349cc55cSDimitry Andric static RISCVCC::CondCode getRISCVCCForIntCC(ISD::CondCode CC) { 109349cc55cSDimitry Andric switch (CC) { 110349cc55cSDimitry Andric default: 111349cc55cSDimitry Andric llvm_unreachable("Unsupported CondCode"); 112349cc55cSDimitry Andric case ISD::SETEQ: 113349cc55cSDimitry Andric return RISCVCC::COND_EQ; 114349cc55cSDimitry Andric case ISD::SETNE: 115349cc55cSDimitry Andric return RISCVCC::COND_NE; 116349cc55cSDimitry Andric case ISD::SETLT: 117349cc55cSDimitry Andric return RISCVCC::COND_LT; 118349cc55cSDimitry Andric case ISD::SETGE: 119349cc55cSDimitry Andric return RISCVCC::COND_GE; 120349cc55cSDimitry Andric case ISD::SETULT: 121349cc55cSDimitry Andric return RISCVCC::COND_LTU; 122349cc55cSDimitry Andric case ISD::SETUGE: 123349cc55cSDimitry Andric return RISCVCC::COND_GEU; 124349cc55cSDimitry Andric } 125349cc55cSDimitry Andric } 126349cc55cSDimitry Andric 1275ffd83dbSDimitry Andric // Include the pieces autogenerated from the target description. 1285ffd83dbSDimitry Andric #include "RISCVGenDAGISel.inc" 1295ffd83dbSDimitry Andric 1305ffd83dbSDimitry Andric private: 131349cc55cSDimitry Andric bool doPeepholeSExtW(SDNode *Node); 13281ad6265SDimitry Andric bool doPeepholeMaskedRVV(SDNode *Node); 1335ffd83dbSDimitry Andric }; 134fe6060f1SDimitry Andric 135fe6060f1SDimitry Andric namespace RISCV { 136fe6060f1SDimitry Andric struct VLSEGPseudo { 137fe6060f1SDimitry Andric uint16_t NF : 4; 138fe6060f1SDimitry Andric uint16_t Masked : 1; 13981ad6265SDimitry Andric uint16_t IsTU : 1; 140fe6060f1SDimitry Andric uint16_t Strided : 1; 141fe6060f1SDimitry Andric uint16_t FF : 1; 142fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 143fe6060f1SDimitry Andric uint16_t LMUL : 3; 144fe6060f1SDimitry Andric uint16_t Pseudo; 145fe6060f1SDimitry Andric }; 146fe6060f1SDimitry Andric 147fe6060f1SDimitry Andric struct VLXSEGPseudo { 148fe6060f1SDimitry Andric uint16_t NF : 4; 149fe6060f1SDimitry Andric uint16_t Masked : 1; 15081ad6265SDimitry Andric uint16_t IsTU : 1; 151fe6060f1SDimitry Andric uint16_t Ordered : 1; 152fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 153fe6060f1SDimitry Andric uint16_t LMUL : 3; 154fe6060f1SDimitry Andric uint16_t IndexLMUL : 3; 155fe6060f1SDimitry Andric uint16_t Pseudo; 156fe6060f1SDimitry Andric }; 157fe6060f1SDimitry Andric 158fe6060f1SDimitry Andric struct VSSEGPseudo { 159fe6060f1SDimitry Andric uint16_t NF : 4; 160fe6060f1SDimitry Andric uint16_t Masked : 1; 161fe6060f1SDimitry Andric uint16_t Strided : 1; 162fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 163fe6060f1SDimitry Andric uint16_t LMUL : 3; 164fe6060f1SDimitry Andric uint16_t Pseudo; 165fe6060f1SDimitry Andric }; 166fe6060f1SDimitry Andric 167fe6060f1SDimitry Andric struct VSXSEGPseudo { 168fe6060f1SDimitry Andric uint16_t NF : 4; 169fe6060f1SDimitry Andric uint16_t Masked : 1; 170fe6060f1SDimitry Andric uint16_t Ordered : 1; 171fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 172fe6060f1SDimitry Andric uint16_t LMUL : 3; 173fe6060f1SDimitry Andric uint16_t IndexLMUL : 3; 174fe6060f1SDimitry Andric uint16_t Pseudo; 175fe6060f1SDimitry Andric }; 176fe6060f1SDimitry Andric 177fe6060f1SDimitry Andric struct VLEPseudo { 178fe6060f1SDimitry Andric uint16_t Masked : 1; 17904eeddc0SDimitry Andric uint16_t IsTU : 1; 180fe6060f1SDimitry Andric uint16_t Strided : 1; 181fe6060f1SDimitry Andric uint16_t FF : 1; 182fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 183fe6060f1SDimitry Andric uint16_t LMUL : 3; 184fe6060f1SDimitry Andric uint16_t Pseudo; 185fe6060f1SDimitry Andric }; 186fe6060f1SDimitry Andric 187fe6060f1SDimitry Andric struct VSEPseudo { 188fe6060f1SDimitry Andric uint16_t Masked :1; 189fe6060f1SDimitry Andric uint16_t Strided : 1; 190fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 191fe6060f1SDimitry Andric uint16_t LMUL : 3; 192fe6060f1SDimitry Andric uint16_t Pseudo; 193fe6060f1SDimitry Andric }; 194fe6060f1SDimitry Andric 195fe6060f1SDimitry Andric struct VLX_VSXPseudo { 196fe6060f1SDimitry Andric uint16_t Masked : 1; 19704eeddc0SDimitry Andric uint16_t IsTU : 1; 198fe6060f1SDimitry Andric uint16_t Ordered : 1; 199fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 200fe6060f1SDimitry Andric uint16_t LMUL : 3; 201fe6060f1SDimitry Andric uint16_t IndexLMUL : 3; 202fe6060f1SDimitry Andric uint16_t Pseudo; 203fe6060f1SDimitry Andric }; 204fe6060f1SDimitry Andric 20581ad6265SDimitry Andric struct RISCVMaskedPseudoInfo { 20681ad6265SDimitry Andric uint16_t MaskedPseudo; 20781ad6265SDimitry Andric uint16_t UnmaskedPseudo; 20881ad6265SDimitry Andric uint16_t UnmaskedTUPseudo; 20981ad6265SDimitry Andric uint8_t MaskOpIdx; 21081ad6265SDimitry Andric }; 21181ad6265SDimitry Andric 212fe6060f1SDimitry Andric #define GET_RISCVVSSEGTable_DECL 213fe6060f1SDimitry Andric #define GET_RISCVVLSEGTable_DECL 214fe6060f1SDimitry Andric #define GET_RISCVVLXSEGTable_DECL 215fe6060f1SDimitry Andric #define GET_RISCVVSXSEGTable_DECL 216fe6060f1SDimitry Andric #define GET_RISCVVLETable_DECL 217fe6060f1SDimitry Andric #define GET_RISCVVSETable_DECL 218fe6060f1SDimitry Andric #define GET_RISCVVLXTable_DECL 219fe6060f1SDimitry Andric #define GET_RISCVVSXTable_DECL 22081ad6265SDimitry Andric #define GET_RISCVMaskedPseudosTable_DECL 221fe6060f1SDimitry Andric #include "RISCVGenSearchableTables.inc" 222fe6060f1SDimitry Andric } // namespace RISCV 223fe6060f1SDimitry Andric 224fe6060f1SDimitry Andric } // namespace llvm 2255ffd83dbSDimitry Andric 2265ffd83dbSDimitry Andric #endif 227