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: 27*81ad6265SDimitry Andric explicit RISCVDAGToDAGISel(RISCVTargetMachine &TargetMachine, 28*81ad6265SDimitry Andric CodeGenOpt::Level OptLevel) 29*81ad6265SDimitry 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 48*81ad6265SDimitry Andric bool SelectAddrFrameIndex(SDValue Addr, SDValue &Base, SDValue &Offset); 49*81ad6265SDimitry Andric bool SelectFrameAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset); 50fe6060f1SDimitry Andric bool SelectBaseAddr(SDValue Addr, SDValue &Base); 51*81ad6265SDimitry Andric bool SelectAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset); 525ffd83dbSDimitry Andric 53fe6060f1SDimitry Andric bool selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt); 54fe6060f1SDimitry Andric bool selectShiftMaskXLen(SDValue N, SDValue &ShAmt) { 55fe6060f1SDimitry Andric return selectShiftMask(N, Subtarget->getXLen(), ShAmt); 56fe6060f1SDimitry Andric } 57fe6060f1SDimitry Andric bool selectShiftMask32(SDValue N, SDValue &ShAmt) { 58fe6060f1SDimitry Andric return selectShiftMask(N, 32, ShAmt); 59fe6060f1SDimitry Andric } 60fe6060f1SDimitry Andric 61fe6060f1SDimitry Andric bool selectSExti32(SDValue N, SDValue &Val); 62fe6060f1SDimitry Andric bool selectZExti32(SDValue N, SDValue &Val); 63e8d8bef9SDimitry Andric 64349cc55cSDimitry Andric bool hasAllNBitUsers(SDNode *Node, unsigned Bits) const; 65349cc55cSDimitry Andric bool hasAllHUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 16); } 66349cc55cSDimitry Andric bool hasAllWUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 32); } 67349cc55cSDimitry Andric 68d409305fSDimitry Andric bool selectVLOp(SDValue N, SDValue &VL); 69d409305fSDimitry Andric 70e8d8bef9SDimitry Andric bool selectVSplat(SDValue N, SDValue &SplatVal); 71e8d8bef9SDimitry Andric bool selectVSplatSimm5(SDValue N, SDValue &SplatVal); 72e8d8bef9SDimitry Andric bool selectVSplatUimm5(SDValue N, SDValue &SplatVal); 73fe6060f1SDimitry Andric bool selectVSplatSimm5Plus1(SDValue N, SDValue &SplatVal); 74fe6060f1SDimitry Andric bool selectVSplatSimm5Plus1NonZero(SDValue N, SDValue &SplatVal); 75e8d8bef9SDimitry Andric 76fe6060f1SDimitry Andric bool selectRVVSimm5(SDValue N, unsigned Width, SDValue &Imm); 77fe6060f1SDimitry Andric template <unsigned Width> bool selectRVVSimm5(SDValue N, SDValue &Imm) { 78fe6060f1SDimitry Andric return selectRVVSimm5(N, Width, Imm); 79fe6060f1SDimitry Andric } 80fe6060f1SDimitry Andric 81fe6060f1SDimitry Andric void addVectorLoadStoreOperands(SDNode *Node, unsigned SEWImm, 82fe6060f1SDimitry Andric const SDLoc &DL, unsigned CurOp, 83fe6060f1SDimitry Andric bool IsMasked, bool IsStridedOrIndexed, 84fe6060f1SDimitry Andric SmallVectorImpl<SDValue> &Operands, 85349cc55cSDimitry Andric bool IsLoad = false, MVT *IndexVT = nullptr); 86fe6060f1SDimitry Andric 87fe6060f1SDimitry Andric void selectVLSEG(SDNode *Node, bool IsMasked, bool IsStrided); 88fe6060f1SDimitry Andric void selectVLSEGFF(SDNode *Node, bool IsMasked); 89fe6060f1SDimitry Andric void selectVLXSEG(SDNode *Node, bool IsMasked, bool IsOrdered); 90fe6060f1SDimitry Andric void selectVSSEG(SDNode *Node, bool IsMasked, bool IsStrided); 91fe6060f1SDimitry Andric void selectVSXSEG(SDNode *Node, bool IsMasked, bool IsOrdered); 92979e22ffSDimitry Andric 9304eeddc0SDimitry Andric void selectVSETVLI(SDNode *Node); 9404eeddc0SDimitry Andric 95349cc55cSDimitry Andric // Return the RISC-V condition code that matches the given DAG integer 96349cc55cSDimitry Andric // condition code. The CondCode must be one of those supported by the RISC-V 97349cc55cSDimitry Andric // ISA (see translateSetCCForBranch). 98349cc55cSDimitry Andric static RISCVCC::CondCode getRISCVCCForIntCC(ISD::CondCode CC) { 99349cc55cSDimitry Andric switch (CC) { 100349cc55cSDimitry Andric default: 101349cc55cSDimitry Andric llvm_unreachable("Unsupported CondCode"); 102349cc55cSDimitry Andric case ISD::SETEQ: 103349cc55cSDimitry Andric return RISCVCC::COND_EQ; 104349cc55cSDimitry Andric case ISD::SETNE: 105349cc55cSDimitry Andric return RISCVCC::COND_NE; 106349cc55cSDimitry Andric case ISD::SETLT: 107349cc55cSDimitry Andric return RISCVCC::COND_LT; 108349cc55cSDimitry Andric case ISD::SETGE: 109349cc55cSDimitry Andric return RISCVCC::COND_GE; 110349cc55cSDimitry Andric case ISD::SETULT: 111349cc55cSDimitry Andric return RISCVCC::COND_LTU; 112349cc55cSDimitry Andric case ISD::SETUGE: 113349cc55cSDimitry Andric return RISCVCC::COND_GEU; 114349cc55cSDimitry Andric } 115349cc55cSDimitry Andric } 116349cc55cSDimitry Andric 1175ffd83dbSDimitry Andric // Include the pieces autogenerated from the target description. 1185ffd83dbSDimitry Andric #include "RISCVGenDAGISel.inc" 1195ffd83dbSDimitry Andric 1205ffd83dbSDimitry Andric private: 121349cc55cSDimitry Andric bool doPeepholeLoadStoreADDI(SDNode *Node); 122349cc55cSDimitry Andric bool doPeepholeSExtW(SDNode *Node); 123*81ad6265SDimitry Andric bool doPeepholeMaskedRVV(SDNode *Node); 1245ffd83dbSDimitry Andric }; 125fe6060f1SDimitry Andric 126fe6060f1SDimitry Andric namespace RISCV { 127fe6060f1SDimitry Andric struct VLSEGPseudo { 128fe6060f1SDimitry Andric uint16_t NF : 4; 129fe6060f1SDimitry Andric uint16_t Masked : 1; 130*81ad6265SDimitry Andric uint16_t IsTU : 1; 131fe6060f1SDimitry Andric uint16_t Strided : 1; 132fe6060f1SDimitry Andric uint16_t FF : 1; 133fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 134fe6060f1SDimitry Andric uint16_t LMUL : 3; 135fe6060f1SDimitry Andric uint16_t Pseudo; 136fe6060f1SDimitry Andric }; 137fe6060f1SDimitry Andric 138fe6060f1SDimitry Andric struct VLXSEGPseudo { 139fe6060f1SDimitry Andric uint16_t NF : 4; 140fe6060f1SDimitry Andric uint16_t Masked : 1; 141*81ad6265SDimitry Andric uint16_t IsTU : 1; 142fe6060f1SDimitry Andric uint16_t Ordered : 1; 143fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 144fe6060f1SDimitry Andric uint16_t LMUL : 3; 145fe6060f1SDimitry Andric uint16_t IndexLMUL : 3; 146fe6060f1SDimitry Andric uint16_t Pseudo; 147fe6060f1SDimitry Andric }; 148fe6060f1SDimitry Andric 149fe6060f1SDimitry Andric struct VSSEGPseudo { 150fe6060f1SDimitry Andric uint16_t NF : 4; 151fe6060f1SDimitry Andric uint16_t Masked : 1; 152fe6060f1SDimitry Andric uint16_t Strided : 1; 153fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 154fe6060f1SDimitry Andric uint16_t LMUL : 3; 155fe6060f1SDimitry Andric uint16_t Pseudo; 156fe6060f1SDimitry Andric }; 157fe6060f1SDimitry Andric 158fe6060f1SDimitry Andric struct VSXSEGPseudo { 159fe6060f1SDimitry Andric uint16_t NF : 4; 160fe6060f1SDimitry Andric uint16_t Masked : 1; 161fe6060f1SDimitry Andric uint16_t Ordered : 1; 162fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 163fe6060f1SDimitry Andric uint16_t LMUL : 3; 164fe6060f1SDimitry Andric uint16_t IndexLMUL : 3; 165fe6060f1SDimitry Andric uint16_t Pseudo; 166fe6060f1SDimitry Andric }; 167fe6060f1SDimitry Andric 168fe6060f1SDimitry Andric struct VLEPseudo { 169fe6060f1SDimitry Andric uint16_t Masked : 1; 17004eeddc0SDimitry Andric uint16_t IsTU : 1; 171fe6060f1SDimitry Andric uint16_t Strided : 1; 172fe6060f1SDimitry Andric uint16_t FF : 1; 173fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 174fe6060f1SDimitry Andric uint16_t LMUL : 3; 175fe6060f1SDimitry Andric uint16_t Pseudo; 176fe6060f1SDimitry Andric }; 177fe6060f1SDimitry Andric 178fe6060f1SDimitry Andric struct VSEPseudo { 179fe6060f1SDimitry Andric uint16_t Masked :1; 180fe6060f1SDimitry Andric uint16_t Strided : 1; 181fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 182fe6060f1SDimitry Andric uint16_t LMUL : 3; 183fe6060f1SDimitry Andric uint16_t Pseudo; 184fe6060f1SDimitry Andric }; 185fe6060f1SDimitry Andric 186fe6060f1SDimitry Andric struct VLX_VSXPseudo { 187fe6060f1SDimitry Andric uint16_t Masked : 1; 18804eeddc0SDimitry Andric uint16_t IsTU : 1; 189fe6060f1SDimitry Andric uint16_t Ordered : 1; 190fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 191fe6060f1SDimitry Andric uint16_t LMUL : 3; 192fe6060f1SDimitry Andric uint16_t IndexLMUL : 3; 193fe6060f1SDimitry Andric uint16_t Pseudo; 194fe6060f1SDimitry Andric }; 195fe6060f1SDimitry Andric 196*81ad6265SDimitry Andric struct RISCVMaskedPseudoInfo { 197*81ad6265SDimitry Andric uint16_t MaskedPseudo; 198*81ad6265SDimitry Andric uint16_t UnmaskedPseudo; 199*81ad6265SDimitry Andric uint16_t UnmaskedTUPseudo; 200*81ad6265SDimitry Andric uint8_t MaskOpIdx; 201*81ad6265SDimitry Andric }; 202*81ad6265SDimitry Andric 203fe6060f1SDimitry Andric #define GET_RISCVVSSEGTable_DECL 204fe6060f1SDimitry Andric #define GET_RISCVVLSEGTable_DECL 205fe6060f1SDimitry Andric #define GET_RISCVVLXSEGTable_DECL 206fe6060f1SDimitry Andric #define GET_RISCVVSXSEGTable_DECL 207fe6060f1SDimitry Andric #define GET_RISCVVLETable_DECL 208fe6060f1SDimitry Andric #define GET_RISCVVSETable_DECL 209fe6060f1SDimitry Andric #define GET_RISCVVLXTable_DECL 210fe6060f1SDimitry Andric #define GET_RISCVVSXTable_DECL 211*81ad6265SDimitry Andric #define GET_RISCVMaskedPseudosTable_DECL 212fe6060f1SDimitry Andric #include "RISCVGenSearchableTables.inc" 213fe6060f1SDimitry Andric } // namespace RISCV 214fe6060f1SDimitry Andric 215fe6060f1SDimitry Andric } // namespace llvm 2165ffd83dbSDimitry Andric 2175ffd83dbSDimitry Andric #endif 218