xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/VE/VEISelDAGToDAG.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 
1381ad6265SDimitry Andric #include "VE.h"
14480093f4SDimitry Andric #include "VETargetMachine.h"
15480093f4SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
16480093f4SDimitry Andric #include "llvm/CodeGen/SelectionDAGISel.h"
17480093f4SDimitry Andric #include "llvm/IR/Intrinsics.h"
18480093f4SDimitry Andric #include "llvm/Support/Debug.h"
19480093f4SDimitry Andric #include "llvm/Support/ErrorHandling.h"
20480093f4SDimitry Andric #include "llvm/Support/raw_ostream.h"
21480093f4SDimitry Andric using namespace llvm;
22480093f4SDimitry Andric 
23bdd1243dSDimitry Andric #define DEBUG_TYPE "ve-isel"
24bdd1243dSDimitry Andric #define PASS_NAME "VE DAG->DAG Pattern Instruction Selection"
255ffd83dbSDimitry Andric 
26480093f4SDimitry Andric //===--------------------------------------------------------------------===//
27480093f4SDimitry Andric /// VEDAGToDAGISel - VE specific code to select VE machine
28480093f4SDimitry Andric /// instructions for SelectionDAG operations.
29480093f4SDimitry Andric ///
30480093f4SDimitry Andric namespace {
31480093f4SDimitry Andric class VEDAGToDAGISel : public SelectionDAGISel {
32480093f4SDimitry Andric   /// Subtarget - Keep a pointer to the VE Subtarget around so that we can
33480093f4SDimitry Andric   /// make the right decision when generating code for different targets.
34480093f4SDimitry Andric   const VESubtarget *Subtarget;
35480093f4SDimitry Andric 
36480093f4SDimitry Andric public:
37bdd1243dSDimitry Andric   VEDAGToDAGISel() = delete;
38bdd1243dSDimitry Andric 
39*0fca6ea1SDimitry Andric   explicit VEDAGToDAGISel(VETargetMachine &tm) : SelectionDAGISel(tm) {}
40480093f4SDimitry Andric 
41480093f4SDimitry Andric   bool runOnMachineFunction(MachineFunction &MF) override {
42480093f4SDimitry Andric     Subtarget = &MF.getSubtarget<VESubtarget>();
43480093f4SDimitry Andric     return SelectionDAGISel::runOnMachineFunction(MF);
44480093f4SDimitry Andric   }
45480093f4SDimitry Andric 
46480093f4SDimitry Andric   void Select(SDNode *N) override;
47480093f4SDimitry Andric 
485ffd83dbSDimitry Andric   // Complex Pattern Selectors.
495ffd83dbSDimitry Andric   bool selectADDRrri(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset);
505ffd83dbSDimitry Andric   bool selectADDRrii(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset);
515ffd83dbSDimitry Andric   bool selectADDRzri(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset);
525ffd83dbSDimitry Andric   bool selectADDRzii(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset);
535ffd83dbSDimitry Andric   bool selectADDRri(SDValue N, SDValue &Base, SDValue &Offset);
54e8d8bef9SDimitry Andric   bool selectADDRzi(SDValue N, SDValue &Base, SDValue &Offset);
555ffd83dbSDimitry Andric 
56bdd1243dSDimitry Andric   /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
57bdd1243dSDimitry Andric   /// inline asm expressions.
58bdd1243dSDimitry Andric   bool SelectInlineAsmMemoryOperand(const SDValue &Op,
595f757f3fSDimitry Andric                                     InlineAsm::ConstraintCode ConstraintID,
60bdd1243dSDimitry Andric                                     std::vector<SDValue> &OutOps) override;
61480093f4SDimitry Andric 
62480093f4SDimitry Andric   // Include the pieces autogenerated from the target description.
63480093f4SDimitry Andric #include "VEGenDAGISel.inc"
645ffd83dbSDimitry Andric 
655ffd83dbSDimitry Andric private:
665ffd83dbSDimitry Andric   SDNode *getGlobalBaseReg();
675ffd83dbSDimitry Andric 
685ffd83dbSDimitry Andric   bool matchADDRrr(SDValue N, SDValue &Base, SDValue &Index);
695ffd83dbSDimitry Andric   bool matchADDRri(SDValue N, SDValue &Base, SDValue &Offset);
70480093f4SDimitry Andric };
71*0fca6ea1SDimitry Andric 
72*0fca6ea1SDimitry Andric class VEDAGToDAGISelLegacy : public SelectionDAGISelLegacy {
73*0fca6ea1SDimitry Andric public:
74*0fca6ea1SDimitry Andric   static char ID;
75*0fca6ea1SDimitry Andric   explicit VEDAGToDAGISelLegacy(VETargetMachine &tm)
76*0fca6ea1SDimitry Andric       : SelectionDAGISelLegacy(ID, std::make_unique<VEDAGToDAGISel>(tm)) {}
77*0fca6ea1SDimitry Andric };
78480093f4SDimitry Andric } // end anonymous namespace
79480093f4SDimitry Andric 
80*0fca6ea1SDimitry Andric char VEDAGToDAGISelLegacy::ID = 0;
81bdd1243dSDimitry Andric 
82*0fca6ea1SDimitry Andric INITIALIZE_PASS(VEDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false)
83bdd1243dSDimitry Andric 
845ffd83dbSDimitry Andric bool VEDAGToDAGISel::selectADDRrri(SDValue Addr, SDValue &Base, SDValue &Index,
855ffd83dbSDimitry Andric                                    SDValue &Offset) {
865ffd83dbSDimitry Andric   if (Addr.getOpcode() == ISD::FrameIndex)
875ffd83dbSDimitry Andric     return false;
885ffd83dbSDimitry Andric   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
895ffd83dbSDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalAddress ||
905ffd83dbSDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
915ffd83dbSDimitry Andric     return false; // direct calls.
925ffd83dbSDimitry Andric 
935ffd83dbSDimitry Andric   SDValue LHS, RHS;
945ffd83dbSDimitry Andric   if (matchADDRri(Addr, LHS, RHS)) {
955ffd83dbSDimitry Andric     if (matchADDRrr(LHS, Base, Index)) {
965ffd83dbSDimitry Andric       Offset = RHS;
975ffd83dbSDimitry Andric       return true;
985ffd83dbSDimitry Andric     }
995ffd83dbSDimitry Andric     // Return false to try selectADDRrii.
1005ffd83dbSDimitry Andric     return false;
1015ffd83dbSDimitry Andric   }
1025ffd83dbSDimitry Andric   if (matchADDRrr(Addr, LHS, RHS)) {
103e8d8bef9SDimitry Andric     // If the input is a pair of a frame-index and a register, move a
104e8d8bef9SDimitry Andric     // frame-index to LHS.  This generates MI with following operands.
105e8d8bef9SDimitry Andric     //    %dest, #FI, %reg, offset
106e8d8bef9SDimitry Andric     // In the eliminateFrameIndex, above MI is converted to the following.
107e8d8bef9SDimitry Andric     //    %dest, %fp, %reg, fi_offset + offset
108fe6060f1SDimitry Andric     if (isa<FrameIndexSDNode>(RHS))
109e8d8bef9SDimitry Andric       std::swap(LHS, RHS);
110e8d8bef9SDimitry Andric 
1115ffd83dbSDimitry Andric     if (matchADDRri(RHS, Index, Offset)) {
1125ffd83dbSDimitry Andric       Base = LHS;
1135ffd83dbSDimitry Andric       return true;
1145ffd83dbSDimitry Andric     }
1155ffd83dbSDimitry Andric     if (matchADDRri(LHS, Base, Offset)) {
1165ffd83dbSDimitry Andric       Index = RHS;
1175ffd83dbSDimitry Andric       return true;
1185ffd83dbSDimitry Andric     }
1195ffd83dbSDimitry Andric     Base = LHS;
1205ffd83dbSDimitry Andric     Index = RHS;
1215ffd83dbSDimitry Andric     Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
1225ffd83dbSDimitry Andric     return true;
1235ffd83dbSDimitry Andric   }
1245ffd83dbSDimitry Andric   return false; // Let the reg+imm(=0) pattern catch this!
1255ffd83dbSDimitry Andric }
1265ffd83dbSDimitry Andric 
1275ffd83dbSDimitry Andric bool VEDAGToDAGISel::selectADDRrii(SDValue Addr, SDValue &Base, SDValue &Index,
1285ffd83dbSDimitry Andric                                    SDValue &Offset) {
1295ffd83dbSDimitry Andric   if (matchADDRri(Addr, Base, Offset)) {
1305ffd83dbSDimitry Andric     Index = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
1315ffd83dbSDimitry Andric     return true;
1325ffd83dbSDimitry Andric   }
1335ffd83dbSDimitry Andric 
1345ffd83dbSDimitry Andric   Base = Addr;
1355ffd83dbSDimitry Andric   Index = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
1365ffd83dbSDimitry Andric   Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
1375ffd83dbSDimitry Andric   return true;
1385ffd83dbSDimitry Andric }
1395ffd83dbSDimitry Andric 
1405ffd83dbSDimitry Andric bool VEDAGToDAGISel::selectADDRzri(SDValue Addr, SDValue &Base, SDValue &Index,
1415ffd83dbSDimitry Andric                                    SDValue &Offset) {
1425ffd83dbSDimitry Andric   // Prefer ADDRrii.
1435ffd83dbSDimitry Andric   return false;
1445ffd83dbSDimitry Andric }
1455ffd83dbSDimitry Andric 
1465ffd83dbSDimitry Andric bool VEDAGToDAGISel::selectADDRzii(SDValue Addr, SDValue &Base, SDValue &Index,
1475ffd83dbSDimitry Andric                                    SDValue &Offset) {
148fe6060f1SDimitry Andric   if (isa<FrameIndexSDNode>(Addr))
1495ffd83dbSDimitry Andric     return false;
1505ffd83dbSDimitry Andric   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1515ffd83dbSDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalAddress ||
1525ffd83dbSDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
1535ffd83dbSDimitry Andric     return false; // direct calls.
1545ffd83dbSDimitry Andric 
155e8d8bef9SDimitry Andric   if (auto *CN = dyn_cast<ConstantSDNode>(Addr)) {
1565ffd83dbSDimitry Andric     if (isInt<32>(CN->getSExtValue())) {
1575ffd83dbSDimitry Andric       Base = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
1585ffd83dbSDimitry Andric       Index = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
1595ffd83dbSDimitry Andric       Offset =
1605ffd83dbSDimitry Andric           CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), MVT::i32);
1615ffd83dbSDimitry Andric       return true;
1625ffd83dbSDimitry Andric     }
1635ffd83dbSDimitry Andric   }
1645ffd83dbSDimitry Andric   return false;
1655ffd83dbSDimitry Andric }
1665ffd83dbSDimitry Andric 
1675ffd83dbSDimitry Andric bool VEDAGToDAGISel::selectADDRri(SDValue Addr, SDValue &Base,
1685ffd83dbSDimitry Andric                                   SDValue &Offset) {
1695ffd83dbSDimitry Andric   if (matchADDRri(Addr, Base, Offset))
1705ffd83dbSDimitry Andric     return true;
1715ffd83dbSDimitry Andric 
1725ffd83dbSDimitry Andric   Base = Addr;
1735ffd83dbSDimitry Andric   Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
1745ffd83dbSDimitry Andric   return true;
1755ffd83dbSDimitry Andric }
1765ffd83dbSDimitry Andric 
177e8d8bef9SDimitry Andric bool VEDAGToDAGISel::selectADDRzi(SDValue Addr, SDValue &Base,
178e8d8bef9SDimitry Andric                                   SDValue &Offset) {
179fe6060f1SDimitry Andric   if (isa<FrameIndexSDNode>(Addr))
180e8d8bef9SDimitry Andric     return false;
181e8d8bef9SDimitry Andric   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
182e8d8bef9SDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalAddress ||
183e8d8bef9SDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
184e8d8bef9SDimitry Andric     return false; // direct calls.
185e8d8bef9SDimitry Andric 
186e8d8bef9SDimitry Andric   if (auto *CN = dyn_cast<ConstantSDNode>(Addr)) {
187e8d8bef9SDimitry Andric     if (isInt<32>(CN->getSExtValue())) {
188e8d8bef9SDimitry Andric       Base = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
189e8d8bef9SDimitry Andric       Offset =
190e8d8bef9SDimitry Andric           CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), MVT::i32);
191e8d8bef9SDimitry Andric       return true;
192e8d8bef9SDimitry Andric     }
193e8d8bef9SDimitry Andric   }
194e8d8bef9SDimitry Andric   return false;
195e8d8bef9SDimitry Andric }
196e8d8bef9SDimitry Andric 
1975ffd83dbSDimitry Andric bool VEDAGToDAGISel::matchADDRrr(SDValue Addr, SDValue &Base, SDValue &Index) {
198fe6060f1SDimitry Andric   if (isa<FrameIndexSDNode>(Addr))
1995ffd83dbSDimitry Andric     return false;
2005ffd83dbSDimitry Andric   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
2015ffd83dbSDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalAddress ||
2025ffd83dbSDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
2035ffd83dbSDimitry Andric     return false; // direct calls.
2045ffd83dbSDimitry Andric 
2055ffd83dbSDimitry Andric   if (Addr.getOpcode() == ISD::ADD) {
2065ffd83dbSDimitry Andric     ; // Nothing to do here.
2075ffd83dbSDimitry Andric   } else if (Addr.getOpcode() == ISD::OR) {
2085ffd83dbSDimitry Andric     // We want to look through a transform in InstCombine and DAGCombiner that
2095ffd83dbSDimitry Andric     // turns 'add' into 'or', so we can treat this 'or' exactly like an 'add'.
2105ffd83dbSDimitry Andric     if (!CurDAG->haveNoCommonBitsSet(Addr.getOperand(0), Addr.getOperand(1)))
2115ffd83dbSDimitry Andric       return false;
2125ffd83dbSDimitry Andric   } else {
2135ffd83dbSDimitry Andric     return false;
2145ffd83dbSDimitry Andric   }
2155ffd83dbSDimitry Andric 
2165ffd83dbSDimitry Andric   if (Addr.getOperand(0).getOpcode() == VEISD::Lo ||
2175ffd83dbSDimitry Andric       Addr.getOperand(1).getOpcode() == VEISD::Lo)
2185ffd83dbSDimitry Andric     return false; // Let the LEASL patterns catch this!
2195ffd83dbSDimitry Andric 
2205ffd83dbSDimitry Andric   Base = Addr.getOperand(0);
2215ffd83dbSDimitry Andric   Index = Addr.getOperand(1);
2225ffd83dbSDimitry Andric   return true;
2235ffd83dbSDimitry Andric }
2245ffd83dbSDimitry Andric 
2255ffd83dbSDimitry Andric bool VEDAGToDAGISel::matchADDRri(SDValue Addr, SDValue &Base, SDValue &Offset) {
2265ffd83dbSDimitry Andric   auto AddrTy = Addr->getValueType(0);
2275ffd83dbSDimitry Andric   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
2285ffd83dbSDimitry Andric     Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), AddrTy);
2295ffd83dbSDimitry Andric     Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
2305ffd83dbSDimitry Andric     return true;
2315ffd83dbSDimitry Andric   }
2325ffd83dbSDimitry Andric   if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
2335ffd83dbSDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalAddress ||
2345ffd83dbSDimitry Andric       Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
2355ffd83dbSDimitry Andric     return false; // direct calls.
2365ffd83dbSDimitry Andric 
2375ffd83dbSDimitry Andric   if (CurDAG->isBaseWithConstantOffset(Addr)) {
2385ffd83dbSDimitry Andric     ConstantSDNode *CN = cast<ConstantSDNode>(Addr.getOperand(1));
2395ffd83dbSDimitry Andric     if (isInt<32>(CN->getSExtValue())) {
2405ffd83dbSDimitry Andric       if (FrameIndexSDNode *FIN =
2415ffd83dbSDimitry Andric               dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) {
2425ffd83dbSDimitry Andric         // Constant offset from frame ref.
2435ffd83dbSDimitry Andric         Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), AddrTy);
2445ffd83dbSDimitry Andric       } else {
2455ffd83dbSDimitry Andric         Base = Addr.getOperand(0);
2465ffd83dbSDimitry Andric       }
2475ffd83dbSDimitry Andric       Offset =
2485ffd83dbSDimitry Andric           CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), MVT::i32);
2495ffd83dbSDimitry Andric       return true;
2505ffd83dbSDimitry Andric     }
2515ffd83dbSDimitry Andric   }
2525ffd83dbSDimitry Andric   return false;
2535ffd83dbSDimitry Andric }
2545ffd83dbSDimitry Andric 
255480093f4SDimitry Andric void VEDAGToDAGISel::Select(SDNode *N) {
256480093f4SDimitry Andric   SDLoc dl(N);
257480093f4SDimitry Andric   if (N->isMachineOpcode()) {
258480093f4SDimitry Andric     N->setNodeId(-1);
259480093f4SDimitry Andric     return; // Already selected.
260480093f4SDimitry Andric   }
261480093f4SDimitry Andric 
2625ffd83dbSDimitry Andric   switch (N->getOpcode()) {
26381ad6265SDimitry Andric 
26481ad6265SDimitry Andric   // Late eliminate the LEGALAVL wrapper
26581ad6265SDimitry Andric   case VEISD::LEGALAVL:
26681ad6265SDimitry Andric     ReplaceNode(N, N->getOperand(0).getNode());
26781ad6265SDimitry Andric     return;
26881ad6265SDimitry Andric 
26981ad6265SDimitry Andric   // Lower (broadcast 1) and (broadcast 0) to VM[P]0
27081ad6265SDimitry Andric   case VEISD::VEC_BROADCAST: {
27181ad6265SDimitry Andric     MVT SplatResTy = N->getSimpleValueType(0);
27281ad6265SDimitry Andric     if (SplatResTy.getVectorElementType() != MVT::i1)
27381ad6265SDimitry Andric       break;
27481ad6265SDimitry Andric 
27581ad6265SDimitry Andric     // Constant non-zero broadcast.
27681ad6265SDimitry Andric     auto BConst = dyn_cast<ConstantSDNode>(N->getOperand(0));
27781ad6265SDimitry Andric     if (!BConst)
27881ad6265SDimitry Andric       break;
27981ad6265SDimitry Andric     bool BCTrueMask = (BConst->getSExtValue() != 0);
28081ad6265SDimitry Andric     if (!BCTrueMask)
28181ad6265SDimitry Andric       break;
28281ad6265SDimitry Andric 
28381ad6265SDimitry Andric     // Packed or non-packed.
28481ad6265SDimitry Andric     SDValue New;
28581ad6265SDimitry Andric     if (SplatResTy.getVectorNumElements() == StandardVectorWidth) {
28681ad6265SDimitry Andric       New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), SDLoc(N), VE::VM0,
28781ad6265SDimitry Andric                                    MVT::v256i1);
28881ad6265SDimitry Andric     } else if (SplatResTy.getVectorNumElements() == PackedVectorWidth) {
28981ad6265SDimitry Andric       New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), SDLoc(N), VE::VMP0,
29081ad6265SDimitry Andric                                    MVT::v512i1);
29181ad6265SDimitry Andric     } else
29281ad6265SDimitry Andric       break;
29381ad6265SDimitry Andric 
29481ad6265SDimitry Andric     // Replace.
29581ad6265SDimitry Andric     ReplaceNode(N, New.getNode());
29681ad6265SDimitry Andric     return;
29781ad6265SDimitry Andric   }
29881ad6265SDimitry Andric 
2995ffd83dbSDimitry Andric   case VEISD::GLOBAL_BASE_REG:
3005ffd83dbSDimitry Andric     ReplaceNode(N, getGlobalBaseReg());
3015ffd83dbSDimitry Andric     return;
3025ffd83dbSDimitry Andric   }
3035ffd83dbSDimitry Andric 
304480093f4SDimitry Andric   SelectCode(N);
305480093f4SDimitry Andric }
306480093f4SDimitry Andric 
307bdd1243dSDimitry Andric /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
308bdd1243dSDimitry Andric /// inline asm expressions.
3095f757f3fSDimitry Andric bool VEDAGToDAGISel::SelectInlineAsmMemoryOperand(
3105f757f3fSDimitry Andric     const SDValue &Op, InlineAsm::ConstraintCode ConstraintID,
311bdd1243dSDimitry Andric     std::vector<SDValue> &OutOps) {
312bdd1243dSDimitry Andric   SDValue Op0, Op1;
313bdd1243dSDimitry Andric   switch (ConstraintID) {
314bdd1243dSDimitry Andric   default:
315bdd1243dSDimitry Andric     llvm_unreachable("Unexpected asm memory constraint");
3165f757f3fSDimitry Andric   case InlineAsm::ConstraintCode::o:
3175f757f3fSDimitry Andric   case InlineAsm::ConstraintCode::m: // memory
318bdd1243dSDimitry Andric     // Try to match ADDRri since reg+imm style is safe for all VE instructions
319bdd1243dSDimitry Andric     // with a memory operand.
320bdd1243dSDimitry Andric     if (selectADDRri(Op, Op0, Op1)) {
321bdd1243dSDimitry Andric       OutOps.push_back(Op0);
322bdd1243dSDimitry Andric       OutOps.push_back(Op1);
323bdd1243dSDimitry Andric       return false;
324bdd1243dSDimitry Andric     }
325bdd1243dSDimitry Andric     // Otherwise, require the address to be in a register and immediate 0.
326bdd1243dSDimitry Andric     OutOps.push_back(Op);
327bdd1243dSDimitry Andric     OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32));
328bdd1243dSDimitry Andric     return false;
329bdd1243dSDimitry Andric   }
330bdd1243dSDimitry Andric   return true;
331bdd1243dSDimitry Andric }
332bdd1243dSDimitry Andric 
3335ffd83dbSDimitry Andric SDNode *VEDAGToDAGISel::getGlobalBaseReg() {
3345ffd83dbSDimitry Andric   Register GlobalBaseReg = Subtarget->getInstrInfo()->getGlobalBaseReg(MF);
3355ffd83dbSDimitry Andric   return CurDAG
3365ffd83dbSDimitry Andric       ->getRegister(GlobalBaseReg, TLI->getPointerTy(CurDAG->getDataLayout()))
3375ffd83dbSDimitry Andric       .getNode();
3385ffd83dbSDimitry Andric }
3395ffd83dbSDimitry Andric 
340480093f4SDimitry Andric /// createVEISelDag - This pass converts a legalized DAG into a
341480093f4SDimitry Andric /// VE-specific DAG, ready for instruction scheduling.
342480093f4SDimitry Andric ///
343480093f4SDimitry Andric FunctionPass *llvm::createVEISelDag(VETargetMachine &TM) {
344*0fca6ea1SDimitry Andric   return new VEDAGToDAGISelLegacy(TM);
345480093f4SDimitry Andric }
346