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 #include "llvm/Support/KnownBits.h" 20 21 // RISCV-specific code to select RISCV machine instructions for 22 // SelectionDAG operations. 23 namespace llvm { 24 class RISCVDAGToDAGISel : public SelectionDAGISel { 25 const RISCVSubtarget *Subtarget = nullptr; 26 27 public: 28 static char ID; 29 30 RISCVDAGToDAGISel() = delete; 31 32 explicit RISCVDAGToDAGISel(RISCVTargetMachine &TargetMachine, 33 CodeGenOpt::Level OptLevel) 34 : SelectionDAGISel(ID, TargetMachine, OptLevel) {} 35 36 bool runOnMachineFunction(MachineFunction &MF) override { 37 Subtarget = &MF.getSubtarget<RISCVSubtarget>(); 38 return SelectionDAGISel::runOnMachineFunction(MF); 39 } 40 41 void PreprocessISelDAG() override; 42 void PostprocessISelDAG() override; 43 44 void Select(SDNode *Node) override; 45 46 bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, 47 std::vector<SDValue> &OutOps) override; 48 49 bool SelectAddrFrameIndex(SDValue Addr, SDValue &Base, SDValue &Offset); 50 bool SelectFrameAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset); 51 bool SelectAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset); 52 53 bool tryShrinkShlLogicImm(SDNode *Node); 54 55 bool selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt); 56 bool selectShiftMaskXLen(SDValue N, SDValue &ShAmt) { 57 return selectShiftMask(N, Subtarget->getXLen(), ShAmt); 58 } 59 bool selectShiftMask32(SDValue N, SDValue &ShAmt) { 60 return selectShiftMask(N, 32, ShAmt); 61 } 62 63 bool selectSExti32(SDValue N, SDValue &Val); 64 bool selectZExtBits(SDValue N, unsigned Bits, SDValue &Val); 65 template <unsigned Bits> bool selectZExtBits(SDValue N, SDValue &Val) { 66 return selectZExtBits(N, Bits, Val); 67 } 68 69 bool selectSHXADDOp(SDValue N, unsigned ShAmt, SDValue &Val); 70 template <unsigned ShAmt> bool selectSHXADDOp(SDValue N, SDValue &Val) { 71 return selectSHXADDOp(N, ShAmt, Val); 72 } 73 74 bool selectSHXADD_UWOp(SDValue N, unsigned ShAmt, SDValue &Val); 75 template <unsigned ShAmt> bool selectSHXADD_UWOp(SDValue N, SDValue &Val) { 76 return selectSHXADD_UWOp(N, ShAmt, Val); 77 } 78 79 bool hasAllNBitUsers(SDNode *Node, unsigned Bits, 80 const unsigned Depth = 0) const; 81 bool hasAllHUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 16); } 82 bool hasAllWUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 32); } 83 84 bool selectVLOp(SDValue N, SDValue &VL); 85 86 bool selectVSplat(SDValue N, SDValue &SplatVal); 87 bool selectVSplatSimm5(SDValue N, SDValue &SplatVal); 88 bool selectVSplatUimm5(SDValue N, SDValue &SplatVal); 89 bool selectVSplatSimm5Plus1(SDValue N, SDValue &SplatVal); 90 bool selectVSplatSimm5Plus1NonZero(SDValue N, SDValue &SplatVal); 91 92 bool selectRVVSimm5(SDValue N, unsigned Width, SDValue &Imm); 93 template <unsigned Width> bool selectRVVSimm5(SDValue N, SDValue &Imm) { 94 return selectRVVSimm5(N, Width, Imm); 95 } 96 97 void addVectorLoadStoreOperands(SDNode *Node, unsigned SEWImm, 98 const SDLoc &DL, unsigned CurOp, 99 bool IsMasked, bool IsStridedOrIndexed, 100 SmallVectorImpl<SDValue> &Operands, 101 bool IsLoad = false, MVT *IndexVT = nullptr); 102 103 void selectVLSEG(SDNode *Node, bool IsMasked, bool IsStrided); 104 void selectVLSEGFF(SDNode *Node, bool IsMasked); 105 void selectVLXSEG(SDNode *Node, bool IsMasked, bool IsOrdered); 106 void selectVSSEG(SDNode *Node, bool IsMasked, bool IsStrided); 107 void selectVSXSEG(SDNode *Node, bool IsMasked, bool IsOrdered); 108 109 void selectVSETVLI(SDNode *Node); 110 111 // Return the RISC-V condition code that matches the given DAG integer 112 // condition code. The CondCode must be one of those supported by the RISC-V 113 // ISA (see translateSetCCForBranch). 114 static RISCVCC::CondCode getRISCVCCForIntCC(ISD::CondCode CC) { 115 switch (CC) { 116 default: 117 llvm_unreachable("Unsupported CondCode"); 118 case ISD::SETEQ: 119 return RISCVCC::COND_EQ; 120 case ISD::SETNE: 121 return RISCVCC::COND_NE; 122 case ISD::SETLT: 123 return RISCVCC::COND_LT; 124 case ISD::SETGE: 125 return RISCVCC::COND_GE; 126 case ISD::SETULT: 127 return RISCVCC::COND_LTU; 128 case ISD::SETUGE: 129 return RISCVCC::COND_GEU; 130 } 131 } 132 133 // Include the pieces autogenerated from the target description. 134 #include "RISCVGenDAGISel.inc" 135 136 private: 137 bool doPeepholeSExtW(SDNode *Node); 138 bool doPeepholeMaskedRVV(SDNode *Node); 139 bool doPeepholeMergeVVMFold(); 140 bool performVMergeToVAdd(SDNode *N); 141 bool performCombineVMergeAndVOps(SDNode *N, bool IsTA); 142 }; 143 144 namespace RISCV { 145 struct VLSEGPseudo { 146 uint16_t NF : 4; 147 uint16_t Masked : 1; 148 uint16_t IsTU : 1; 149 uint16_t Strided : 1; 150 uint16_t FF : 1; 151 uint16_t Log2SEW : 3; 152 uint16_t LMUL : 3; 153 uint16_t Pseudo; 154 }; 155 156 struct VLXSEGPseudo { 157 uint16_t NF : 4; 158 uint16_t Masked : 1; 159 uint16_t IsTU : 1; 160 uint16_t Ordered : 1; 161 uint16_t Log2SEW : 3; 162 uint16_t LMUL : 3; 163 uint16_t IndexLMUL : 3; 164 uint16_t Pseudo; 165 }; 166 167 struct VSSEGPseudo { 168 uint16_t NF : 4; 169 uint16_t Masked : 1; 170 uint16_t Strided : 1; 171 uint16_t Log2SEW : 3; 172 uint16_t LMUL : 3; 173 uint16_t Pseudo; 174 }; 175 176 struct VSXSEGPseudo { 177 uint16_t NF : 4; 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 struct VLEPseudo { 187 uint16_t Masked : 1; 188 uint16_t IsTU : 1; 189 uint16_t Strided : 1; 190 uint16_t FF : 1; 191 uint16_t Log2SEW : 3; 192 uint16_t LMUL : 3; 193 uint16_t Pseudo; 194 }; 195 196 struct VSEPseudo { 197 uint16_t Masked :1; 198 uint16_t Strided : 1; 199 uint16_t Log2SEW : 3; 200 uint16_t LMUL : 3; 201 uint16_t Pseudo; 202 }; 203 204 struct VLX_VSXPseudo { 205 uint16_t Masked : 1; 206 uint16_t IsTU : 1; 207 uint16_t Ordered : 1; 208 uint16_t Log2SEW : 3; 209 uint16_t LMUL : 3; 210 uint16_t IndexLMUL : 3; 211 uint16_t Pseudo; 212 }; 213 214 struct RISCVMaskedPseudoInfo { 215 uint16_t MaskedPseudo; 216 uint16_t UnmaskedPseudo; 217 uint16_t UnmaskedTUPseudo; 218 uint8_t MaskOpIdx; 219 }; 220 221 #define GET_RISCVVSSEGTable_DECL 222 #define GET_RISCVVLSEGTable_DECL 223 #define GET_RISCVVLXSEGTable_DECL 224 #define GET_RISCVVSXSEGTable_DECL 225 #define GET_RISCVVLETable_DECL 226 #define GET_RISCVVSETable_DECL 227 #define GET_RISCVVLXTable_DECL 228 #define GET_RISCVVSXTable_DECL 229 #define GET_RISCVMaskedPseudosTable_DECL 230 #include "RISCVGenSearchableTables.inc" 231 } // namespace RISCV 232 233 } // namespace llvm 234 235 #endif 236