1*9880d681SAndroid Build Coastguard Worker //===-- BPFISelLowering.cpp - BPF DAG Lowering Implementation ------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file defines the interfaces that BPF uses to lower LLVM code into a
11*9880d681SAndroid Build Coastguard Worker // selection DAG.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Worker #include "BPFISelLowering.h"
16*9880d681SAndroid Build Coastguard Worker #include "BPF.h"
17*9880d681SAndroid Build Coastguard Worker #include "BPFSubtarget.h"
18*9880d681SAndroid Build Coastguard Worker #include "BPFTargetMachine.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/CallingConvLower.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFrameInfo.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/SelectionDAGISel.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/ValueTypes.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DiagnosticInfo.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DiagnosticPrinter.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
32*9880d681SAndroid Build Coastguard Worker using namespace llvm;
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "bpf-lower"
35*9880d681SAndroid Build Coastguard Worker
fail(const SDLoc & DL,SelectionDAG & DAG,const char * Msg)36*9880d681SAndroid Build Coastguard Worker static void fail(const SDLoc &DL, SelectionDAG &DAG, const char *Msg) {
37*9880d681SAndroid Build Coastguard Worker MachineFunction &MF = DAG.getMachineFunction();
38*9880d681SAndroid Build Coastguard Worker DAG.getContext()->diagnose(
39*9880d681SAndroid Build Coastguard Worker DiagnosticInfoUnsupported(*MF.getFunction(), Msg, DL.getDebugLoc()));
40*9880d681SAndroid Build Coastguard Worker }
41*9880d681SAndroid Build Coastguard Worker
fail(const SDLoc & DL,SelectionDAG & DAG,const char * Msg,SDValue Val)42*9880d681SAndroid Build Coastguard Worker static void fail(const SDLoc &DL, SelectionDAG &DAG, const char *Msg,
43*9880d681SAndroid Build Coastguard Worker SDValue Val) {
44*9880d681SAndroid Build Coastguard Worker MachineFunction &MF = DAG.getMachineFunction();
45*9880d681SAndroid Build Coastguard Worker std::string Str;
46*9880d681SAndroid Build Coastguard Worker raw_string_ostream OS(Str);
47*9880d681SAndroid Build Coastguard Worker OS << Msg;
48*9880d681SAndroid Build Coastguard Worker Val->print(OS);
49*9880d681SAndroid Build Coastguard Worker OS.flush();
50*9880d681SAndroid Build Coastguard Worker DAG.getContext()->diagnose(
51*9880d681SAndroid Build Coastguard Worker DiagnosticInfoUnsupported(*MF.getFunction(), Str, DL.getDebugLoc()));
52*9880d681SAndroid Build Coastguard Worker }
53*9880d681SAndroid Build Coastguard Worker
BPFTargetLowering(const TargetMachine & TM,const BPFSubtarget & STI)54*9880d681SAndroid Build Coastguard Worker BPFTargetLowering::BPFTargetLowering(const TargetMachine &TM,
55*9880d681SAndroid Build Coastguard Worker const BPFSubtarget &STI)
56*9880d681SAndroid Build Coastguard Worker : TargetLowering(TM) {
57*9880d681SAndroid Build Coastguard Worker
58*9880d681SAndroid Build Coastguard Worker // Set up the register classes.
59*9880d681SAndroid Build Coastguard Worker addRegisterClass(MVT::i64, &BPF::GPRRegClass);
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Worker // Compute derived properties from the register classes
62*9880d681SAndroid Build Coastguard Worker computeRegisterProperties(STI.getRegisterInfo());
63*9880d681SAndroid Build Coastguard Worker
64*9880d681SAndroid Build Coastguard Worker setStackPointerRegisterToSaveRestore(BPF::R11);
65*9880d681SAndroid Build Coastguard Worker
66*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::BR_CC, MVT::i64, Custom);
67*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::BR_JT, MVT::Other, Expand);
68*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::BRIND, MVT::Other, Expand);
69*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::BRCOND, MVT::Other, Expand);
70*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::SETCC, MVT::i64, Expand);
71*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::SELECT, MVT::i64, Expand);
72*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::SELECT_CC, MVT::i64, Custom);
73*9880d681SAndroid Build Coastguard Worker
74*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::GlobalAddress, MVT::i64, Custom);
75*9880d681SAndroid Build Coastguard Worker
76*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Custom);
77*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
78*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
79*9880d681SAndroid Build Coastguard Worker
80*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::SDIVREM, MVT::i64, Expand);
81*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::UDIVREM, MVT::i64, Expand);
82*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::SREM, MVT::i64, Expand);
83*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::UREM, MVT::i64, Expand);
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::MULHU, MVT::i64, Expand);
86*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::MULHS, MVT::i64, Expand);
87*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand);
88*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand);
89*9880d681SAndroid Build Coastguard Worker
90*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::ADDC, MVT::i64, Expand);
91*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::ADDE, MVT::i64, Expand);
92*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::SUBC, MVT::i64, Expand);
93*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::SUBE, MVT::i64, Expand);
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::ROTR, MVT::i64, Expand);
96*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::ROTL, MVT::i64, Expand);
97*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::SHL_PARTS, MVT::i64, Expand);
98*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::SRL_PARTS, MVT::i64, Expand);
99*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::SRA_PARTS, MVT::i64, Expand);
100*9880d681SAndroid Build Coastguard Worker
101*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::CTTZ, MVT::i64, Custom);
102*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::CTLZ, MVT::i64, Custom);
103*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i64, Custom);
104*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i64, Custom);
105*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::CTPOP, MVT::i64, Expand);
106*9880d681SAndroid Build Coastguard Worker
107*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
108*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8, Expand);
109*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand);
110*9880d681SAndroid Build Coastguard Worker setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i32, Expand);
111*9880d681SAndroid Build Coastguard Worker
112*9880d681SAndroid Build Coastguard Worker // Extended load operations for i1 types must be promoted
113*9880d681SAndroid Build Coastguard Worker for (MVT VT : MVT::integer_valuetypes()) {
114*9880d681SAndroid Build Coastguard Worker setLoadExtAction(ISD::EXTLOAD, VT, MVT::i1, Promote);
115*9880d681SAndroid Build Coastguard Worker setLoadExtAction(ISD::ZEXTLOAD, VT, MVT::i1, Promote);
116*9880d681SAndroid Build Coastguard Worker setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Promote);
117*9880d681SAndroid Build Coastguard Worker
118*9880d681SAndroid Build Coastguard Worker setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i8, Expand);
119*9880d681SAndroid Build Coastguard Worker setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i16, Expand);
120*9880d681SAndroid Build Coastguard Worker setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i32, Expand);
121*9880d681SAndroid Build Coastguard Worker }
122*9880d681SAndroid Build Coastguard Worker
123*9880d681SAndroid Build Coastguard Worker setBooleanContents(ZeroOrOneBooleanContent);
124*9880d681SAndroid Build Coastguard Worker
125*9880d681SAndroid Build Coastguard Worker // Function alignments (log2)
126*9880d681SAndroid Build Coastguard Worker setMinFunctionAlignment(3);
127*9880d681SAndroid Build Coastguard Worker setPrefFunctionAlignment(3);
128*9880d681SAndroid Build Coastguard Worker
129*9880d681SAndroid Build Coastguard Worker // inline memcpy() for kernel to see explicit copy
130*9880d681SAndroid Build Coastguard Worker MaxStoresPerMemset = MaxStoresPerMemsetOptSize = 128;
131*9880d681SAndroid Build Coastguard Worker MaxStoresPerMemcpy = MaxStoresPerMemcpyOptSize = 128;
132*9880d681SAndroid Build Coastguard Worker MaxStoresPerMemmove = MaxStoresPerMemmoveOptSize = 128;
133*9880d681SAndroid Build Coastguard Worker }
134*9880d681SAndroid Build Coastguard Worker
LowerOperation(SDValue Op,SelectionDAG & DAG) const135*9880d681SAndroid Build Coastguard Worker SDValue BPFTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
136*9880d681SAndroid Build Coastguard Worker switch (Op.getOpcode()) {
137*9880d681SAndroid Build Coastguard Worker case ISD::BR_CC:
138*9880d681SAndroid Build Coastguard Worker return LowerBR_CC(Op, DAG);
139*9880d681SAndroid Build Coastguard Worker case ISD::GlobalAddress:
140*9880d681SAndroid Build Coastguard Worker return LowerGlobalAddress(Op, DAG);
141*9880d681SAndroid Build Coastguard Worker case ISD::SELECT_CC:
142*9880d681SAndroid Build Coastguard Worker return LowerSELECT_CC(Op, DAG);
143*9880d681SAndroid Build Coastguard Worker default:
144*9880d681SAndroid Build Coastguard Worker llvm_unreachable("unimplemented operand");
145*9880d681SAndroid Build Coastguard Worker }
146*9880d681SAndroid Build Coastguard Worker }
147*9880d681SAndroid Build Coastguard Worker
148*9880d681SAndroid Build Coastguard Worker // Calling Convention Implementation
149*9880d681SAndroid Build Coastguard Worker #include "BPFGenCallingConv.inc"
150*9880d681SAndroid Build Coastguard Worker
LowerFormalArguments(SDValue Chain,CallingConv::ID CallConv,bool IsVarArg,const SmallVectorImpl<ISD::InputArg> & Ins,const SDLoc & DL,SelectionDAG & DAG,SmallVectorImpl<SDValue> & InVals) const151*9880d681SAndroid Build Coastguard Worker SDValue BPFTargetLowering::LowerFormalArguments(
152*9880d681SAndroid Build Coastguard Worker SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
153*9880d681SAndroid Build Coastguard Worker const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
154*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
155*9880d681SAndroid Build Coastguard Worker switch (CallConv) {
156*9880d681SAndroid Build Coastguard Worker default:
157*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unsupported calling convention");
158*9880d681SAndroid Build Coastguard Worker case CallingConv::C:
159*9880d681SAndroid Build Coastguard Worker case CallingConv::Fast:
160*9880d681SAndroid Build Coastguard Worker break;
161*9880d681SAndroid Build Coastguard Worker }
162*9880d681SAndroid Build Coastguard Worker
163*9880d681SAndroid Build Coastguard Worker MachineFunction &MF = DAG.getMachineFunction();
164*9880d681SAndroid Build Coastguard Worker MachineRegisterInfo &RegInfo = MF.getRegInfo();
165*9880d681SAndroid Build Coastguard Worker
166*9880d681SAndroid Build Coastguard Worker // Assign locations to all of the incoming arguments.
167*9880d681SAndroid Build Coastguard Worker SmallVector<CCValAssign, 16> ArgLocs;
168*9880d681SAndroid Build Coastguard Worker CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
169*9880d681SAndroid Build Coastguard Worker CCInfo.AnalyzeFormalArguments(Ins, CC_BPF64);
170*9880d681SAndroid Build Coastguard Worker
171*9880d681SAndroid Build Coastguard Worker for (auto &VA : ArgLocs) {
172*9880d681SAndroid Build Coastguard Worker if (VA.isRegLoc()) {
173*9880d681SAndroid Build Coastguard Worker // Arguments passed in registers
174*9880d681SAndroid Build Coastguard Worker EVT RegVT = VA.getLocVT();
175*9880d681SAndroid Build Coastguard Worker switch (RegVT.getSimpleVT().SimpleTy) {
176*9880d681SAndroid Build Coastguard Worker default: {
177*9880d681SAndroid Build Coastguard Worker errs() << "LowerFormalArguments Unhandled argument type: "
178*9880d681SAndroid Build Coastguard Worker << RegVT.getEVTString() << '\n';
179*9880d681SAndroid Build Coastguard Worker llvm_unreachable(0);
180*9880d681SAndroid Build Coastguard Worker }
181*9880d681SAndroid Build Coastguard Worker case MVT::i64:
182*9880d681SAndroid Build Coastguard Worker unsigned VReg = RegInfo.createVirtualRegister(&BPF::GPRRegClass);
183*9880d681SAndroid Build Coastguard Worker RegInfo.addLiveIn(VA.getLocReg(), VReg);
184*9880d681SAndroid Build Coastguard Worker SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, VReg, RegVT);
185*9880d681SAndroid Build Coastguard Worker
186*9880d681SAndroid Build Coastguard Worker // If this is an 8/16/32-bit value, it is really passed promoted to 64
187*9880d681SAndroid Build Coastguard Worker // bits. Insert an assert[sz]ext to capture this, then truncate to the
188*9880d681SAndroid Build Coastguard Worker // right size.
189*9880d681SAndroid Build Coastguard Worker if (VA.getLocInfo() == CCValAssign::SExt)
190*9880d681SAndroid Build Coastguard Worker ArgValue = DAG.getNode(ISD::AssertSext, DL, RegVT, ArgValue,
191*9880d681SAndroid Build Coastguard Worker DAG.getValueType(VA.getValVT()));
192*9880d681SAndroid Build Coastguard Worker else if (VA.getLocInfo() == CCValAssign::ZExt)
193*9880d681SAndroid Build Coastguard Worker ArgValue = DAG.getNode(ISD::AssertZext, DL, RegVT, ArgValue,
194*9880d681SAndroid Build Coastguard Worker DAG.getValueType(VA.getValVT()));
195*9880d681SAndroid Build Coastguard Worker
196*9880d681SAndroid Build Coastguard Worker if (VA.getLocInfo() != CCValAssign::Full)
197*9880d681SAndroid Build Coastguard Worker ArgValue = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), ArgValue);
198*9880d681SAndroid Build Coastguard Worker
199*9880d681SAndroid Build Coastguard Worker InVals.push_back(ArgValue);
200*9880d681SAndroid Build Coastguard Worker }
201*9880d681SAndroid Build Coastguard Worker } else {
202*9880d681SAndroid Build Coastguard Worker fail(DL, DAG, "defined with too many args");
203*9880d681SAndroid Build Coastguard Worker InVals.push_back(DAG.getConstant(0, DL, VA.getLocVT()));
204*9880d681SAndroid Build Coastguard Worker }
205*9880d681SAndroid Build Coastguard Worker }
206*9880d681SAndroid Build Coastguard Worker
207*9880d681SAndroid Build Coastguard Worker if (IsVarArg || MF.getFunction()->hasStructRetAttr()) {
208*9880d681SAndroid Build Coastguard Worker fail(DL, DAG, "functions with VarArgs or StructRet are not supported");
209*9880d681SAndroid Build Coastguard Worker }
210*9880d681SAndroid Build Coastguard Worker
211*9880d681SAndroid Build Coastguard Worker return Chain;
212*9880d681SAndroid Build Coastguard Worker }
213*9880d681SAndroid Build Coastguard Worker
214*9880d681SAndroid Build Coastguard Worker const unsigned BPFTargetLowering::MaxArgs = 5;
215*9880d681SAndroid Build Coastguard Worker
LowerCall(TargetLowering::CallLoweringInfo & CLI,SmallVectorImpl<SDValue> & InVals) const216*9880d681SAndroid Build Coastguard Worker SDValue BPFTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
217*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<SDValue> &InVals) const {
218*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG = CLI.DAG;
219*9880d681SAndroid Build Coastguard Worker auto &Outs = CLI.Outs;
220*9880d681SAndroid Build Coastguard Worker auto &OutVals = CLI.OutVals;
221*9880d681SAndroid Build Coastguard Worker auto &Ins = CLI.Ins;
222*9880d681SAndroid Build Coastguard Worker SDValue Chain = CLI.Chain;
223*9880d681SAndroid Build Coastguard Worker SDValue Callee = CLI.Callee;
224*9880d681SAndroid Build Coastguard Worker bool &IsTailCall = CLI.IsTailCall;
225*9880d681SAndroid Build Coastguard Worker CallingConv::ID CallConv = CLI.CallConv;
226*9880d681SAndroid Build Coastguard Worker bool IsVarArg = CLI.IsVarArg;
227*9880d681SAndroid Build Coastguard Worker MachineFunction &MF = DAG.getMachineFunction();
228*9880d681SAndroid Build Coastguard Worker
229*9880d681SAndroid Build Coastguard Worker // BPF target does not support tail call optimization.
230*9880d681SAndroid Build Coastguard Worker IsTailCall = false;
231*9880d681SAndroid Build Coastguard Worker
232*9880d681SAndroid Build Coastguard Worker switch (CallConv) {
233*9880d681SAndroid Build Coastguard Worker default:
234*9880d681SAndroid Build Coastguard Worker report_fatal_error("Unsupported calling convention");
235*9880d681SAndroid Build Coastguard Worker case CallingConv::Fast:
236*9880d681SAndroid Build Coastguard Worker case CallingConv::C:
237*9880d681SAndroid Build Coastguard Worker break;
238*9880d681SAndroid Build Coastguard Worker }
239*9880d681SAndroid Build Coastguard Worker
240*9880d681SAndroid Build Coastguard Worker // Analyze operands of the call, assigning locations to each operand.
241*9880d681SAndroid Build Coastguard Worker SmallVector<CCValAssign, 16> ArgLocs;
242*9880d681SAndroid Build Coastguard Worker CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
243*9880d681SAndroid Build Coastguard Worker
244*9880d681SAndroid Build Coastguard Worker CCInfo.AnalyzeCallOperands(Outs, CC_BPF64);
245*9880d681SAndroid Build Coastguard Worker
246*9880d681SAndroid Build Coastguard Worker unsigned NumBytes = CCInfo.getNextStackOffset();
247*9880d681SAndroid Build Coastguard Worker
248*9880d681SAndroid Build Coastguard Worker if (Outs.size() > MaxArgs)
249*9880d681SAndroid Build Coastguard Worker fail(CLI.DL, DAG, "too many args to ", Callee);
250*9880d681SAndroid Build Coastguard Worker
251*9880d681SAndroid Build Coastguard Worker for (auto &Arg : Outs) {
252*9880d681SAndroid Build Coastguard Worker ISD::ArgFlagsTy Flags = Arg.Flags;
253*9880d681SAndroid Build Coastguard Worker if (!Flags.isByVal())
254*9880d681SAndroid Build Coastguard Worker continue;
255*9880d681SAndroid Build Coastguard Worker
256*9880d681SAndroid Build Coastguard Worker fail(CLI.DL, DAG, "pass by value not supported ", Callee);
257*9880d681SAndroid Build Coastguard Worker }
258*9880d681SAndroid Build Coastguard Worker
259*9880d681SAndroid Build Coastguard Worker auto PtrVT = getPointerTy(MF.getDataLayout());
260*9880d681SAndroid Build Coastguard Worker Chain = DAG.getCALLSEQ_START(
261*9880d681SAndroid Build Coastguard Worker Chain, DAG.getConstant(NumBytes, CLI.DL, PtrVT, true), CLI.DL);
262*9880d681SAndroid Build Coastguard Worker
263*9880d681SAndroid Build Coastguard Worker SmallVector<std::pair<unsigned, SDValue>, MaxArgs> RegsToPass;
264*9880d681SAndroid Build Coastguard Worker
265*9880d681SAndroid Build Coastguard Worker // Walk arg assignments
266*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0,
267*9880d681SAndroid Build Coastguard Worker e = std::min(static_cast<unsigned>(ArgLocs.size()), MaxArgs);
268*9880d681SAndroid Build Coastguard Worker i != e; ++i) {
269*9880d681SAndroid Build Coastguard Worker CCValAssign &VA = ArgLocs[i];
270*9880d681SAndroid Build Coastguard Worker SDValue Arg = OutVals[i];
271*9880d681SAndroid Build Coastguard Worker
272*9880d681SAndroid Build Coastguard Worker // Promote the value if needed.
273*9880d681SAndroid Build Coastguard Worker switch (VA.getLocInfo()) {
274*9880d681SAndroid Build Coastguard Worker default:
275*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unknown loc info");
276*9880d681SAndroid Build Coastguard Worker case CCValAssign::Full:
277*9880d681SAndroid Build Coastguard Worker break;
278*9880d681SAndroid Build Coastguard Worker case CCValAssign::SExt:
279*9880d681SAndroid Build Coastguard Worker Arg = DAG.getNode(ISD::SIGN_EXTEND, CLI.DL, VA.getLocVT(), Arg);
280*9880d681SAndroid Build Coastguard Worker break;
281*9880d681SAndroid Build Coastguard Worker case CCValAssign::ZExt:
282*9880d681SAndroid Build Coastguard Worker Arg = DAG.getNode(ISD::ZERO_EXTEND, CLI.DL, VA.getLocVT(), Arg);
283*9880d681SAndroid Build Coastguard Worker break;
284*9880d681SAndroid Build Coastguard Worker case CCValAssign::AExt:
285*9880d681SAndroid Build Coastguard Worker Arg = DAG.getNode(ISD::ANY_EXTEND, CLI.DL, VA.getLocVT(), Arg);
286*9880d681SAndroid Build Coastguard Worker break;
287*9880d681SAndroid Build Coastguard Worker }
288*9880d681SAndroid Build Coastguard Worker
289*9880d681SAndroid Build Coastguard Worker // Push arguments into RegsToPass vector
290*9880d681SAndroid Build Coastguard Worker if (VA.isRegLoc())
291*9880d681SAndroid Build Coastguard Worker RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
292*9880d681SAndroid Build Coastguard Worker else
293*9880d681SAndroid Build Coastguard Worker llvm_unreachable("call arg pass bug");
294*9880d681SAndroid Build Coastguard Worker }
295*9880d681SAndroid Build Coastguard Worker
296*9880d681SAndroid Build Coastguard Worker SDValue InFlag;
297*9880d681SAndroid Build Coastguard Worker
298*9880d681SAndroid Build Coastguard Worker // Build a sequence of copy-to-reg nodes chained together with token chain and
299*9880d681SAndroid Build Coastguard Worker // flag operands which copy the outgoing args into registers. The InFlag in
300*9880d681SAndroid Build Coastguard Worker // necessary since all emitted instructions must be stuck together.
301*9880d681SAndroid Build Coastguard Worker for (auto &Reg : RegsToPass) {
302*9880d681SAndroid Build Coastguard Worker Chain = DAG.getCopyToReg(Chain, CLI.DL, Reg.first, Reg.second, InFlag);
303*9880d681SAndroid Build Coastguard Worker InFlag = Chain.getValue(1);
304*9880d681SAndroid Build Coastguard Worker }
305*9880d681SAndroid Build Coastguard Worker
306*9880d681SAndroid Build Coastguard Worker // If the callee is a GlobalAddress node (quite common, every direct call is)
307*9880d681SAndroid Build Coastguard Worker // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
308*9880d681SAndroid Build Coastguard Worker // Likewise ExternalSymbol -> TargetExternalSymbol.
309*9880d681SAndroid Build Coastguard Worker if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
310*9880d681SAndroid Build Coastguard Worker Callee = DAG.getTargetGlobalAddress(G->getGlobal(), CLI.DL, PtrVT,
311*9880d681SAndroid Build Coastguard Worker G->getOffset(), 0);
312*9880d681SAndroid Build Coastguard Worker else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
313*9880d681SAndroid Build Coastguard Worker Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, 0);
314*9880d681SAndroid Build Coastguard Worker
315*9880d681SAndroid Build Coastguard Worker // Returns a chain & a flag for retval copy to use.
316*9880d681SAndroid Build Coastguard Worker SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
317*9880d681SAndroid Build Coastguard Worker SmallVector<SDValue, 8> Ops;
318*9880d681SAndroid Build Coastguard Worker Ops.push_back(Chain);
319*9880d681SAndroid Build Coastguard Worker Ops.push_back(Callee);
320*9880d681SAndroid Build Coastguard Worker
321*9880d681SAndroid Build Coastguard Worker // Add argument registers to the end of the list so that they are
322*9880d681SAndroid Build Coastguard Worker // known live into the call.
323*9880d681SAndroid Build Coastguard Worker for (auto &Reg : RegsToPass)
324*9880d681SAndroid Build Coastguard Worker Ops.push_back(DAG.getRegister(Reg.first, Reg.second.getValueType()));
325*9880d681SAndroid Build Coastguard Worker
326*9880d681SAndroid Build Coastguard Worker if (InFlag.getNode())
327*9880d681SAndroid Build Coastguard Worker Ops.push_back(InFlag);
328*9880d681SAndroid Build Coastguard Worker
329*9880d681SAndroid Build Coastguard Worker Chain = DAG.getNode(BPFISD::CALL, CLI.DL, NodeTys, Ops);
330*9880d681SAndroid Build Coastguard Worker InFlag = Chain.getValue(1);
331*9880d681SAndroid Build Coastguard Worker
332*9880d681SAndroid Build Coastguard Worker // Create the CALLSEQ_END node.
333*9880d681SAndroid Build Coastguard Worker Chain = DAG.getCALLSEQ_END(
334*9880d681SAndroid Build Coastguard Worker Chain, DAG.getConstant(NumBytes, CLI.DL, PtrVT, true),
335*9880d681SAndroid Build Coastguard Worker DAG.getConstant(0, CLI.DL, PtrVT, true), InFlag, CLI.DL);
336*9880d681SAndroid Build Coastguard Worker InFlag = Chain.getValue(1);
337*9880d681SAndroid Build Coastguard Worker
338*9880d681SAndroid Build Coastguard Worker // Handle result values, copying them out of physregs into vregs that we
339*9880d681SAndroid Build Coastguard Worker // return.
340*9880d681SAndroid Build Coastguard Worker return LowerCallResult(Chain, InFlag, CallConv, IsVarArg, Ins, CLI.DL, DAG,
341*9880d681SAndroid Build Coastguard Worker InVals);
342*9880d681SAndroid Build Coastguard Worker }
343*9880d681SAndroid Build Coastguard Worker
344*9880d681SAndroid Build Coastguard Worker SDValue
LowerReturn(SDValue Chain,CallingConv::ID CallConv,bool IsVarArg,const SmallVectorImpl<ISD::OutputArg> & Outs,const SmallVectorImpl<SDValue> & OutVals,const SDLoc & DL,SelectionDAG & DAG) const345*9880d681SAndroid Build Coastguard Worker BPFTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
346*9880d681SAndroid Build Coastguard Worker bool IsVarArg,
347*9880d681SAndroid Build Coastguard Worker const SmallVectorImpl<ISD::OutputArg> &Outs,
348*9880d681SAndroid Build Coastguard Worker const SmallVectorImpl<SDValue> &OutVals,
349*9880d681SAndroid Build Coastguard Worker const SDLoc &DL, SelectionDAG &DAG) const {
350*9880d681SAndroid Build Coastguard Worker unsigned Opc = BPFISD::RET_FLAG;
351*9880d681SAndroid Build Coastguard Worker
352*9880d681SAndroid Build Coastguard Worker // CCValAssign - represent the assignment of the return value to a location
353*9880d681SAndroid Build Coastguard Worker SmallVector<CCValAssign, 16> RVLocs;
354*9880d681SAndroid Build Coastguard Worker MachineFunction &MF = DAG.getMachineFunction();
355*9880d681SAndroid Build Coastguard Worker
356*9880d681SAndroid Build Coastguard Worker // CCState - Info about the registers and stack slot.
357*9880d681SAndroid Build Coastguard Worker CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext());
358*9880d681SAndroid Build Coastguard Worker
359*9880d681SAndroid Build Coastguard Worker if (MF.getFunction()->getReturnType()->isAggregateType()) {
360*9880d681SAndroid Build Coastguard Worker fail(DL, DAG, "only integer returns supported");
361*9880d681SAndroid Build Coastguard Worker return DAG.getNode(Opc, DL, MVT::Other, Chain);
362*9880d681SAndroid Build Coastguard Worker }
363*9880d681SAndroid Build Coastguard Worker
364*9880d681SAndroid Build Coastguard Worker // Analize return values.
365*9880d681SAndroid Build Coastguard Worker CCInfo.AnalyzeReturn(Outs, RetCC_BPF64);
366*9880d681SAndroid Build Coastguard Worker
367*9880d681SAndroid Build Coastguard Worker SDValue Flag;
368*9880d681SAndroid Build Coastguard Worker SmallVector<SDValue, 4> RetOps(1, Chain);
369*9880d681SAndroid Build Coastguard Worker
370*9880d681SAndroid Build Coastguard Worker // Copy the result values into the output registers.
371*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i != RVLocs.size(); ++i) {
372*9880d681SAndroid Build Coastguard Worker CCValAssign &VA = RVLocs[i];
373*9880d681SAndroid Build Coastguard Worker assert(VA.isRegLoc() && "Can only return in registers!");
374*9880d681SAndroid Build Coastguard Worker
375*9880d681SAndroid Build Coastguard Worker Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVals[i], Flag);
376*9880d681SAndroid Build Coastguard Worker
377*9880d681SAndroid Build Coastguard Worker // Guarantee that all emitted copies are stuck together,
378*9880d681SAndroid Build Coastguard Worker // avoiding something bad.
379*9880d681SAndroid Build Coastguard Worker Flag = Chain.getValue(1);
380*9880d681SAndroid Build Coastguard Worker RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
381*9880d681SAndroid Build Coastguard Worker }
382*9880d681SAndroid Build Coastguard Worker
383*9880d681SAndroid Build Coastguard Worker RetOps[0] = Chain; // Update chain.
384*9880d681SAndroid Build Coastguard Worker
385*9880d681SAndroid Build Coastguard Worker // Add the flag if we have it.
386*9880d681SAndroid Build Coastguard Worker if (Flag.getNode())
387*9880d681SAndroid Build Coastguard Worker RetOps.push_back(Flag);
388*9880d681SAndroid Build Coastguard Worker
389*9880d681SAndroid Build Coastguard Worker return DAG.getNode(Opc, DL, MVT::Other, RetOps);
390*9880d681SAndroid Build Coastguard Worker }
391*9880d681SAndroid Build Coastguard Worker
LowerCallResult(SDValue Chain,SDValue InFlag,CallingConv::ID CallConv,bool IsVarArg,const SmallVectorImpl<ISD::InputArg> & Ins,const SDLoc & DL,SelectionDAG & DAG,SmallVectorImpl<SDValue> & InVals) const392*9880d681SAndroid Build Coastguard Worker SDValue BPFTargetLowering::LowerCallResult(
393*9880d681SAndroid Build Coastguard Worker SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, bool IsVarArg,
394*9880d681SAndroid Build Coastguard Worker const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
395*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
396*9880d681SAndroid Build Coastguard Worker
397*9880d681SAndroid Build Coastguard Worker MachineFunction &MF = DAG.getMachineFunction();
398*9880d681SAndroid Build Coastguard Worker // Assign locations to each value returned by this call.
399*9880d681SAndroid Build Coastguard Worker SmallVector<CCValAssign, 16> RVLocs;
400*9880d681SAndroid Build Coastguard Worker CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext());
401*9880d681SAndroid Build Coastguard Worker
402*9880d681SAndroid Build Coastguard Worker if (Ins.size() >= 2) {
403*9880d681SAndroid Build Coastguard Worker fail(DL, DAG, "only small returns supported");
404*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = Ins.size(); i != e; ++i)
405*9880d681SAndroid Build Coastguard Worker InVals.push_back(DAG.getConstant(0, DL, Ins[i].VT));
406*9880d681SAndroid Build Coastguard Worker return DAG.getCopyFromReg(Chain, DL, 1, Ins[0].VT, InFlag).getValue(1);
407*9880d681SAndroid Build Coastguard Worker }
408*9880d681SAndroid Build Coastguard Worker
409*9880d681SAndroid Build Coastguard Worker CCInfo.AnalyzeCallResult(Ins, RetCC_BPF64);
410*9880d681SAndroid Build Coastguard Worker
411*9880d681SAndroid Build Coastguard Worker // Copy all of the result registers out of their specified physreg.
412*9880d681SAndroid Build Coastguard Worker for (auto &Val : RVLocs) {
413*9880d681SAndroid Build Coastguard Worker Chain = DAG.getCopyFromReg(Chain, DL, Val.getLocReg(),
414*9880d681SAndroid Build Coastguard Worker Val.getValVT(), InFlag).getValue(1);
415*9880d681SAndroid Build Coastguard Worker InFlag = Chain.getValue(2);
416*9880d681SAndroid Build Coastguard Worker InVals.push_back(Chain.getValue(0));
417*9880d681SAndroid Build Coastguard Worker }
418*9880d681SAndroid Build Coastguard Worker
419*9880d681SAndroid Build Coastguard Worker return Chain;
420*9880d681SAndroid Build Coastguard Worker }
421*9880d681SAndroid Build Coastguard Worker
NegateCC(SDValue & LHS,SDValue & RHS,ISD::CondCode & CC)422*9880d681SAndroid Build Coastguard Worker static void NegateCC(SDValue &LHS, SDValue &RHS, ISD::CondCode &CC) {
423*9880d681SAndroid Build Coastguard Worker switch (CC) {
424*9880d681SAndroid Build Coastguard Worker default:
425*9880d681SAndroid Build Coastguard Worker break;
426*9880d681SAndroid Build Coastguard Worker case ISD::SETULT:
427*9880d681SAndroid Build Coastguard Worker case ISD::SETULE:
428*9880d681SAndroid Build Coastguard Worker case ISD::SETLT:
429*9880d681SAndroid Build Coastguard Worker case ISD::SETLE:
430*9880d681SAndroid Build Coastguard Worker CC = ISD::getSetCCSwappedOperands(CC);
431*9880d681SAndroid Build Coastguard Worker std::swap(LHS, RHS);
432*9880d681SAndroid Build Coastguard Worker break;
433*9880d681SAndroid Build Coastguard Worker }
434*9880d681SAndroid Build Coastguard Worker }
435*9880d681SAndroid Build Coastguard Worker
LowerBR_CC(SDValue Op,SelectionDAG & DAG) const436*9880d681SAndroid Build Coastguard Worker SDValue BPFTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
437*9880d681SAndroid Build Coastguard Worker SDValue Chain = Op.getOperand(0);
438*9880d681SAndroid Build Coastguard Worker ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
439*9880d681SAndroid Build Coastguard Worker SDValue LHS = Op.getOperand(2);
440*9880d681SAndroid Build Coastguard Worker SDValue RHS = Op.getOperand(3);
441*9880d681SAndroid Build Coastguard Worker SDValue Dest = Op.getOperand(4);
442*9880d681SAndroid Build Coastguard Worker SDLoc DL(Op);
443*9880d681SAndroid Build Coastguard Worker
444*9880d681SAndroid Build Coastguard Worker NegateCC(LHS, RHS, CC);
445*9880d681SAndroid Build Coastguard Worker
446*9880d681SAndroid Build Coastguard Worker return DAG.getNode(BPFISD::BR_CC, DL, Op.getValueType(), Chain, LHS, RHS,
447*9880d681SAndroid Build Coastguard Worker DAG.getConstant(CC, DL, MVT::i64), Dest);
448*9880d681SAndroid Build Coastguard Worker }
449*9880d681SAndroid Build Coastguard Worker
LowerSELECT_CC(SDValue Op,SelectionDAG & DAG) const450*9880d681SAndroid Build Coastguard Worker SDValue BPFTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
451*9880d681SAndroid Build Coastguard Worker SDValue LHS = Op.getOperand(0);
452*9880d681SAndroid Build Coastguard Worker SDValue RHS = Op.getOperand(1);
453*9880d681SAndroid Build Coastguard Worker SDValue TrueV = Op.getOperand(2);
454*9880d681SAndroid Build Coastguard Worker SDValue FalseV = Op.getOperand(3);
455*9880d681SAndroid Build Coastguard Worker ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
456*9880d681SAndroid Build Coastguard Worker SDLoc DL(Op);
457*9880d681SAndroid Build Coastguard Worker
458*9880d681SAndroid Build Coastguard Worker NegateCC(LHS, RHS, CC);
459*9880d681SAndroid Build Coastguard Worker
460*9880d681SAndroid Build Coastguard Worker SDValue TargetCC = DAG.getConstant(CC, DL, MVT::i64);
461*9880d681SAndroid Build Coastguard Worker
462*9880d681SAndroid Build Coastguard Worker SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
463*9880d681SAndroid Build Coastguard Worker SDValue Ops[] = {LHS, RHS, TargetCC, TrueV, FalseV};
464*9880d681SAndroid Build Coastguard Worker
465*9880d681SAndroid Build Coastguard Worker return DAG.getNode(BPFISD::SELECT_CC, DL, VTs, Ops);
466*9880d681SAndroid Build Coastguard Worker }
467*9880d681SAndroid Build Coastguard Worker
getTargetNodeName(unsigned Opcode) const468*9880d681SAndroid Build Coastguard Worker const char *BPFTargetLowering::getTargetNodeName(unsigned Opcode) const {
469*9880d681SAndroid Build Coastguard Worker switch ((BPFISD::NodeType)Opcode) {
470*9880d681SAndroid Build Coastguard Worker case BPFISD::FIRST_NUMBER:
471*9880d681SAndroid Build Coastguard Worker break;
472*9880d681SAndroid Build Coastguard Worker case BPFISD::RET_FLAG:
473*9880d681SAndroid Build Coastguard Worker return "BPFISD::RET_FLAG";
474*9880d681SAndroid Build Coastguard Worker case BPFISD::CALL:
475*9880d681SAndroid Build Coastguard Worker return "BPFISD::CALL";
476*9880d681SAndroid Build Coastguard Worker case BPFISD::SELECT_CC:
477*9880d681SAndroid Build Coastguard Worker return "BPFISD::SELECT_CC";
478*9880d681SAndroid Build Coastguard Worker case BPFISD::BR_CC:
479*9880d681SAndroid Build Coastguard Worker return "BPFISD::BR_CC";
480*9880d681SAndroid Build Coastguard Worker case BPFISD::Wrapper:
481*9880d681SAndroid Build Coastguard Worker return "BPFISD::Wrapper";
482*9880d681SAndroid Build Coastguard Worker }
483*9880d681SAndroid Build Coastguard Worker return nullptr;
484*9880d681SAndroid Build Coastguard Worker }
485*9880d681SAndroid Build Coastguard Worker
LowerGlobalAddress(SDValue Op,SelectionDAG & DAG) const486*9880d681SAndroid Build Coastguard Worker SDValue BPFTargetLowering::LowerGlobalAddress(SDValue Op,
487*9880d681SAndroid Build Coastguard Worker SelectionDAG &DAG) const {
488*9880d681SAndroid Build Coastguard Worker SDLoc DL(Op);
489*9880d681SAndroid Build Coastguard Worker const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
490*9880d681SAndroid Build Coastguard Worker SDValue GA = DAG.getTargetGlobalAddress(GV, DL, MVT::i64);
491*9880d681SAndroid Build Coastguard Worker
492*9880d681SAndroid Build Coastguard Worker return DAG.getNode(BPFISD::Wrapper, DL, MVT::i64, GA);
493*9880d681SAndroid Build Coastguard Worker }
494*9880d681SAndroid Build Coastguard Worker
495*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *
EmitInstrWithCustomInserter(MachineInstr & MI,MachineBasicBlock * BB) const496*9880d681SAndroid Build Coastguard Worker BPFTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
497*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *BB) const {
498*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo &TII = *BB->getParent()->getSubtarget().getInstrInfo();
499*9880d681SAndroid Build Coastguard Worker DebugLoc DL = MI.getDebugLoc();
500*9880d681SAndroid Build Coastguard Worker
501*9880d681SAndroid Build Coastguard Worker assert(MI.getOpcode() == BPF::Select && "Unexpected instr type to insert");
502*9880d681SAndroid Build Coastguard Worker
503*9880d681SAndroid Build Coastguard Worker // To "insert" a SELECT instruction, we actually have to insert the diamond
504*9880d681SAndroid Build Coastguard Worker // control-flow pattern. The incoming instruction knows the destination vreg
505*9880d681SAndroid Build Coastguard Worker // to set, the condition code register to branch on, the true/false values to
506*9880d681SAndroid Build Coastguard Worker // select between, and a branch opcode to use.
507*9880d681SAndroid Build Coastguard Worker const BasicBlock *LLVM_BB = BB->getBasicBlock();
508*9880d681SAndroid Build Coastguard Worker MachineFunction::iterator I = ++BB->getIterator();
509*9880d681SAndroid Build Coastguard Worker
510*9880d681SAndroid Build Coastguard Worker // ThisMBB:
511*9880d681SAndroid Build Coastguard Worker // ...
512*9880d681SAndroid Build Coastguard Worker // TrueVal = ...
513*9880d681SAndroid Build Coastguard Worker // jmp_XX r1, r2 goto Copy1MBB
514*9880d681SAndroid Build Coastguard Worker // fallthrough --> Copy0MBB
515*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *ThisMBB = BB;
516*9880d681SAndroid Build Coastguard Worker MachineFunction *F = BB->getParent();
517*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *Copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
518*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *Copy1MBB = F->CreateMachineBasicBlock(LLVM_BB);
519*9880d681SAndroid Build Coastguard Worker
520*9880d681SAndroid Build Coastguard Worker F->insert(I, Copy0MBB);
521*9880d681SAndroid Build Coastguard Worker F->insert(I, Copy1MBB);
522*9880d681SAndroid Build Coastguard Worker // Update machine-CFG edges by transferring all successors of the current
523*9880d681SAndroid Build Coastguard Worker // block to the new block which will contain the Phi node for the select.
524*9880d681SAndroid Build Coastguard Worker Copy1MBB->splice(Copy1MBB->begin(), BB,
525*9880d681SAndroid Build Coastguard Worker std::next(MachineBasicBlock::iterator(MI)), BB->end());
526*9880d681SAndroid Build Coastguard Worker Copy1MBB->transferSuccessorsAndUpdatePHIs(BB);
527*9880d681SAndroid Build Coastguard Worker // Next, add the true and fallthrough blocks as its successors.
528*9880d681SAndroid Build Coastguard Worker BB->addSuccessor(Copy0MBB);
529*9880d681SAndroid Build Coastguard Worker BB->addSuccessor(Copy1MBB);
530*9880d681SAndroid Build Coastguard Worker
531*9880d681SAndroid Build Coastguard Worker // Insert Branch if Flag
532*9880d681SAndroid Build Coastguard Worker unsigned LHS = MI.getOperand(1).getReg();
533*9880d681SAndroid Build Coastguard Worker unsigned RHS = MI.getOperand(2).getReg();
534*9880d681SAndroid Build Coastguard Worker int CC = MI.getOperand(3).getImm();
535*9880d681SAndroid Build Coastguard Worker switch (CC) {
536*9880d681SAndroid Build Coastguard Worker case ISD::SETGT:
537*9880d681SAndroid Build Coastguard Worker BuildMI(BB, DL, TII.get(BPF::JSGT_rr))
538*9880d681SAndroid Build Coastguard Worker .addReg(LHS)
539*9880d681SAndroid Build Coastguard Worker .addReg(RHS)
540*9880d681SAndroid Build Coastguard Worker .addMBB(Copy1MBB);
541*9880d681SAndroid Build Coastguard Worker break;
542*9880d681SAndroid Build Coastguard Worker case ISD::SETUGT:
543*9880d681SAndroid Build Coastguard Worker BuildMI(BB, DL, TII.get(BPF::JUGT_rr))
544*9880d681SAndroid Build Coastguard Worker .addReg(LHS)
545*9880d681SAndroid Build Coastguard Worker .addReg(RHS)
546*9880d681SAndroid Build Coastguard Worker .addMBB(Copy1MBB);
547*9880d681SAndroid Build Coastguard Worker break;
548*9880d681SAndroid Build Coastguard Worker case ISD::SETGE:
549*9880d681SAndroid Build Coastguard Worker BuildMI(BB, DL, TII.get(BPF::JSGE_rr))
550*9880d681SAndroid Build Coastguard Worker .addReg(LHS)
551*9880d681SAndroid Build Coastguard Worker .addReg(RHS)
552*9880d681SAndroid Build Coastguard Worker .addMBB(Copy1MBB);
553*9880d681SAndroid Build Coastguard Worker break;
554*9880d681SAndroid Build Coastguard Worker case ISD::SETUGE:
555*9880d681SAndroid Build Coastguard Worker BuildMI(BB, DL, TII.get(BPF::JUGE_rr))
556*9880d681SAndroid Build Coastguard Worker .addReg(LHS)
557*9880d681SAndroid Build Coastguard Worker .addReg(RHS)
558*9880d681SAndroid Build Coastguard Worker .addMBB(Copy1MBB);
559*9880d681SAndroid Build Coastguard Worker break;
560*9880d681SAndroid Build Coastguard Worker case ISD::SETEQ:
561*9880d681SAndroid Build Coastguard Worker BuildMI(BB, DL, TII.get(BPF::JEQ_rr))
562*9880d681SAndroid Build Coastguard Worker .addReg(LHS)
563*9880d681SAndroid Build Coastguard Worker .addReg(RHS)
564*9880d681SAndroid Build Coastguard Worker .addMBB(Copy1MBB);
565*9880d681SAndroid Build Coastguard Worker break;
566*9880d681SAndroid Build Coastguard Worker case ISD::SETNE:
567*9880d681SAndroid Build Coastguard Worker BuildMI(BB, DL, TII.get(BPF::JNE_rr))
568*9880d681SAndroid Build Coastguard Worker .addReg(LHS)
569*9880d681SAndroid Build Coastguard Worker .addReg(RHS)
570*9880d681SAndroid Build Coastguard Worker .addMBB(Copy1MBB);
571*9880d681SAndroid Build Coastguard Worker break;
572*9880d681SAndroid Build Coastguard Worker default:
573*9880d681SAndroid Build Coastguard Worker report_fatal_error("unimplemented select CondCode " + Twine(CC));
574*9880d681SAndroid Build Coastguard Worker }
575*9880d681SAndroid Build Coastguard Worker
576*9880d681SAndroid Build Coastguard Worker // Copy0MBB:
577*9880d681SAndroid Build Coastguard Worker // %FalseValue = ...
578*9880d681SAndroid Build Coastguard Worker // # fallthrough to Copy1MBB
579*9880d681SAndroid Build Coastguard Worker BB = Copy0MBB;
580*9880d681SAndroid Build Coastguard Worker
581*9880d681SAndroid Build Coastguard Worker // Update machine-CFG edges
582*9880d681SAndroid Build Coastguard Worker BB->addSuccessor(Copy1MBB);
583*9880d681SAndroid Build Coastguard Worker
584*9880d681SAndroid Build Coastguard Worker // Copy1MBB:
585*9880d681SAndroid Build Coastguard Worker // %Result = phi [ %FalseValue, Copy0MBB ], [ %TrueValue, ThisMBB ]
586*9880d681SAndroid Build Coastguard Worker // ...
587*9880d681SAndroid Build Coastguard Worker BB = Copy1MBB;
588*9880d681SAndroid Build Coastguard Worker BuildMI(*BB, BB->begin(), DL, TII.get(BPF::PHI), MI.getOperand(0).getReg())
589*9880d681SAndroid Build Coastguard Worker .addReg(MI.getOperand(5).getReg())
590*9880d681SAndroid Build Coastguard Worker .addMBB(Copy0MBB)
591*9880d681SAndroid Build Coastguard Worker .addReg(MI.getOperand(4).getReg())
592*9880d681SAndroid Build Coastguard Worker .addMBB(ThisMBB);
593*9880d681SAndroid Build Coastguard Worker
594*9880d681SAndroid Build Coastguard Worker MI.eraseFromParent(); // The pseudo instruction is gone now.
595*9880d681SAndroid Build Coastguard Worker return BB;
596*9880d681SAndroid Build Coastguard Worker }
597