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: 275ffd83dbSDimitry Andric explicit RISCVDAGToDAGISel(RISCVTargetMachine &TargetMachine) 285ffd83dbSDimitry Andric : SelectionDAGISel(TargetMachine) {} 295ffd83dbSDimitry Andric 305ffd83dbSDimitry Andric StringRef getPassName() const override { 315ffd83dbSDimitry Andric return "RISCV DAG->DAG Pattern Instruction Selection"; 325ffd83dbSDimitry Andric } 335ffd83dbSDimitry Andric 345ffd83dbSDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override { 355ffd83dbSDimitry Andric Subtarget = &MF.getSubtarget<RISCVSubtarget>(); 365ffd83dbSDimitry Andric return SelectionDAGISel::runOnMachineFunction(MF); 375ffd83dbSDimitry Andric } 385ffd83dbSDimitry Andric 39fe6060f1SDimitry Andric void PreprocessISelDAG() override; 405ffd83dbSDimitry Andric void PostprocessISelDAG() override; 415ffd83dbSDimitry Andric 425ffd83dbSDimitry Andric void Select(SDNode *Node) override; 435ffd83dbSDimitry Andric 445ffd83dbSDimitry Andric bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, 455ffd83dbSDimitry Andric std::vector<SDValue> &OutOps) override; 465ffd83dbSDimitry Andric 475ffd83dbSDimitry Andric bool SelectAddrFI(SDValue Addr, SDValue &Base); 48fe6060f1SDimitry Andric bool SelectBaseAddr(SDValue Addr, SDValue &Base); 495ffd83dbSDimitry Andric 50fe6060f1SDimitry Andric bool selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt); 51fe6060f1SDimitry Andric bool selectShiftMaskXLen(SDValue N, SDValue &ShAmt) { 52fe6060f1SDimitry Andric return selectShiftMask(N, Subtarget->getXLen(), ShAmt); 53fe6060f1SDimitry Andric } 54fe6060f1SDimitry Andric bool selectShiftMask32(SDValue N, SDValue &ShAmt) { 55fe6060f1SDimitry Andric return selectShiftMask(N, 32, ShAmt); 56fe6060f1SDimitry Andric } 57fe6060f1SDimitry Andric 58fe6060f1SDimitry Andric bool selectSExti32(SDValue N, SDValue &Val); 59fe6060f1SDimitry Andric bool selectZExti32(SDValue N, SDValue &Val); 60e8d8bef9SDimitry Andric 61*349cc55cSDimitry Andric bool hasAllNBitUsers(SDNode *Node, unsigned Bits) const; 62*349cc55cSDimitry Andric bool hasAllHUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 16); } 63*349cc55cSDimitry Andric bool hasAllWUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 32); } 64*349cc55cSDimitry Andric 65d409305fSDimitry Andric bool selectVLOp(SDValue N, SDValue &VL); 66d409305fSDimitry Andric 67e8d8bef9SDimitry Andric bool selectVSplat(SDValue N, SDValue &SplatVal); 68e8d8bef9SDimitry Andric bool selectVSplatSimm5(SDValue N, SDValue &SplatVal); 69e8d8bef9SDimitry Andric bool selectVSplatUimm5(SDValue N, SDValue &SplatVal); 70fe6060f1SDimitry Andric bool selectVSplatSimm5Plus1(SDValue N, SDValue &SplatVal); 71fe6060f1SDimitry Andric bool selectVSplatSimm5Plus1NonZero(SDValue N, SDValue &SplatVal); 72e8d8bef9SDimitry Andric 73fe6060f1SDimitry Andric bool selectRVVSimm5(SDValue N, unsigned Width, SDValue &Imm); 74fe6060f1SDimitry Andric template <unsigned Width> bool selectRVVSimm5(SDValue N, SDValue &Imm) { 75fe6060f1SDimitry Andric return selectRVVSimm5(N, Width, Imm); 76fe6060f1SDimitry Andric } 77fe6060f1SDimitry Andric 78fe6060f1SDimitry Andric void addVectorLoadStoreOperands(SDNode *Node, unsigned SEWImm, 79fe6060f1SDimitry Andric const SDLoc &DL, unsigned CurOp, 80fe6060f1SDimitry Andric bool IsMasked, bool IsStridedOrIndexed, 81fe6060f1SDimitry Andric SmallVectorImpl<SDValue> &Operands, 82*349cc55cSDimitry Andric bool IsLoad = false, MVT *IndexVT = nullptr); 83fe6060f1SDimitry Andric 84fe6060f1SDimitry Andric void selectVLSEG(SDNode *Node, bool IsMasked, bool IsStrided); 85fe6060f1SDimitry Andric void selectVLSEGFF(SDNode *Node, bool IsMasked); 86fe6060f1SDimitry Andric void selectVLXSEG(SDNode *Node, bool IsMasked, bool IsOrdered); 87fe6060f1SDimitry Andric void selectVSSEG(SDNode *Node, bool IsMasked, bool IsStrided); 88fe6060f1SDimitry Andric void selectVSXSEG(SDNode *Node, bool IsMasked, bool IsOrdered); 89979e22ffSDimitry Andric 90*349cc55cSDimitry Andric // Return the RISC-V condition code that matches the given DAG integer 91*349cc55cSDimitry Andric // condition code. The CondCode must be one of those supported by the RISC-V 92*349cc55cSDimitry Andric // ISA (see translateSetCCForBranch). 93*349cc55cSDimitry Andric static RISCVCC::CondCode getRISCVCCForIntCC(ISD::CondCode CC) { 94*349cc55cSDimitry Andric switch (CC) { 95*349cc55cSDimitry Andric default: 96*349cc55cSDimitry Andric llvm_unreachable("Unsupported CondCode"); 97*349cc55cSDimitry Andric case ISD::SETEQ: 98*349cc55cSDimitry Andric return RISCVCC::COND_EQ; 99*349cc55cSDimitry Andric case ISD::SETNE: 100*349cc55cSDimitry Andric return RISCVCC::COND_NE; 101*349cc55cSDimitry Andric case ISD::SETLT: 102*349cc55cSDimitry Andric return RISCVCC::COND_LT; 103*349cc55cSDimitry Andric case ISD::SETGE: 104*349cc55cSDimitry Andric return RISCVCC::COND_GE; 105*349cc55cSDimitry Andric case ISD::SETULT: 106*349cc55cSDimitry Andric return RISCVCC::COND_LTU; 107*349cc55cSDimitry Andric case ISD::SETUGE: 108*349cc55cSDimitry Andric return RISCVCC::COND_GEU; 109*349cc55cSDimitry Andric } 110*349cc55cSDimitry Andric } 111*349cc55cSDimitry Andric 1125ffd83dbSDimitry Andric // Include the pieces autogenerated from the target description. 1135ffd83dbSDimitry Andric #include "RISCVGenDAGISel.inc" 1145ffd83dbSDimitry Andric 1155ffd83dbSDimitry Andric private: 116*349cc55cSDimitry Andric bool doPeepholeLoadStoreADDI(SDNode *Node); 117*349cc55cSDimitry Andric bool doPeepholeSExtW(SDNode *Node); 1185ffd83dbSDimitry Andric }; 119fe6060f1SDimitry Andric 120fe6060f1SDimitry Andric namespace RISCV { 121fe6060f1SDimitry Andric struct VLSEGPseudo { 122fe6060f1SDimitry Andric uint16_t NF : 4; 123fe6060f1SDimitry Andric uint16_t Masked : 1; 124fe6060f1SDimitry Andric uint16_t Strided : 1; 125fe6060f1SDimitry Andric uint16_t FF : 1; 126fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 127fe6060f1SDimitry Andric uint16_t LMUL : 3; 128fe6060f1SDimitry Andric uint16_t Pseudo; 129fe6060f1SDimitry Andric }; 130fe6060f1SDimitry Andric 131fe6060f1SDimitry Andric struct VLXSEGPseudo { 132fe6060f1SDimitry Andric uint16_t NF : 4; 133fe6060f1SDimitry Andric uint16_t Masked : 1; 134fe6060f1SDimitry Andric uint16_t Ordered : 1; 135fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 136fe6060f1SDimitry Andric uint16_t LMUL : 3; 137fe6060f1SDimitry Andric uint16_t IndexLMUL : 3; 138fe6060f1SDimitry Andric uint16_t Pseudo; 139fe6060f1SDimitry Andric }; 140fe6060f1SDimitry Andric 141fe6060f1SDimitry Andric struct VSSEGPseudo { 142fe6060f1SDimitry Andric uint16_t NF : 4; 143fe6060f1SDimitry Andric uint16_t Masked : 1; 144fe6060f1SDimitry Andric uint16_t Strided : 1; 145fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 146fe6060f1SDimitry Andric uint16_t LMUL : 3; 147fe6060f1SDimitry Andric uint16_t Pseudo; 148fe6060f1SDimitry Andric }; 149fe6060f1SDimitry Andric 150fe6060f1SDimitry Andric struct VSXSEGPseudo { 151fe6060f1SDimitry Andric uint16_t NF : 4; 152fe6060f1SDimitry Andric uint16_t Masked : 1; 153fe6060f1SDimitry Andric uint16_t Ordered : 1; 154fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 155fe6060f1SDimitry Andric uint16_t LMUL : 3; 156fe6060f1SDimitry Andric uint16_t IndexLMUL : 3; 157fe6060f1SDimitry Andric uint16_t Pseudo; 158fe6060f1SDimitry Andric }; 159fe6060f1SDimitry Andric 160fe6060f1SDimitry Andric struct VLEPseudo { 161fe6060f1SDimitry Andric uint16_t Masked : 1; 162fe6060f1SDimitry Andric uint16_t Strided : 1; 163fe6060f1SDimitry Andric uint16_t FF : 1; 164fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 165fe6060f1SDimitry Andric uint16_t LMUL : 3; 166fe6060f1SDimitry Andric uint16_t Pseudo; 167fe6060f1SDimitry Andric }; 168fe6060f1SDimitry Andric 169fe6060f1SDimitry Andric struct VSEPseudo { 170fe6060f1SDimitry Andric uint16_t Masked :1; 171fe6060f1SDimitry Andric uint16_t Strided : 1; 172fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 173fe6060f1SDimitry Andric uint16_t LMUL : 3; 174fe6060f1SDimitry Andric uint16_t Pseudo; 175fe6060f1SDimitry Andric }; 176fe6060f1SDimitry Andric 177fe6060f1SDimitry Andric struct VLX_VSXPseudo { 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 #define GET_RISCVVSSEGTable_DECL 187fe6060f1SDimitry Andric #define GET_RISCVVLSEGTable_DECL 188fe6060f1SDimitry Andric #define GET_RISCVVLXSEGTable_DECL 189fe6060f1SDimitry Andric #define GET_RISCVVSXSEGTable_DECL 190fe6060f1SDimitry Andric #define GET_RISCVVLETable_DECL 191fe6060f1SDimitry Andric #define GET_RISCVVSETable_DECL 192fe6060f1SDimitry Andric #define GET_RISCVVLXTable_DECL 193fe6060f1SDimitry Andric #define GET_RISCVVSXTable_DECL 194fe6060f1SDimitry Andric #include "RISCVGenSearchableTables.inc" 195fe6060f1SDimitry Andric } // namespace RISCV 196fe6060f1SDimitry Andric 197fe6060f1SDimitry Andric } // namespace llvm 1985ffd83dbSDimitry Andric 1995ffd83dbSDimitry Andric #endif 200