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