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
VEDAGToDAGISel(VETargetMachine & tm)39*0fca6ea1SDimitry Andric explicit VEDAGToDAGISel(VETargetMachine &tm) : SelectionDAGISel(tm) {}
40480093f4SDimitry Andric
runOnMachineFunction(MachineFunction & MF)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;
VEDAGToDAGISelLegacy(VETargetMachine & tm)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
INITIALIZE_PASS(VEDAGToDAGISelLegacy,DEBUG_TYPE,PASS_NAME,false,false)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
selectADDRrii(SDValue Addr,SDValue & Base,SDValue & Index,SDValue & Offset)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
selectADDRzri(SDValue Addr,SDValue & Base,SDValue & Index,SDValue & Offset)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
selectADDRzii(SDValue Addr,SDValue & Base,SDValue & Index,SDValue & Offset)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
selectADDRri(SDValue Addr,SDValue & Base,SDValue & Offset)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
selectADDRzi(SDValue Addr,SDValue & Base,SDValue & Offset)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
matchADDRrr(SDValue Addr,SDValue & Base,SDValue & Index)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
matchADDRri(SDValue Addr,SDValue & Base,SDValue & Offset)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
Select(SDNode * N)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.
SelectInlineAsmMemoryOperand(const SDValue & Op,InlineAsm::ConstraintCode ConstraintID,std::vector<SDValue> & OutOps)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
getGlobalBaseReg()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 ///
createVEISelDag(VETargetMachine & TM)343480093f4SDimitry Andric FunctionPass *llvm::createVEISelDag(VETargetMachine &TM) {
344*0fca6ea1SDimitry Andric return new VEDAGToDAGISelLegacy(TM);
345480093f4SDimitry Andric }
346