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 selectVLOp(SDValue N, SDValue &VL);
62 
63   bool selectVSplat(SDValue N, SDValue &SplatVal);
64   bool selectVSplatSimm5(SDValue N, SDValue &SplatVal);
65   bool selectVSplatUimm5(SDValue N, SDValue &SplatVal);
66   bool selectVSplatSimm5Plus1(SDValue N, SDValue &SplatVal);
67   bool selectVSplatSimm5Plus1NonZero(SDValue N, SDValue &SplatVal);
68 
69   bool selectRVVSimm5(SDValue N, unsigned Width, SDValue &Imm);
70   template <unsigned Width> bool selectRVVSimm5(SDValue N, SDValue &Imm) {
71     return selectRVVSimm5(N, Width, Imm);
72   }
73 
74   void addVectorLoadStoreOperands(SDNode *Node, unsigned SEWImm,
75                                   const SDLoc &DL, unsigned CurOp,
76                                   bool IsMasked, bool IsStridedOrIndexed,
77                                   SmallVectorImpl<SDValue> &Operands,
78                                   MVT *IndexVT = nullptr);
79 
80   void selectVLSEG(SDNode *Node, bool IsMasked, bool IsStrided);
81   void selectVLSEGFF(SDNode *Node, bool IsMasked);
82   void selectVLXSEG(SDNode *Node, bool IsMasked, bool IsOrdered);
83   void selectVSSEG(SDNode *Node, bool IsMasked, bool IsStrided);
84   void selectVSXSEG(SDNode *Node, bool IsMasked, bool IsOrdered);
85 
86 // Include the pieces autogenerated from the target description.
87 #include "RISCVGenDAGISel.inc"
88 
89 private:
90   void doPeepholeLoadStoreADDI();
91 };
92 
93 namespace RISCV {
94 struct VLSEGPseudo {
95   uint16_t NF : 4;
96   uint16_t Masked : 1;
97   uint16_t Strided : 1;
98   uint16_t FF : 1;
99   uint16_t Log2SEW : 3;
100   uint16_t LMUL : 3;
101   uint16_t Pseudo;
102 };
103 
104 struct VLXSEGPseudo {
105   uint16_t NF : 4;
106   uint16_t Masked : 1;
107   uint16_t Ordered : 1;
108   uint16_t Log2SEW : 3;
109   uint16_t LMUL : 3;
110   uint16_t IndexLMUL : 3;
111   uint16_t Pseudo;
112 };
113 
114 struct VSSEGPseudo {
115   uint16_t NF : 4;
116   uint16_t Masked : 1;
117   uint16_t Strided : 1;
118   uint16_t Log2SEW : 3;
119   uint16_t LMUL : 3;
120   uint16_t Pseudo;
121 };
122 
123 struct VSXSEGPseudo {
124   uint16_t NF : 4;
125   uint16_t Masked : 1;
126   uint16_t Ordered : 1;
127   uint16_t Log2SEW : 3;
128   uint16_t LMUL : 3;
129   uint16_t IndexLMUL : 3;
130   uint16_t Pseudo;
131 };
132 
133 struct VLEPseudo {
134   uint16_t Masked : 1;
135   uint16_t Strided : 1;
136   uint16_t FF : 1;
137   uint16_t Log2SEW : 3;
138   uint16_t LMUL : 3;
139   uint16_t Pseudo;
140 };
141 
142 struct VSEPseudo {
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 VLX_VSXPseudo {
151   uint16_t Masked : 1;
152   uint16_t Ordered : 1;
153   uint16_t Log2SEW : 3;
154   uint16_t LMUL : 3;
155   uint16_t IndexLMUL : 3;
156   uint16_t Pseudo;
157 };
158 
159 #define GET_RISCVVSSEGTable_DECL
160 #define GET_RISCVVLSEGTable_DECL
161 #define GET_RISCVVLXSEGTable_DECL
162 #define GET_RISCVVSXSEGTable_DECL
163 #define GET_RISCVVLETable_DECL
164 #define GET_RISCVVSETable_DECL
165 #define GET_RISCVVLXTable_DECL
166 #define GET_RISCVVSXTable_DECL
167 #include "RISCVGenSearchableTables.inc"
168 } // namespace RISCV
169 
170 } // namespace llvm
171 
172 #endif
173