xref: /freebsd/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h (revision f126d349810fdb512c0b01e101342d430b947488)
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       : SelectionDAGISel(TargetMachine) {}
29 
30   StringRef getPassName() const override {
31     return "RISCV DAG->DAG Pattern Instruction Selection";
32   }
33 
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);
51   bool selectShiftMaskXLen(SDValue N, SDValue &ShAmt) {
52     return selectShiftMask(N, Subtarget->getXLen(), ShAmt);
53   }
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;
62   bool hasAllHUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 16); }
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);
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   void selectVSETVLI(SDNode *Node);
91 
92   // Return the RISC-V condition code that matches the given DAG integer
93   // condition code. The CondCode must be one of those supported by the RISC-V
94   // ISA (see translateSetCCForBranch).
95   static RISCVCC::CondCode getRISCVCCForIntCC(ISD::CondCode CC) {
96     switch (CC) {
97     default:
98       llvm_unreachable("Unsupported CondCode");
99     case ISD::SETEQ:
100       return RISCVCC::COND_EQ;
101     case ISD::SETNE:
102       return RISCVCC::COND_NE;
103     case ISD::SETLT:
104       return RISCVCC::COND_LT;
105     case ISD::SETGE:
106       return RISCVCC::COND_GE;
107     case ISD::SETULT:
108       return RISCVCC::COND_LTU;
109     case ISD::SETUGE:
110       return RISCVCC::COND_GEU;
111     }
112   }
113 
114 // Include the pieces autogenerated from the target description.
115 #include "RISCVGenDAGISel.inc"
116 
117 private:
118   bool doPeepholeLoadStoreADDI(SDNode *Node);
119   bool doPeepholeSExtW(SDNode *Node);
120 };
121 
122 namespace RISCV {
123 struct VLSEGPseudo {
124   uint16_t NF : 4;
125   uint16_t Masked : 1;
126   uint16_t Strided : 1;
127   uint16_t FF : 1;
128   uint16_t Log2SEW : 3;
129   uint16_t LMUL : 3;
130   uint16_t Pseudo;
131 };
132 
133 struct VLXSEGPseudo {
134   uint16_t NF : 4;
135   uint16_t Masked : 1;
136   uint16_t Ordered : 1;
137   uint16_t Log2SEW : 3;
138   uint16_t LMUL : 3;
139   uint16_t IndexLMUL : 3;
140   uint16_t Pseudo;
141 };
142 
143 struct VSSEGPseudo {
144   uint16_t NF : 4;
145   uint16_t Masked : 1;
146   uint16_t Strided : 1;
147   uint16_t Log2SEW : 3;
148   uint16_t LMUL : 3;
149   uint16_t Pseudo;
150 };
151 
152 struct VSXSEGPseudo {
153   uint16_t NF : 4;
154   uint16_t Masked : 1;
155   uint16_t Ordered : 1;
156   uint16_t Log2SEW : 3;
157   uint16_t LMUL : 3;
158   uint16_t IndexLMUL : 3;
159   uint16_t Pseudo;
160 };
161 
162 struct VLEPseudo {
163   uint16_t Masked : 1;
164   uint16_t IsTU : 1;
165   uint16_t Strided : 1;
166   uint16_t FF : 1;
167   uint16_t Log2SEW : 3;
168   uint16_t LMUL : 3;
169   uint16_t Pseudo;
170 };
171 
172 struct VSEPseudo {
173   uint16_t Masked :1;
174   uint16_t Strided : 1;
175   uint16_t Log2SEW : 3;
176   uint16_t LMUL : 3;
177   uint16_t Pseudo;
178 };
179 
180 struct VLX_VSXPseudo {
181   uint16_t Masked : 1;
182   uint16_t IsTU : 1;
183   uint16_t Ordered : 1;
184   uint16_t Log2SEW : 3;
185   uint16_t LMUL : 3;
186   uint16_t IndexLMUL : 3;
187   uint16_t Pseudo;
188 };
189 
190 #define GET_RISCVVSSEGTable_DECL
191 #define GET_RISCVVLSEGTable_DECL
192 #define GET_RISCVVLXSEGTable_DECL
193 #define GET_RISCVVSXSEGTable_DECL
194 #define GET_RISCVVLETable_DECL
195 #define GET_RISCVVSETable_DECL
196 #define GET_RISCVVLXTable_DECL
197 #define GET_RISCVVSXTable_DECL
198 #include "RISCVGenSearchableTables.inc"
199 } // namespace RISCV
200 
201 } // namespace llvm
202 
203 #endif
204