xref: /freebsd/contrib/llvm-project/llvm/lib/Target/VE/VEISelDAGToDAG.cpp (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
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 
265ffd83dbSDimitry Andric /// Convert a DAG integer condition code to a VE ICC condition.
275ffd83dbSDimitry Andric inline static VECC::CondCode intCondCode2Icc(ISD::CondCode CC) {
285ffd83dbSDimitry Andric   switch (CC) {
295ffd83dbSDimitry Andric   default:
305ffd83dbSDimitry Andric     llvm_unreachable("Unknown integer condition code!");
315ffd83dbSDimitry Andric   case ISD::SETEQ:
325ffd83dbSDimitry Andric     return VECC::CC_IEQ;
335ffd83dbSDimitry Andric   case ISD::SETNE:
345ffd83dbSDimitry Andric     return VECC::CC_INE;
355ffd83dbSDimitry Andric   case ISD::SETLT:
365ffd83dbSDimitry Andric     return VECC::CC_IL;
375ffd83dbSDimitry Andric   case ISD::SETGT:
385ffd83dbSDimitry Andric     return VECC::CC_IG;
395ffd83dbSDimitry Andric   case ISD::SETLE:
405ffd83dbSDimitry Andric     return VECC::CC_ILE;
415ffd83dbSDimitry Andric   case ISD::SETGE:
425ffd83dbSDimitry Andric     return VECC::CC_IGE;
435ffd83dbSDimitry Andric   case ISD::SETULT:
445ffd83dbSDimitry Andric     return VECC::CC_IL;
455ffd83dbSDimitry Andric   case ISD::SETULE:
465ffd83dbSDimitry Andric     return VECC::CC_ILE;
475ffd83dbSDimitry Andric   case ISD::SETUGT:
485ffd83dbSDimitry Andric     return VECC::CC_IG;
495ffd83dbSDimitry Andric   case ISD::SETUGE:
505ffd83dbSDimitry Andric     return VECC::CC_IGE;
515ffd83dbSDimitry Andric   }
525ffd83dbSDimitry Andric }
535ffd83dbSDimitry Andric 
545ffd83dbSDimitry Andric /// Convert a DAG floating point condition code to a VE FCC condition.
555ffd83dbSDimitry Andric inline static VECC::CondCode fpCondCode2Fcc(ISD::CondCode CC) {
565ffd83dbSDimitry Andric   switch (CC) {
575ffd83dbSDimitry Andric   default:
585ffd83dbSDimitry Andric     llvm_unreachable("Unknown fp condition code!");
595ffd83dbSDimitry Andric   case ISD::SETFALSE:
605ffd83dbSDimitry Andric     return VECC::CC_AF;
615ffd83dbSDimitry Andric   case ISD::SETEQ:
625ffd83dbSDimitry Andric   case ISD::SETOEQ:
635ffd83dbSDimitry Andric     return VECC::CC_EQ;
645ffd83dbSDimitry Andric   case ISD::SETNE:
655ffd83dbSDimitry Andric   case ISD::SETONE:
665ffd83dbSDimitry Andric     return VECC::CC_NE;
675ffd83dbSDimitry Andric   case ISD::SETLT:
685ffd83dbSDimitry Andric   case ISD::SETOLT:
695ffd83dbSDimitry Andric     return VECC::CC_L;
705ffd83dbSDimitry Andric   case ISD::SETGT:
715ffd83dbSDimitry Andric   case ISD::SETOGT:
725ffd83dbSDimitry Andric     return VECC::CC_G;
735ffd83dbSDimitry Andric   case ISD::SETLE:
745ffd83dbSDimitry Andric   case ISD::SETOLE:
755ffd83dbSDimitry Andric     return VECC::CC_LE;
765ffd83dbSDimitry Andric   case ISD::SETGE:
775ffd83dbSDimitry Andric   case ISD::SETOGE:
785ffd83dbSDimitry Andric     return VECC::CC_GE;
795ffd83dbSDimitry Andric   case ISD::SETO:
805ffd83dbSDimitry Andric     return VECC::CC_NUM;
815ffd83dbSDimitry Andric   case ISD::SETUO:
825ffd83dbSDimitry Andric     return VECC::CC_NAN;
835ffd83dbSDimitry Andric   case ISD::SETUEQ:
845ffd83dbSDimitry Andric     return VECC::CC_EQNAN;
855ffd83dbSDimitry Andric   case ISD::SETUNE:
865ffd83dbSDimitry Andric     return VECC::CC_NENAN;
875ffd83dbSDimitry Andric   case ISD::SETULT:
885ffd83dbSDimitry Andric     return VECC::CC_LNAN;
895ffd83dbSDimitry Andric   case ISD::SETUGT:
905ffd83dbSDimitry Andric     return VECC::CC_GNAN;
915ffd83dbSDimitry Andric   case ISD::SETULE:
925ffd83dbSDimitry Andric     return VECC::CC_LENAN;
935ffd83dbSDimitry Andric   case ISD::SETUGE:
945ffd83dbSDimitry Andric     return VECC::CC_GENAN;
955ffd83dbSDimitry Andric   case ISD::SETTRUE:
965ffd83dbSDimitry Andric     return VECC::CC_AT;
975ffd83dbSDimitry Andric   }
985ffd83dbSDimitry Andric }
995ffd83dbSDimitry Andric 
1005ffd83dbSDimitry Andric /// getImmVal - get immediate representation of integer value
1015ffd83dbSDimitry Andric inline static uint64_t getImmVal(const ConstantSDNode *N) {
1025ffd83dbSDimitry Andric   return N->getSExtValue();
1035ffd83dbSDimitry Andric }
1045ffd83dbSDimitry Andric 
1055ffd83dbSDimitry Andric /// getFpImmVal - get immediate representation of floating point value
1065ffd83dbSDimitry Andric inline static uint64_t getFpImmVal(const ConstantFPSDNode *N) {
1075ffd83dbSDimitry Andric   const APInt &Imm = N->getValueAPF().bitcastToAPInt();
1085ffd83dbSDimitry Andric   uint64_t Val = Imm.getZExtValue();
1095ffd83dbSDimitry Andric   if (Imm.getBitWidth() == 32) {
1105ffd83dbSDimitry Andric     // Immediate value of float place places at higher bits on VE.
1115ffd83dbSDimitry Andric     Val <<= 32;
1125ffd83dbSDimitry Andric   }
1135ffd83dbSDimitry Andric   return Val;
1145ffd83dbSDimitry Andric }
1155ffd83dbSDimitry Andric 
116480093f4SDimitry Andric //===--------------------------------------------------------------------===//
117480093f4SDimitry Andric /// VEDAGToDAGISel - VE specific code to select VE machine
118480093f4SDimitry Andric /// instructions for SelectionDAG operations.
119480093f4SDimitry Andric ///
120480093f4SDimitry Andric namespace {
121480093f4SDimitry Andric class VEDAGToDAGISel : public SelectionDAGISel {
122480093f4SDimitry Andric   /// Subtarget - Keep a pointer to the VE Subtarget around so that we can
123480093f4SDimitry Andric   /// make the right decision when generating code for different targets.
124480093f4SDimitry Andric   const VESubtarget *Subtarget;
125480093f4SDimitry Andric 
126480093f4SDimitry Andric public:
127480093f4SDimitry Andric   explicit VEDAGToDAGISel(VETargetMachine &tm) : SelectionDAGISel(tm) {}
128480093f4SDimitry Andric 
129480093f4SDimitry Andric   bool runOnMachineFunction(MachineFunction &MF) override {
130480093f4SDimitry Andric     Subtarget = &MF.getSubtarget<VESubtarget>();
131480093f4SDimitry Andric     return SelectionDAGISel::runOnMachineFunction(MF);
132480093f4SDimitry Andric   }
133480093f4SDimitry Andric 
134480093f4SDimitry Andric   void Select(SDNode *N) override;
135480093f4SDimitry Andric 
1365ffd83dbSDimitry Andric   // Complex Pattern Selectors.
1375ffd83dbSDimitry Andric   bool selectADDRrri(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset);
1385ffd83dbSDimitry Andric   bool selectADDRrii(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset);
1395ffd83dbSDimitry Andric   bool selectADDRzri(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset);
1405ffd83dbSDimitry Andric   bool selectADDRzii(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset);
1415ffd83dbSDimitry Andric   bool selectADDRri(SDValue N, SDValue &Base, SDValue &Offset);
142*e8d8bef9SDimitry Andric   bool selectADDRzi(SDValue N, SDValue &Base, SDValue &Offset);
1435ffd83dbSDimitry Andric 
144480093f4SDimitry Andric   StringRef getPassName() const override {
145480093f4SDimitry Andric     return "VE DAG->DAG Pattern Instruction Selection";
146480093f4SDimitry Andric   }
147480093f4SDimitry Andric 
148480093f4SDimitry Andric   // Include the pieces autogenerated from the target description.
149480093f4SDimitry Andric #include "VEGenDAGISel.inc"
1505ffd83dbSDimitry Andric 
1515ffd83dbSDimitry Andric private:
1525ffd83dbSDimitry Andric   SDNode *getGlobalBaseReg();
1535ffd83dbSDimitry Andric 
1545ffd83dbSDimitry Andric   bool matchADDRrr(SDValue N, SDValue &Base, SDValue &Index);
1555ffd83dbSDimitry Andric   bool matchADDRri(SDValue N, SDValue &Base, SDValue &Offset);
156480093f4SDimitry Andric };
157480093f4SDimitry Andric } // end anonymous namespace
158480093f4SDimitry Andric 
1595ffd83dbSDimitry Andric bool VEDAGToDAGISel::selectADDRrri(SDValue Addr, SDValue &Base, SDValue &Index,
1605ffd83dbSDimitry Andric                                    SDValue &Offset) {
1615ffd83dbSDimitry Andric   if (Addr.getOpcode() == ISD::FrameIndex)
1625ffd83dbSDimitry Andric     return false;
1635ffd83dbSDimitry Andric   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1645ffd83dbSDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalAddress ||
1655ffd83dbSDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
1665ffd83dbSDimitry Andric     return false; // direct calls.
1675ffd83dbSDimitry Andric 
1685ffd83dbSDimitry Andric   SDValue LHS, RHS;
1695ffd83dbSDimitry Andric   if (matchADDRri(Addr, LHS, RHS)) {
1705ffd83dbSDimitry Andric     if (matchADDRrr(LHS, Base, Index)) {
1715ffd83dbSDimitry Andric       Offset = RHS;
1725ffd83dbSDimitry Andric       return true;
1735ffd83dbSDimitry Andric     }
1745ffd83dbSDimitry Andric     // Return false to try selectADDRrii.
1755ffd83dbSDimitry Andric     return false;
1765ffd83dbSDimitry Andric   }
1775ffd83dbSDimitry Andric   if (matchADDRrr(Addr, LHS, RHS)) {
178*e8d8bef9SDimitry Andric     // If the input is a pair of a frame-index and a register, move a
179*e8d8bef9SDimitry Andric     // frame-index to LHS.  This generates MI with following operands.
180*e8d8bef9SDimitry Andric     //    %dest, #FI, %reg, offset
181*e8d8bef9SDimitry Andric     // In the eliminateFrameIndex, above MI is converted to the following.
182*e8d8bef9SDimitry Andric     //    %dest, %fp, %reg, fi_offset + offset
183*e8d8bef9SDimitry Andric     if (dyn_cast<FrameIndexSDNode>(RHS))
184*e8d8bef9SDimitry Andric       std::swap(LHS, RHS);
185*e8d8bef9SDimitry Andric 
1865ffd83dbSDimitry Andric     if (matchADDRri(RHS, Index, Offset)) {
1875ffd83dbSDimitry Andric       Base = LHS;
1885ffd83dbSDimitry Andric       return true;
1895ffd83dbSDimitry Andric     }
1905ffd83dbSDimitry Andric     if (matchADDRri(LHS, Base, Offset)) {
1915ffd83dbSDimitry Andric       Index = RHS;
1925ffd83dbSDimitry Andric       return true;
1935ffd83dbSDimitry Andric     }
1945ffd83dbSDimitry Andric     Base = LHS;
1955ffd83dbSDimitry Andric     Index = RHS;
1965ffd83dbSDimitry Andric     Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
1975ffd83dbSDimitry Andric     return true;
1985ffd83dbSDimitry Andric   }
1995ffd83dbSDimitry Andric   return false; // Let the reg+imm(=0) pattern catch this!
2005ffd83dbSDimitry Andric }
2015ffd83dbSDimitry Andric 
2025ffd83dbSDimitry Andric bool VEDAGToDAGISel::selectADDRrii(SDValue Addr, SDValue &Base, SDValue &Index,
2035ffd83dbSDimitry Andric                                    SDValue &Offset) {
2045ffd83dbSDimitry Andric   if (matchADDRri(Addr, Base, Offset)) {
2055ffd83dbSDimitry Andric     Index = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
2065ffd83dbSDimitry Andric     return true;
2075ffd83dbSDimitry Andric   }
2085ffd83dbSDimitry Andric 
2095ffd83dbSDimitry Andric   Base = Addr;
2105ffd83dbSDimitry Andric   Index = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
2115ffd83dbSDimitry Andric   Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
2125ffd83dbSDimitry Andric   return true;
2135ffd83dbSDimitry Andric }
2145ffd83dbSDimitry Andric 
2155ffd83dbSDimitry Andric bool VEDAGToDAGISel::selectADDRzri(SDValue Addr, SDValue &Base, SDValue &Index,
2165ffd83dbSDimitry Andric                                    SDValue &Offset) {
2175ffd83dbSDimitry Andric   // Prefer ADDRrii.
2185ffd83dbSDimitry Andric   return false;
2195ffd83dbSDimitry Andric }
2205ffd83dbSDimitry Andric 
2215ffd83dbSDimitry Andric bool VEDAGToDAGISel::selectADDRzii(SDValue Addr, SDValue &Base, SDValue &Index,
2225ffd83dbSDimitry Andric                                    SDValue &Offset) {
2235ffd83dbSDimitry Andric   if (dyn_cast<FrameIndexSDNode>(Addr)) {
2245ffd83dbSDimitry Andric     return false;
2255ffd83dbSDimitry Andric   }
2265ffd83dbSDimitry Andric   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
2275ffd83dbSDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalAddress ||
2285ffd83dbSDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
2295ffd83dbSDimitry Andric     return false; // direct calls.
2305ffd83dbSDimitry Andric 
231*e8d8bef9SDimitry Andric   if (auto *CN = dyn_cast<ConstantSDNode>(Addr)) {
2325ffd83dbSDimitry Andric     if (isInt<32>(CN->getSExtValue())) {
2335ffd83dbSDimitry Andric       Base = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
2345ffd83dbSDimitry Andric       Index = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
2355ffd83dbSDimitry Andric       Offset =
2365ffd83dbSDimitry Andric           CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), MVT::i32);
2375ffd83dbSDimitry Andric       return true;
2385ffd83dbSDimitry Andric     }
2395ffd83dbSDimitry Andric   }
2405ffd83dbSDimitry Andric   return false;
2415ffd83dbSDimitry Andric }
2425ffd83dbSDimitry Andric 
2435ffd83dbSDimitry Andric bool VEDAGToDAGISel::selectADDRri(SDValue Addr, SDValue &Base,
2445ffd83dbSDimitry Andric                                   SDValue &Offset) {
2455ffd83dbSDimitry Andric   if (matchADDRri(Addr, Base, Offset))
2465ffd83dbSDimitry Andric     return true;
2475ffd83dbSDimitry Andric 
2485ffd83dbSDimitry Andric   Base = Addr;
2495ffd83dbSDimitry Andric   Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
2505ffd83dbSDimitry Andric   return true;
2515ffd83dbSDimitry Andric }
2525ffd83dbSDimitry Andric 
253*e8d8bef9SDimitry Andric bool VEDAGToDAGISel::selectADDRzi(SDValue Addr, SDValue &Base,
254*e8d8bef9SDimitry Andric                                   SDValue &Offset) {
255*e8d8bef9SDimitry Andric   if (dyn_cast<FrameIndexSDNode>(Addr))
256*e8d8bef9SDimitry Andric     return false;
257*e8d8bef9SDimitry Andric   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
258*e8d8bef9SDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalAddress ||
259*e8d8bef9SDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
260*e8d8bef9SDimitry Andric     return false; // direct calls.
261*e8d8bef9SDimitry Andric 
262*e8d8bef9SDimitry Andric   if (auto *CN = dyn_cast<ConstantSDNode>(Addr)) {
263*e8d8bef9SDimitry Andric     if (isInt<32>(CN->getSExtValue())) {
264*e8d8bef9SDimitry Andric       Base = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
265*e8d8bef9SDimitry Andric       Offset =
266*e8d8bef9SDimitry Andric           CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), MVT::i32);
267*e8d8bef9SDimitry Andric       return true;
268*e8d8bef9SDimitry Andric     }
269*e8d8bef9SDimitry Andric   }
270*e8d8bef9SDimitry Andric   return false;
271*e8d8bef9SDimitry Andric }
272*e8d8bef9SDimitry Andric 
2735ffd83dbSDimitry Andric bool VEDAGToDAGISel::matchADDRrr(SDValue Addr, SDValue &Base, SDValue &Index) {
2745ffd83dbSDimitry Andric   if (dyn_cast<FrameIndexSDNode>(Addr))
2755ffd83dbSDimitry Andric     return false;
2765ffd83dbSDimitry Andric   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
2775ffd83dbSDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalAddress ||
2785ffd83dbSDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
2795ffd83dbSDimitry Andric     return false; // direct calls.
2805ffd83dbSDimitry Andric 
2815ffd83dbSDimitry Andric   if (Addr.getOpcode() == ISD::ADD) {
2825ffd83dbSDimitry Andric     ; // Nothing to do here.
2835ffd83dbSDimitry Andric   } else if (Addr.getOpcode() == ISD::OR) {
2845ffd83dbSDimitry Andric     // We want to look through a transform in InstCombine and DAGCombiner that
2855ffd83dbSDimitry Andric     // turns 'add' into 'or', so we can treat this 'or' exactly like an 'add'.
2865ffd83dbSDimitry Andric     if (!CurDAG->haveNoCommonBitsSet(Addr.getOperand(0), Addr.getOperand(1)))
2875ffd83dbSDimitry Andric       return false;
2885ffd83dbSDimitry Andric   } else {
2895ffd83dbSDimitry Andric     return false;
2905ffd83dbSDimitry Andric   }
2915ffd83dbSDimitry Andric 
2925ffd83dbSDimitry Andric   if (Addr.getOperand(0).getOpcode() == VEISD::Lo ||
2935ffd83dbSDimitry Andric       Addr.getOperand(1).getOpcode() == VEISD::Lo)
2945ffd83dbSDimitry Andric     return false; // Let the LEASL patterns catch this!
2955ffd83dbSDimitry Andric 
2965ffd83dbSDimitry Andric   Base = Addr.getOperand(0);
2975ffd83dbSDimitry Andric   Index = Addr.getOperand(1);
2985ffd83dbSDimitry Andric   return true;
2995ffd83dbSDimitry Andric }
3005ffd83dbSDimitry Andric 
3015ffd83dbSDimitry Andric bool VEDAGToDAGISel::matchADDRri(SDValue Addr, SDValue &Base, SDValue &Offset) {
3025ffd83dbSDimitry Andric   auto AddrTy = Addr->getValueType(0);
3035ffd83dbSDimitry Andric   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
3045ffd83dbSDimitry Andric     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), AddrTy);
3055ffd83dbSDimitry Andric     Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
3065ffd83dbSDimitry Andric     return true;
3075ffd83dbSDimitry Andric   }
3085ffd83dbSDimitry Andric   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
3095ffd83dbSDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalAddress ||
3105ffd83dbSDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
3115ffd83dbSDimitry Andric     return false; // direct calls.
3125ffd83dbSDimitry Andric 
3135ffd83dbSDimitry Andric   if (CurDAG->isBaseWithConstantOffset(Addr)) {
3145ffd83dbSDimitry Andric     ConstantSDNode *CN = cast<ConstantSDNode>(Addr.getOperand(1));
3155ffd83dbSDimitry Andric     if (isInt<32>(CN->getSExtValue())) {
3165ffd83dbSDimitry Andric       if (FrameIndexSDNode *FIN =
3175ffd83dbSDimitry Andric               dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) {
3185ffd83dbSDimitry Andric         // Constant offset from frame ref.
3195ffd83dbSDimitry Andric         Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), AddrTy);
3205ffd83dbSDimitry Andric       } else {
3215ffd83dbSDimitry Andric         Base = Addr.getOperand(0);
3225ffd83dbSDimitry Andric       }
3235ffd83dbSDimitry Andric       Offset =
3245ffd83dbSDimitry Andric           CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), MVT::i32);
3255ffd83dbSDimitry Andric       return true;
3265ffd83dbSDimitry Andric     }
3275ffd83dbSDimitry Andric   }
3285ffd83dbSDimitry Andric   return false;
3295ffd83dbSDimitry Andric }
3305ffd83dbSDimitry Andric 
331480093f4SDimitry Andric void VEDAGToDAGISel::Select(SDNode *N) {
332480093f4SDimitry Andric   SDLoc dl(N);
333480093f4SDimitry Andric   if (N->isMachineOpcode()) {
334480093f4SDimitry Andric     N->setNodeId(-1);
335480093f4SDimitry Andric     return; // Already selected.
336480093f4SDimitry Andric   }
337480093f4SDimitry Andric 
3385ffd83dbSDimitry Andric   switch (N->getOpcode()) {
3395ffd83dbSDimitry Andric   case VEISD::GLOBAL_BASE_REG:
3405ffd83dbSDimitry Andric     ReplaceNode(N, getGlobalBaseReg());
3415ffd83dbSDimitry Andric     return;
3425ffd83dbSDimitry Andric   }
3435ffd83dbSDimitry Andric 
344480093f4SDimitry Andric   SelectCode(N);
345480093f4SDimitry Andric }
346480093f4SDimitry Andric 
3475ffd83dbSDimitry Andric SDNode *VEDAGToDAGISel::getGlobalBaseReg() {
3485ffd83dbSDimitry Andric   Register GlobalBaseReg = Subtarget->getInstrInfo()->getGlobalBaseReg(MF);
3495ffd83dbSDimitry Andric   return CurDAG
3505ffd83dbSDimitry Andric       ->getRegister(GlobalBaseReg, TLI->getPointerTy(CurDAG->getDataLayout()))
3515ffd83dbSDimitry Andric       .getNode();
3525ffd83dbSDimitry Andric }
3535ffd83dbSDimitry Andric 
354480093f4SDimitry Andric /// createVEISelDag - This pass converts a legalized DAG into a
355480093f4SDimitry Andric /// VE-specific DAG, ready for instruction scheduling.
356480093f4SDimitry Andric ///
357480093f4SDimitry Andric FunctionPass *llvm::createVEISelDag(VETargetMachine &TM) {
358480093f4SDimitry Andric   return new VEDAGToDAGISel(TM);
359480093f4SDimitry Andric }
360