xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/VE/VEISelDAGToDAG.cpp (revision 5ffd83dbcc34f10e07f6d3e968ae6365869615f4)
1480093f4SDimitry Andric //===-- VEISelDAGToDAG.cpp - A dag to dag inst selector for VE ------------===//
2480093f4SDimitry Andric //
3480093f4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4480093f4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5480093f4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6480093f4SDimitry Andric //
7480093f4SDimitry Andric //===----------------------------------------------------------------------===//
8480093f4SDimitry Andric //
9480093f4SDimitry Andric // This file defines an instruction selector for the VE target.
10480093f4SDimitry Andric //
11480093f4SDimitry Andric //===----------------------------------------------------------------------===//
12480093f4SDimitry Andric 
13480093f4SDimitry Andric #include "VETargetMachine.h"
14480093f4SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
15480093f4SDimitry Andric #include "llvm/CodeGen/SelectionDAGISel.h"
16480093f4SDimitry Andric #include "llvm/IR/Intrinsics.h"
17480093f4SDimitry Andric #include "llvm/Support/Debug.h"
18480093f4SDimitry Andric #include "llvm/Support/ErrorHandling.h"
19480093f4SDimitry Andric #include "llvm/Support/raw_ostream.h"
20480093f4SDimitry Andric using namespace llvm;
21480093f4SDimitry Andric 
22480093f4SDimitry Andric //===----------------------------------------------------------------------===//
23480093f4SDimitry Andric // Instruction Selector Implementation
24480093f4SDimitry Andric //===----------------------------------------------------------------------===//
25480093f4SDimitry Andric 
26*5ffd83dbSDimitry Andric /// Convert a DAG integer condition code to a VE ICC condition.
27*5ffd83dbSDimitry Andric inline static VECC::CondCode intCondCode2Icc(ISD::CondCode CC) {
28*5ffd83dbSDimitry Andric   switch (CC) {
29*5ffd83dbSDimitry Andric   default:
30*5ffd83dbSDimitry Andric     llvm_unreachable("Unknown integer condition code!");
31*5ffd83dbSDimitry Andric   case ISD::SETEQ:
32*5ffd83dbSDimitry Andric     return VECC::CC_IEQ;
33*5ffd83dbSDimitry Andric   case ISD::SETNE:
34*5ffd83dbSDimitry Andric     return VECC::CC_INE;
35*5ffd83dbSDimitry Andric   case ISD::SETLT:
36*5ffd83dbSDimitry Andric     return VECC::CC_IL;
37*5ffd83dbSDimitry Andric   case ISD::SETGT:
38*5ffd83dbSDimitry Andric     return VECC::CC_IG;
39*5ffd83dbSDimitry Andric   case ISD::SETLE:
40*5ffd83dbSDimitry Andric     return VECC::CC_ILE;
41*5ffd83dbSDimitry Andric   case ISD::SETGE:
42*5ffd83dbSDimitry Andric     return VECC::CC_IGE;
43*5ffd83dbSDimitry Andric   case ISD::SETULT:
44*5ffd83dbSDimitry Andric     return VECC::CC_IL;
45*5ffd83dbSDimitry Andric   case ISD::SETULE:
46*5ffd83dbSDimitry Andric     return VECC::CC_ILE;
47*5ffd83dbSDimitry Andric   case ISD::SETUGT:
48*5ffd83dbSDimitry Andric     return VECC::CC_IG;
49*5ffd83dbSDimitry Andric   case ISD::SETUGE:
50*5ffd83dbSDimitry Andric     return VECC::CC_IGE;
51*5ffd83dbSDimitry Andric   }
52*5ffd83dbSDimitry Andric }
53*5ffd83dbSDimitry Andric 
54*5ffd83dbSDimitry Andric /// Convert a DAG floating point condition code to a VE FCC condition.
55*5ffd83dbSDimitry Andric inline static VECC::CondCode fpCondCode2Fcc(ISD::CondCode CC) {
56*5ffd83dbSDimitry Andric   switch (CC) {
57*5ffd83dbSDimitry Andric   default:
58*5ffd83dbSDimitry Andric     llvm_unreachable("Unknown fp condition code!");
59*5ffd83dbSDimitry Andric   case ISD::SETFALSE:
60*5ffd83dbSDimitry Andric     return VECC::CC_AF;
61*5ffd83dbSDimitry Andric   case ISD::SETEQ:
62*5ffd83dbSDimitry Andric   case ISD::SETOEQ:
63*5ffd83dbSDimitry Andric     return VECC::CC_EQ;
64*5ffd83dbSDimitry Andric   case ISD::SETNE:
65*5ffd83dbSDimitry Andric   case ISD::SETONE:
66*5ffd83dbSDimitry Andric     return VECC::CC_NE;
67*5ffd83dbSDimitry Andric   case ISD::SETLT:
68*5ffd83dbSDimitry Andric   case ISD::SETOLT:
69*5ffd83dbSDimitry Andric     return VECC::CC_L;
70*5ffd83dbSDimitry Andric   case ISD::SETGT:
71*5ffd83dbSDimitry Andric   case ISD::SETOGT:
72*5ffd83dbSDimitry Andric     return VECC::CC_G;
73*5ffd83dbSDimitry Andric   case ISD::SETLE:
74*5ffd83dbSDimitry Andric   case ISD::SETOLE:
75*5ffd83dbSDimitry Andric     return VECC::CC_LE;
76*5ffd83dbSDimitry Andric   case ISD::SETGE:
77*5ffd83dbSDimitry Andric   case ISD::SETOGE:
78*5ffd83dbSDimitry Andric     return VECC::CC_GE;
79*5ffd83dbSDimitry Andric   case ISD::SETO:
80*5ffd83dbSDimitry Andric     return VECC::CC_NUM;
81*5ffd83dbSDimitry Andric   case ISD::SETUO:
82*5ffd83dbSDimitry Andric     return VECC::CC_NAN;
83*5ffd83dbSDimitry Andric   case ISD::SETUEQ:
84*5ffd83dbSDimitry Andric     return VECC::CC_EQNAN;
85*5ffd83dbSDimitry Andric   case ISD::SETUNE:
86*5ffd83dbSDimitry Andric     return VECC::CC_NENAN;
87*5ffd83dbSDimitry Andric   case ISD::SETULT:
88*5ffd83dbSDimitry Andric     return VECC::CC_LNAN;
89*5ffd83dbSDimitry Andric   case ISD::SETUGT:
90*5ffd83dbSDimitry Andric     return VECC::CC_GNAN;
91*5ffd83dbSDimitry Andric   case ISD::SETULE:
92*5ffd83dbSDimitry Andric     return VECC::CC_LENAN;
93*5ffd83dbSDimitry Andric   case ISD::SETUGE:
94*5ffd83dbSDimitry Andric     return VECC::CC_GENAN;
95*5ffd83dbSDimitry Andric   case ISD::SETTRUE:
96*5ffd83dbSDimitry Andric     return VECC::CC_AT;
97*5ffd83dbSDimitry Andric   }
98*5ffd83dbSDimitry Andric }
99*5ffd83dbSDimitry Andric 
100*5ffd83dbSDimitry Andric /// getImmVal - get immediate representation of integer value
101*5ffd83dbSDimitry Andric inline static uint64_t getImmVal(const ConstantSDNode *N) {
102*5ffd83dbSDimitry Andric   return N->getSExtValue();
103*5ffd83dbSDimitry Andric }
104*5ffd83dbSDimitry Andric 
105*5ffd83dbSDimitry Andric /// getFpImmVal - get immediate representation of floating point value
106*5ffd83dbSDimitry Andric inline static uint64_t getFpImmVal(const ConstantFPSDNode *N) {
107*5ffd83dbSDimitry Andric   const APInt &Imm = N->getValueAPF().bitcastToAPInt();
108*5ffd83dbSDimitry Andric   uint64_t Val = Imm.getZExtValue();
109*5ffd83dbSDimitry Andric   if (Imm.getBitWidth() == 32) {
110*5ffd83dbSDimitry Andric     // Immediate value of float place places at higher bits on VE.
111*5ffd83dbSDimitry Andric     Val <<= 32;
112*5ffd83dbSDimitry Andric   }
113*5ffd83dbSDimitry Andric   return Val;
114*5ffd83dbSDimitry Andric }
115*5ffd83dbSDimitry Andric 
116*5ffd83dbSDimitry Andric /// convMImmVal - Convert a mimm integer immediate value to target immediate.
117*5ffd83dbSDimitry Andric inline static uint64_t convMImmVal(uint64_t Val) {
118*5ffd83dbSDimitry Andric   if (Val == 0)
119*5ffd83dbSDimitry Andric     return 0; // (0)1
120*5ffd83dbSDimitry Andric   if (Val & (1UL << 63))
121*5ffd83dbSDimitry Andric     return countLeadingOnes(Val);       // (m)1
122*5ffd83dbSDimitry Andric   return countLeadingZeros(Val) | 0x40; // (m)0
123*5ffd83dbSDimitry Andric }
124*5ffd83dbSDimitry Andric 
125480093f4SDimitry Andric //===--------------------------------------------------------------------===//
126480093f4SDimitry Andric /// VEDAGToDAGISel - VE specific code to select VE machine
127480093f4SDimitry Andric /// instructions for SelectionDAG operations.
128480093f4SDimitry Andric ///
129480093f4SDimitry Andric namespace {
130480093f4SDimitry Andric class VEDAGToDAGISel : public SelectionDAGISel {
131480093f4SDimitry Andric   /// Subtarget - Keep a pointer to the VE Subtarget around so that we can
132480093f4SDimitry Andric   /// make the right decision when generating code for different targets.
133480093f4SDimitry Andric   const VESubtarget *Subtarget;
134480093f4SDimitry Andric 
135480093f4SDimitry Andric public:
136480093f4SDimitry Andric   explicit VEDAGToDAGISel(VETargetMachine &tm) : SelectionDAGISel(tm) {}
137480093f4SDimitry Andric 
138480093f4SDimitry Andric   bool runOnMachineFunction(MachineFunction &MF) override {
139480093f4SDimitry Andric     Subtarget = &MF.getSubtarget<VESubtarget>();
140480093f4SDimitry Andric     return SelectionDAGISel::runOnMachineFunction(MF);
141480093f4SDimitry Andric   }
142480093f4SDimitry Andric 
143480093f4SDimitry Andric   void Select(SDNode *N) override;
144480093f4SDimitry Andric 
145*5ffd83dbSDimitry Andric   // Complex Pattern Selectors.
146*5ffd83dbSDimitry Andric   bool selectADDRrri(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset);
147*5ffd83dbSDimitry Andric   bool selectADDRrii(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset);
148*5ffd83dbSDimitry Andric   bool selectADDRzri(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset);
149*5ffd83dbSDimitry Andric   bool selectADDRzii(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset);
150*5ffd83dbSDimitry Andric   bool selectADDRri(SDValue N, SDValue &Base, SDValue &Offset);
151*5ffd83dbSDimitry Andric 
152480093f4SDimitry Andric   StringRef getPassName() const override {
153480093f4SDimitry Andric     return "VE DAG->DAG Pattern Instruction Selection";
154480093f4SDimitry Andric   }
155480093f4SDimitry Andric 
156480093f4SDimitry Andric   // Include the pieces autogenerated from the target description.
157480093f4SDimitry Andric #include "VEGenDAGISel.inc"
158*5ffd83dbSDimitry Andric 
159*5ffd83dbSDimitry Andric private:
160*5ffd83dbSDimitry Andric   SDNode *getGlobalBaseReg();
161*5ffd83dbSDimitry Andric 
162*5ffd83dbSDimitry Andric   bool matchADDRrr(SDValue N, SDValue &Base, SDValue &Index);
163*5ffd83dbSDimitry Andric   bool matchADDRri(SDValue N, SDValue &Base, SDValue &Offset);
164480093f4SDimitry Andric };
165480093f4SDimitry Andric } // end anonymous namespace
166480093f4SDimitry Andric 
167*5ffd83dbSDimitry Andric bool VEDAGToDAGISel::selectADDRrri(SDValue Addr, SDValue &Base, SDValue &Index,
168*5ffd83dbSDimitry Andric                                    SDValue &Offset) {
169*5ffd83dbSDimitry Andric   if (Addr.getOpcode() == ISD::FrameIndex)
170*5ffd83dbSDimitry Andric     return false;
171*5ffd83dbSDimitry Andric   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
172*5ffd83dbSDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalAddress ||
173*5ffd83dbSDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
174*5ffd83dbSDimitry Andric     return false; // direct calls.
175*5ffd83dbSDimitry Andric 
176*5ffd83dbSDimitry Andric   SDValue LHS, RHS;
177*5ffd83dbSDimitry Andric   if (matchADDRri(Addr, LHS, RHS)) {
178*5ffd83dbSDimitry Andric     if (matchADDRrr(LHS, Base, Index)) {
179*5ffd83dbSDimitry Andric       Offset = RHS;
180*5ffd83dbSDimitry Andric       return true;
181*5ffd83dbSDimitry Andric     }
182*5ffd83dbSDimitry Andric     // Return false to try selectADDRrii.
183*5ffd83dbSDimitry Andric     return false;
184*5ffd83dbSDimitry Andric   }
185*5ffd83dbSDimitry Andric   if (matchADDRrr(Addr, LHS, RHS)) {
186*5ffd83dbSDimitry Andric     if (matchADDRri(RHS, Index, Offset)) {
187*5ffd83dbSDimitry Andric       Base = LHS;
188*5ffd83dbSDimitry Andric       return true;
189*5ffd83dbSDimitry Andric     }
190*5ffd83dbSDimitry Andric     if (matchADDRri(LHS, Base, Offset)) {
191*5ffd83dbSDimitry Andric       Index = RHS;
192*5ffd83dbSDimitry Andric       return true;
193*5ffd83dbSDimitry Andric     }
194*5ffd83dbSDimitry Andric     Base = LHS;
195*5ffd83dbSDimitry Andric     Index = RHS;
196*5ffd83dbSDimitry Andric     Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
197*5ffd83dbSDimitry Andric     return true;
198*5ffd83dbSDimitry Andric   }
199*5ffd83dbSDimitry Andric   return false; // Let the reg+imm(=0) pattern catch this!
200*5ffd83dbSDimitry Andric }
201*5ffd83dbSDimitry Andric 
202*5ffd83dbSDimitry Andric bool VEDAGToDAGISel::selectADDRrii(SDValue Addr, SDValue &Base, SDValue &Index,
203*5ffd83dbSDimitry Andric                                    SDValue &Offset) {
204*5ffd83dbSDimitry Andric   if (matchADDRri(Addr, Base, Offset)) {
205*5ffd83dbSDimitry Andric     Index = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
206*5ffd83dbSDimitry Andric     return true;
207*5ffd83dbSDimitry Andric   }
208*5ffd83dbSDimitry Andric 
209*5ffd83dbSDimitry Andric   Base = Addr;
210*5ffd83dbSDimitry Andric   Index = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
211*5ffd83dbSDimitry Andric   Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
212*5ffd83dbSDimitry Andric   return true;
213*5ffd83dbSDimitry Andric }
214*5ffd83dbSDimitry Andric 
215*5ffd83dbSDimitry Andric bool VEDAGToDAGISel::selectADDRzri(SDValue Addr, SDValue &Base, SDValue &Index,
216*5ffd83dbSDimitry Andric                                    SDValue &Offset) {
217*5ffd83dbSDimitry Andric   // Prefer ADDRrii.
218*5ffd83dbSDimitry Andric   return false;
219*5ffd83dbSDimitry Andric }
220*5ffd83dbSDimitry Andric 
221*5ffd83dbSDimitry Andric bool VEDAGToDAGISel::selectADDRzii(SDValue Addr, SDValue &Base, SDValue &Index,
222*5ffd83dbSDimitry Andric                                    SDValue &Offset) {
223*5ffd83dbSDimitry Andric   if (dyn_cast<FrameIndexSDNode>(Addr)) {
224*5ffd83dbSDimitry Andric     return false;
225*5ffd83dbSDimitry Andric   }
226*5ffd83dbSDimitry Andric   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
227*5ffd83dbSDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalAddress ||
228*5ffd83dbSDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
229*5ffd83dbSDimitry Andric     return false; // direct calls.
230*5ffd83dbSDimitry Andric 
231*5ffd83dbSDimitry Andric   if (ConstantSDNode *CN = cast<ConstantSDNode>(Addr)) {
232*5ffd83dbSDimitry Andric     if (isInt<32>(CN->getSExtValue())) {
233*5ffd83dbSDimitry Andric       Base = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
234*5ffd83dbSDimitry Andric       Index = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
235*5ffd83dbSDimitry Andric       Offset =
236*5ffd83dbSDimitry Andric           CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), MVT::i32);
237*5ffd83dbSDimitry Andric       return true;
238*5ffd83dbSDimitry Andric     }
239*5ffd83dbSDimitry Andric   }
240*5ffd83dbSDimitry Andric   return false;
241*5ffd83dbSDimitry Andric }
242*5ffd83dbSDimitry Andric 
243*5ffd83dbSDimitry Andric bool VEDAGToDAGISel::selectADDRri(SDValue Addr, SDValue &Base,
244*5ffd83dbSDimitry Andric                                   SDValue &Offset) {
245*5ffd83dbSDimitry Andric   if (matchADDRri(Addr, Base, Offset))
246*5ffd83dbSDimitry Andric     return true;
247*5ffd83dbSDimitry Andric 
248*5ffd83dbSDimitry Andric   Base = Addr;
249*5ffd83dbSDimitry Andric   Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
250*5ffd83dbSDimitry Andric   return true;
251*5ffd83dbSDimitry Andric }
252*5ffd83dbSDimitry Andric 
253*5ffd83dbSDimitry Andric bool VEDAGToDAGISel::matchADDRrr(SDValue Addr, SDValue &Base, SDValue &Index) {
254*5ffd83dbSDimitry Andric   if (dyn_cast<FrameIndexSDNode>(Addr))
255*5ffd83dbSDimitry Andric     return false;
256*5ffd83dbSDimitry Andric   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
257*5ffd83dbSDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalAddress ||
258*5ffd83dbSDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
259*5ffd83dbSDimitry Andric     return false; // direct calls.
260*5ffd83dbSDimitry Andric 
261*5ffd83dbSDimitry Andric   if (Addr.getOpcode() == ISD::ADD) {
262*5ffd83dbSDimitry Andric     ; // Nothing to do here.
263*5ffd83dbSDimitry Andric   } else if (Addr.getOpcode() == ISD::OR) {
264*5ffd83dbSDimitry Andric     // We want to look through a transform in InstCombine and DAGCombiner that
265*5ffd83dbSDimitry Andric     // turns 'add' into 'or', so we can treat this 'or' exactly like an 'add'.
266*5ffd83dbSDimitry Andric     if (!CurDAG->haveNoCommonBitsSet(Addr.getOperand(0), Addr.getOperand(1)))
267*5ffd83dbSDimitry Andric       return false;
268*5ffd83dbSDimitry Andric   } else {
269*5ffd83dbSDimitry Andric     return false;
270*5ffd83dbSDimitry Andric   }
271*5ffd83dbSDimitry Andric 
272*5ffd83dbSDimitry Andric   if (Addr.getOperand(0).getOpcode() == VEISD::Lo ||
273*5ffd83dbSDimitry Andric       Addr.getOperand(1).getOpcode() == VEISD::Lo)
274*5ffd83dbSDimitry Andric     return false; // Let the LEASL patterns catch this!
275*5ffd83dbSDimitry Andric 
276*5ffd83dbSDimitry Andric   Base = Addr.getOperand(0);
277*5ffd83dbSDimitry Andric   Index = Addr.getOperand(1);
278*5ffd83dbSDimitry Andric   return true;
279*5ffd83dbSDimitry Andric }
280*5ffd83dbSDimitry Andric 
281*5ffd83dbSDimitry Andric bool VEDAGToDAGISel::matchADDRri(SDValue Addr, SDValue &Base, SDValue &Offset) {
282*5ffd83dbSDimitry Andric   auto AddrTy = Addr->getValueType(0);
283*5ffd83dbSDimitry Andric   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
284*5ffd83dbSDimitry Andric     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), AddrTy);
285*5ffd83dbSDimitry Andric     Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
286*5ffd83dbSDimitry Andric     return true;
287*5ffd83dbSDimitry Andric   }
288*5ffd83dbSDimitry Andric   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
289*5ffd83dbSDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalAddress ||
290*5ffd83dbSDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
291*5ffd83dbSDimitry Andric     return false; // direct calls.
292*5ffd83dbSDimitry Andric 
293*5ffd83dbSDimitry Andric   if (CurDAG->isBaseWithConstantOffset(Addr)) {
294*5ffd83dbSDimitry Andric     ConstantSDNode *CN = cast<ConstantSDNode>(Addr.getOperand(1));
295*5ffd83dbSDimitry Andric     if (isInt<32>(CN->getSExtValue())) {
296*5ffd83dbSDimitry Andric       if (FrameIndexSDNode *FIN =
297*5ffd83dbSDimitry Andric               dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) {
298*5ffd83dbSDimitry Andric         // Constant offset from frame ref.
299*5ffd83dbSDimitry Andric         Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), AddrTy);
300*5ffd83dbSDimitry Andric       } else {
301*5ffd83dbSDimitry Andric         Base = Addr.getOperand(0);
302*5ffd83dbSDimitry Andric       }
303*5ffd83dbSDimitry Andric       Offset =
304*5ffd83dbSDimitry Andric           CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), MVT::i32);
305*5ffd83dbSDimitry Andric       return true;
306*5ffd83dbSDimitry Andric     }
307*5ffd83dbSDimitry Andric   }
308*5ffd83dbSDimitry Andric   return false;
309*5ffd83dbSDimitry Andric }
310*5ffd83dbSDimitry Andric 
311480093f4SDimitry Andric void VEDAGToDAGISel::Select(SDNode *N) {
312480093f4SDimitry Andric   SDLoc dl(N);
313480093f4SDimitry Andric   if (N->isMachineOpcode()) {
314480093f4SDimitry Andric     N->setNodeId(-1);
315480093f4SDimitry Andric     return; // Already selected.
316480093f4SDimitry Andric   }
317480093f4SDimitry Andric 
318*5ffd83dbSDimitry Andric   switch (N->getOpcode()) {
319*5ffd83dbSDimitry Andric   case VEISD::GLOBAL_BASE_REG:
320*5ffd83dbSDimitry Andric     ReplaceNode(N, getGlobalBaseReg());
321*5ffd83dbSDimitry Andric     return;
322*5ffd83dbSDimitry Andric   }
323*5ffd83dbSDimitry Andric 
324480093f4SDimitry Andric   SelectCode(N);
325480093f4SDimitry Andric }
326480093f4SDimitry Andric 
327*5ffd83dbSDimitry Andric SDNode *VEDAGToDAGISel::getGlobalBaseReg() {
328*5ffd83dbSDimitry Andric   Register GlobalBaseReg = Subtarget->getInstrInfo()->getGlobalBaseReg(MF);
329*5ffd83dbSDimitry Andric   return CurDAG
330*5ffd83dbSDimitry Andric       ->getRegister(GlobalBaseReg, TLI->getPointerTy(CurDAG->getDataLayout()))
331*5ffd83dbSDimitry Andric       .getNode();
332*5ffd83dbSDimitry Andric }
333*5ffd83dbSDimitry Andric 
334480093f4SDimitry Andric /// createVEISelDag - This pass converts a legalized DAG into a
335480093f4SDimitry Andric /// VE-specific DAG, ready for instruction scheduling.
336480093f4SDimitry Andric ///
337480093f4SDimitry Andric FunctionPass *llvm::createVEISelDag(VETargetMachine &TM) {
338480093f4SDimitry Andric   return new VEDAGToDAGISel(TM);
339480093f4SDimitry Andric }
340