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 61349cc55cSDimitry Andric bool hasAllNBitUsers(SDNode *Node, unsigned Bits) const; 62349cc55cSDimitry Andric bool hasAllHUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 16); } 63349cc55cSDimitry Andric bool hasAllWUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 32); } 64349cc55cSDimitry 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, 82349cc55cSDimitry 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*04eeddc0SDimitry Andric void selectVSETVLI(SDNode *Node); 91*04eeddc0SDimitry Andric 92349cc55cSDimitry Andric // Return the RISC-V condition code that matches the given DAG integer 93349cc55cSDimitry Andric // condition code. The CondCode must be one of those supported by the RISC-V 94349cc55cSDimitry Andric // ISA (see translateSetCCForBranch). 95349cc55cSDimitry Andric static RISCVCC::CondCode getRISCVCCForIntCC(ISD::CondCode CC) { 96349cc55cSDimitry Andric switch (CC) { 97349cc55cSDimitry Andric default: 98349cc55cSDimitry Andric llvm_unreachable("Unsupported CondCode"); 99349cc55cSDimitry Andric case ISD::SETEQ: 100349cc55cSDimitry Andric return RISCVCC::COND_EQ; 101349cc55cSDimitry Andric case ISD::SETNE: 102349cc55cSDimitry Andric return RISCVCC::COND_NE; 103349cc55cSDimitry Andric case ISD::SETLT: 104349cc55cSDimitry Andric return RISCVCC::COND_LT; 105349cc55cSDimitry Andric case ISD::SETGE: 106349cc55cSDimitry Andric return RISCVCC::COND_GE; 107349cc55cSDimitry Andric case ISD::SETULT: 108349cc55cSDimitry Andric return RISCVCC::COND_LTU; 109349cc55cSDimitry Andric case ISD::SETUGE: 110349cc55cSDimitry Andric return RISCVCC::COND_GEU; 111349cc55cSDimitry Andric } 112349cc55cSDimitry Andric } 113349cc55cSDimitry Andric 1145ffd83dbSDimitry Andric // Include the pieces autogenerated from the target description. 1155ffd83dbSDimitry Andric #include "RISCVGenDAGISel.inc" 1165ffd83dbSDimitry Andric 1175ffd83dbSDimitry Andric private: 118349cc55cSDimitry Andric bool doPeepholeLoadStoreADDI(SDNode *Node); 119349cc55cSDimitry Andric bool doPeepholeSExtW(SDNode *Node); 1205ffd83dbSDimitry Andric }; 121fe6060f1SDimitry Andric 122fe6060f1SDimitry Andric namespace RISCV { 123fe6060f1SDimitry Andric struct VLSEGPseudo { 124fe6060f1SDimitry Andric uint16_t NF : 4; 125fe6060f1SDimitry Andric uint16_t Masked : 1; 126fe6060f1SDimitry Andric uint16_t Strided : 1; 127fe6060f1SDimitry Andric uint16_t FF : 1; 128fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 129fe6060f1SDimitry Andric uint16_t LMUL : 3; 130fe6060f1SDimitry Andric uint16_t Pseudo; 131fe6060f1SDimitry Andric }; 132fe6060f1SDimitry Andric 133fe6060f1SDimitry Andric struct VLXSEGPseudo { 134fe6060f1SDimitry Andric uint16_t NF : 4; 135fe6060f1SDimitry Andric uint16_t Masked : 1; 136fe6060f1SDimitry Andric uint16_t Ordered : 1; 137fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 138fe6060f1SDimitry Andric uint16_t LMUL : 3; 139fe6060f1SDimitry Andric uint16_t IndexLMUL : 3; 140fe6060f1SDimitry Andric uint16_t Pseudo; 141fe6060f1SDimitry Andric }; 142fe6060f1SDimitry Andric 143fe6060f1SDimitry Andric struct VSSEGPseudo { 144fe6060f1SDimitry Andric uint16_t NF : 4; 145fe6060f1SDimitry Andric uint16_t Masked : 1; 146fe6060f1SDimitry Andric uint16_t Strided : 1; 147fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 148fe6060f1SDimitry Andric uint16_t LMUL : 3; 149fe6060f1SDimitry Andric uint16_t Pseudo; 150fe6060f1SDimitry Andric }; 151fe6060f1SDimitry Andric 152fe6060f1SDimitry Andric struct VSXSEGPseudo { 153fe6060f1SDimitry Andric uint16_t NF : 4; 154fe6060f1SDimitry Andric uint16_t Masked : 1; 155fe6060f1SDimitry Andric uint16_t Ordered : 1; 156fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 157fe6060f1SDimitry Andric uint16_t LMUL : 3; 158fe6060f1SDimitry Andric uint16_t IndexLMUL : 3; 159fe6060f1SDimitry Andric uint16_t Pseudo; 160fe6060f1SDimitry Andric }; 161fe6060f1SDimitry Andric 162fe6060f1SDimitry Andric struct VLEPseudo { 163fe6060f1SDimitry Andric uint16_t Masked : 1; 164*04eeddc0SDimitry Andric uint16_t IsTU : 1; 165fe6060f1SDimitry Andric uint16_t Strided : 1; 166fe6060f1SDimitry Andric uint16_t FF : 1; 167fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 168fe6060f1SDimitry Andric uint16_t LMUL : 3; 169fe6060f1SDimitry Andric uint16_t Pseudo; 170fe6060f1SDimitry Andric }; 171fe6060f1SDimitry Andric 172fe6060f1SDimitry Andric struct VSEPseudo { 173fe6060f1SDimitry Andric uint16_t Masked :1; 174fe6060f1SDimitry Andric uint16_t Strided : 1; 175fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 176fe6060f1SDimitry Andric uint16_t LMUL : 3; 177fe6060f1SDimitry Andric uint16_t Pseudo; 178fe6060f1SDimitry Andric }; 179fe6060f1SDimitry Andric 180fe6060f1SDimitry Andric struct VLX_VSXPseudo { 181fe6060f1SDimitry Andric uint16_t Masked : 1; 182*04eeddc0SDimitry Andric uint16_t IsTU : 1; 183fe6060f1SDimitry Andric uint16_t Ordered : 1; 184fe6060f1SDimitry Andric uint16_t Log2SEW : 3; 185fe6060f1SDimitry Andric uint16_t LMUL : 3; 186fe6060f1SDimitry Andric uint16_t IndexLMUL : 3; 187fe6060f1SDimitry Andric uint16_t Pseudo; 188fe6060f1SDimitry Andric }; 189fe6060f1SDimitry Andric 190fe6060f1SDimitry Andric #define GET_RISCVVSSEGTable_DECL 191fe6060f1SDimitry Andric #define GET_RISCVVLSEGTable_DECL 192fe6060f1SDimitry Andric #define GET_RISCVVLXSEGTable_DECL 193fe6060f1SDimitry Andric #define GET_RISCVVSXSEGTable_DECL 194fe6060f1SDimitry Andric #define GET_RISCVVLETable_DECL 195fe6060f1SDimitry Andric #define GET_RISCVVSETable_DECL 196fe6060f1SDimitry Andric #define GET_RISCVVLXTable_DECL 197fe6060f1SDimitry Andric #define GET_RISCVVSXTable_DECL 198fe6060f1SDimitry Andric #include "RISCVGenSearchableTables.inc" 199fe6060f1SDimitry Andric } // namespace RISCV 200fe6060f1SDimitry Andric 201fe6060f1SDimitry Andric } // namespace llvm 2025ffd83dbSDimitry Andric 2035ffd83dbSDimitry Andric #endif 204