1 //===---- RISCVISelDAGToDAG.h - A dag to dag inst selector for RISCV ------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines an instruction selector for the RISCV target. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_LIB_TARGET_RISCV_RISCVISELDAGTODAG_H 14 #define LLVM_LIB_TARGET_RISCV_RISCVISELDAGTODAG_H 15 16 #include "RISCV.h" 17 #include "RISCVTargetMachine.h" 18 #include "llvm/CodeGen/SelectionDAGISel.h" 19 20 // RISCV-specific code to select RISCV machine instructions for 21 // SelectionDAG operations. 22 namespace llvm { 23 class RISCVDAGToDAGISel : public SelectionDAGISel { 24 const RISCVSubtarget *Subtarget = nullptr; 25 26 public: RISCVDAGToDAGISel(RISCVTargetMachine & TargetMachine)27 explicit RISCVDAGToDAGISel(RISCVTargetMachine &TargetMachine) 28 : SelectionDAGISel(TargetMachine) {} 29 getPassName()30 StringRef getPassName() const override { 31 return "RISCV DAG->DAG Pattern Instruction Selection"; 32 } 33 runOnMachineFunction(MachineFunction & MF)34 bool runOnMachineFunction(MachineFunction &MF) override { 35 Subtarget = &MF.getSubtarget<RISCVSubtarget>(); 36 return SelectionDAGISel::runOnMachineFunction(MF); 37 } 38 39 void PreprocessISelDAG() override; 40 void PostprocessISelDAG() override; 41 42 void Select(SDNode *Node) override; 43 44 bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, 45 std::vector<SDValue> &OutOps) override; 46 47 bool SelectAddrFI(SDValue Addr, SDValue &Base); 48 bool SelectBaseAddr(SDValue Addr, SDValue &Base); 49 50 bool selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt); selectShiftMaskXLen(SDValue N,SDValue & ShAmt)51 bool selectShiftMaskXLen(SDValue N, SDValue &ShAmt) { 52 return selectShiftMask(N, Subtarget->getXLen(), ShAmt); 53 } selectShiftMask32(SDValue N,SDValue & ShAmt)54 bool selectShiftMask32(SDValue N, SDValue &ShAmt) { 55 return selectShiftMask(N, 32, ShAmt); 56 } 57 58 bool selectSExti32(SDValue N, SDValue &Val); 59 bool selectZExti32(SDValue N, SDValue &Val); 60 61 bool hasAllNBitUsers(SDNode *Node, unsigned Bits) const; hasAllHUsers(SDNode * Node)62 bool hasAllHUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 16); } hasAllWUsers(SDNode * Node)63 bool hasAllWUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 32); } 64 65 bool selectVLOp(SDValue N, SDValue &VL); 66 67 bool selectVSplat(SDValue N, SDValue &SplatVal); 68 bool selectVSplatSimm5(SDValue N, SDValue &SplatVal); 69 bool selectVSplatUimm5(SDValue N, SDValue &SplatVal); 70 bool selectVSplatSimm5Plus1(SDValue N, SDValue &SplatVal); 71 bool selectVSplatSimm5Plus1NonZero(SDValue N, SDValue &SplatVal); 72 73 bool selectRVVSimm5(SDValue N, unsigned Width, SDValue &Imm); selectRVVSimm5(SDValue N,SDValue & Imm)74 template <unsigned Width> bool selectRVVSimm5(SDValue N, SDValue &Imm) { 75 return selectRVVSimm5(N, Width, Imm); 76 } 77 78 void addVectorLoadStoreOperands(SDNode *Node, unsigned SEWImm, 79 const SDLoc &DL, unsigned CurOp, 80 bool IsMasked, bool IsStridedOrIndexed, 81 SmallVectorImpl<SDValue> &Operands, 82 bool IsLoad = false, MVT *IndexVT = nullptr); 83 84 void selectVLSEG(SDNode *Node, bool IsMasked, bool IsStrided); 85 void selectVLSEGFF(SDNode *Node, bool IsMasked); 86 void selectVLXSEG(SDNode *Node, bool IsMasked, bool IsOrdered); 87 void selectVSSEG(SDNode *Node, bool IsMasked, bool IsStrided); 88 void selectVSXSEG(SDNode *Node, bool IsMasked, bool IsOrdered); 89 90 // Return the RISC-V condition code that matches the given DAG integer 91 // condition code. The CondCode must be one of those supported by the RISC-V 92 // ISA (see translateSetCCForBranch). getRISCVCCForIntCC(ISD::CondCode CC)93 static RISCVCC::CondCode getRISCVCCForIntCC(ISD::CondCode CC) { 94 switch (CC) { 95 default: 96 llvm_unreachable("Unsupported CondCode"); 97 case ISD::SETEQ: 98 return RISCVCC::COND_EQ; 99 case ISD::SETNE: 100 return RISCVCC::COND_NE; 101 case ISD::SETLT: 102 return RISCVCC::COND_LT; 103 case ISD::SETGE: 104 return RISCVCC::COND_GE; 105 case ISD::SETULT: 106 return RISCVCC::COND_LTU; 107 case ISD::SETUGE: 108 return RISCVCC::COND_GEU; 109 } 110 } 111 112 // Include the pieces autogenerated from the target description. 113 #include "RISCVGenDAGISel.inc" 114 115 private: 116 bool doPeepholeLoadStoreADDI(SDNode *Node); 117 bool doPeepholeSExtW(SDNode *Node); 118 }; 119 120 namespace RISCV { 121 struct VLSEGPseudo { 122 uint16_t NF : 4; 123 uint16_t Masked : 1; 124 uint16_t Strided : 1; 125 uint16_t FF : 1; 126 uint16_t Log2SEW : 3; 127 uint16_t LMUL : 3; 128 uint16_t Pseudo; 129 }; 130 131 struct VLXSEGPseudo { 132 uint16_t NF : 4; 133 uint16_t Masked : 1; 134 uint16_t Ordered : 1; 135 uint16_t Log2SEW : 3; 136 uint16_t LMUL : 3; 137 uint16_t IndexLMUL : 3; 138 uint16_t Pseudo; 139 }; 140 141 struct VSSEGPseudo { 142 uint16_t NF : 4; 143 uint16_t Masked : 1; 144 uint16_t Strided : 1; 145 uint16_t Log2SEW : 3; 146 uint16_t LMUL : 3; 147 uint16_t Pseudo; 148 }; 149 150 struct VSXSEGPseudo { 151 uint16_t NF : 4; 152 uint16_t Masked : 1; 153 uint16_t Ordered : 1; 154 uint16_t Log2SEW : 3; 155 uint16_t LMUL : 3; 156 uint16_t IndexLMUL : 3; 157 uint16_t Pseudo; 158 }; 159 160 struct VLEPseudo { 161 uint16_t Masked : 1; 162 uint16_t Strided : 1; 163 uint16_t FF : 1; 164 uint16_t Log2SEW : 3; 165 uint16_t LMUL : 3; 166 uint16_t Pseudo; 167 }; 168 169 struct VSEPseudo { 170 uint16_t Masked :1; 171 uint16_t Strided : 1; 172 uint16_t Log2SEW : 3; 173 uint16_t LMUL : 3; 174 uint16_t Pseudo; 175 }; 176 177 struct VLX_VSXPseudo { 178 uint16_t Masked : 1; 179 uint16_t Ordered : 1; 180 uint16_t Log2SEW : 3; 181 uint16_t LMUL : 3; 182 uint16_t IndexLMUL : 3; 183 uint16_t Pseudo; 184 }; 185 186 #define GET_RISCVVSSEGTable_DECL 187 #define GET_RISCVVLSEGTable_DECL 188 #define GET_RISCVVLXSEGTable_DECL 189 #define GET_RISCVVSXSEGTable_DECL 190 #define GET_RISCVVLETable_DECL 191 #define GET_RISCVVSETable_DECL 192 #define GET_RISCVVLXTable_DECL 193 #define GET_RISCVVSXTable_DECL 194 #include "RISCVGenSearchableTables.inc" 195 } // namespace RISCV 196 197 } // namespace llvm 198 199 #endif 200