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