]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/ARC/ARCISelLowering.cpp
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / ARC / ARCISelLowering.cpp
1 //===- ARCISelLowering.cpp - ARC DAG Lowering Impl --------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the ARCTargetLowering class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "ARCISelLowering.h"
15 #include "ARC.h"
16 #include "ARCMachineFunctionInfo.h"
17 #include "ARCSubtarget.h"
18 #include "ARCTargetMachine.h"
19 #include "MCTargetDesc/ARCInfo.h"
20 #include "llvm/CodeGen/CallingConvLower.h"
21 #include "llvm/CodeGen/MachineFrameInfo.h"
22 #include "llvm/CodeGen/MachineFunction.h"
23 #include "llvm/CodeGen/MachineInstrBuilder.h"
24 #include "llvm/CodeGen/MachineJumpTableInfo.h"
25 #include "llvm/CodeGen/MachineRegisterInfo.h"
26 #include "llvm/CodeGen/SelectionDAGISel.h"
27 #include "llvm/CodeGen/ValueTypes.h"
28 #include "llvm/IR/CallingConv.h"
29 #include "llvm/IR/Intrinsics.h"
30 #include "llvm/Support/Debug.h"
31 #include <algorithm>
32
33 #define DEBUG_TYPE "arc-lower"
34
35 using namespace llvm;
36
37 static SDValue lowerCallResult(SDValue Chain, SDValue InFlag,
38                                const SmallVectorImpl<CCValAssign> &RVLocs,
39                                SDLoc dl, SelectionDAG &DAG,
40                                SmallVectorImpl<SDValue> &InVals);
41
42 static ARCCC::CondCode ISDCCtoARCCC(ISD::CondCode isdCC) {
43   switch (isdCC) {
44   case ISD::SETUEQ:
45     return ARCCC::EQ;
46   case ISD::SETUGT:
47     return ARCCC::HI;
48   case ISD::SETUGE:
49     return ARCCC::HS;
50   case ISD::SETULT:
51     return ARCCC::LO;
52   case ISD::SETULE:
53     return ARCCC::LS;
54   case ISD::SETUNE:
55     return ARCCC::NE;
56   case ISD::SETEQ:
57     return ARCCC::EQ;
58   case ISD::SETGT:
59     return ARCCC::GT;
60   case ISD::SETGE:
61     return ARCCC::GE;
62   case ISD::SETLT:
63     return ARCCC::LT;
64   case ISD::SETLE:
65     return ARCCC::LE;
66   case ISD::SETNE:
67     return ARCCC::NE;
68   default:
69     llvm_unreachable("Unhandled ISDCC code.");
70   }
71 }
72
73 ARCTargetLowering::ARCTargetLowering(const TargetMachine &TM,
74                                      const ARCSubtarget &Subtarget)
75     : TargetLowering(TM), Subtarget(Subtarget) {
76   // Set up the register classes.
77   addRegisterClass(MVT::i32, &ARC::GPR32RegClass);
78
79   // Compute derived properties from the register classes
80   computeRegisterProperties(Subtarget.getRegisterInfo());
81
82   setStackPointerRegisterToSaveRestore(ARC::SP);
83
84   setSchedulingPreference(Sched::Source);
85
86   // Use i32 for setcc operations results (slt, sgt, ...).
87   setBooleanContents(ZeroOrOneBooleanContent);
88   setBooleanVectorContents(ZeroOrOneBooleanContent);
89
90   for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
91     setOperationAction(Opc, MVT::i32, Expand);
92
93   // Operations to get us off of the ground.
94   // Basic.
95   setOperationAction(ISD::ADD, MVT::i32, Legal);
96   setOperationAction(ISD::SUB, MVT::i32, Legal);
97   setOperationAction(ISD::AND, MVT::i32, Legal);
98   setOperationAction(ISD::SMAX, MVT::i32, Legal);
99   setOperationAction(ISD::SMIN, MVT::i32, Legal);
100
101   // Need barrel shifter.
102   setOperationAction(ISD::SHL, MVT::i32, Legal);
103   setOperationAction(ISD::SRA, MVT::i32, Legal);
104   setOperationAction(ISD::SRL, MVT::i32, Legal);
105   setOperationAction(ISD::ROTR, MVT::i32, Legal);
106
107   setOperationAction(ISD::Constant, MVT::i32, Legal);
108   setOperationAction(ISD::UNDEF, MVT::i32, Legal);
109
110   // Need multiplier
111   setOperationAction(ISD::MUL, MVT::i32, Legal);
112   setOperationAction(ISD::MULHS, MVT::i32, Legal);
113   setOperationAction(ISD::MULHU, MVT::i32, Legal);
114   setOperationAction(ISD::LOAD, MVT::i32, Legal);
115   setOperationAction(ISD::STORE, MVT::i32, Legal);
116
117   setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
118   setOperationAction(ISD::BR_CC, MVT::i32, Custom);
119   setOperationAction(ISD::BRCOND, MVT::Other, Expand);
120   setOperationAction(ISD::BR_JT, MVT::Other, Expand);
121   setOperationAction(ISD::JumpTable, MVT::i32, Custom);
122
123   // Have psuedo instruction for frame addresses.
124   setOperationAction(ISD::FRAMEADDR, MVT::i32, Legal);
125   // Custom lower global addresses.
126   setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
127
128   // Expand var-args ops.
129   setOperationAction(ISD::VASTART, MVT::Other, Custom);
130   setOperationAction(ISD::VAEND, MVT::Other, Expand);
131   setOperationAction(ISD::VAARG, MVT::Other, Expand);
132   setOperationAction(ISD::VACOPY, MVT::Other, Expand);
133
134   // Other expansions
135   setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
136   setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
137
138   // Sign extend inreg
139   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Custom);
140 }
141
142 const char *ARCTargetLowering::getTargetNodeName(unsigned Opcode) const {
143   switch (Opcode) {
144   case ARCISD::BL:
145     return "ARCISD::BL";
146   case ARCISD::CMOV:
147     return "ARCISD::CMOV";
148   case ARCISD::CMP:
149     return "ARCISD::CMP";
150   case ARCISD::BRcc:
151     return "ARCISD::BRcc";
152   case ARCISD::RET:
153     return "ARCISD::RET";
154   case ARCISD::GAWRAPPER:
155     return "ARCISD::GAWRAPPER";
156   }
157   return nullptr;
158 }
159
160 //===----------------------------------------------------------------------===//
161 //  Misc Lower Operation implementation
162 //===----------------------------------------------------------------------===//
163
164 SDValue ARCTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
165   SDValue LHS = Op.getOperand(0);
166   SDValue RHS = Op.getOperand(1);
167   ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
168   SDValue TVal = Op.getOperand(2);
169   SDValue FVal = Op.getOperand(3);
170   SDLoc dl(Op);
171   ARCCC::CondCode ArcCC = ISDCCtoARCCC(CC);
172   assert(LHS.getValueType() == MVT::i32 && "Only know how to SELECT_CC i32");
173   SDValue Cmp = DAG.getNode(ARCISD::CMP, dl, MVT::Glue, LHS, RHS);
174   return DAG.getNode(ARCISD::CMOV, dl, TVal.getValueType(), TVal, FVal,
175                      DAG.getConstant(ArcCC, dl, MVT::i32), Cmp);
176 }
177
178 SDValue ARCTargetLowering::LowerSIGN_EXTEND_INREG(SDValue Op,
179                                                   SelectionDAG &DAG) const {
180   SDValue Op0 = Op.getOperand(0);
181   SDLoc dl(Op);
182   assert(Op.getValueType() == MVT::i32 &&
183          "Unhandled target sign_extend_inreg.");
184   // These are legal
185   unsigned Width = cast<VTSDNode>(Op.getOperand(1))->getVT().getSizeInBits();
186   if (Width == 16 || Width == 8)
187     return Op;
188   if (Width >= 32) {
189     return {};
190   }
191   SDValue LS = DAG.getNode(ISD::SHL, dl, MVT::i32, Op0,
192                            DAG.getConstant(32 - Width, dl, MVT::i32));
193   SDValue SR = DAG.getNode(ISD::SRA, dl, MVT::i32, LS,
194                            DAG.getConstant(32 - Width, dl, MVT::i32));
195   return SR;
196 }
197
198 SDValue ARCTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
199   SDValue Chain = Op.getOperand(0);
200   ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
201   SDValue LHS = Op.getOperand(2);
202   SDValue RHS = Op.getOperand(3);
203   SDValue Dest = Op.getOperand(4);
204   SDLoc dl(Op);
205   ARCCC::CondCode arcCC = ISDCCtoARCCC(CC);
206   assert(LHS.getValueType() == MVT::i32 && "Only know how to BR_CC i32");
207   return DAG.getNode(ARCISD::BRcc, dl, MVT::Other, Chain, Dest, LHS, RHS,
208                      DAG.getConstant(arcCC, dl, MVT::i32));
209 }
210
211 SDValue ARCTargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) const {
212   auto *N = cast<JumpTableSDNode>(Op);
213   SDValue GA = DAG.getTargetJumpTable(N->getIndex(), MVT::i32);
214   return DAG.getNode(ARCISD::GAWRAPPER, SDLoc(N), MVT::i32, GA);
215 }
216
217 #include "ARCGenCallingConv.inc"
218
219 //===----------------------------------------------------------------------===//
220 //                  Call Calling Convention Implementation
221 //===----------------------------------------------------------------------===//
222
223 /// ARC call implementation
224 SDValue ARCTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
225                                      SmallVectorImpl<SDValue> &InVals) const {
226   SelectionDAG &DAG = CLI.DAG;
227   SDLoc &dl = CLI.DL;
228   SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
229   SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
230   SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
231   SDValue Chain = CLI.Chain;
232   SDValue Callee = CLI.Callee;
233   CallingConv::ID CallConv = CLI.CallConv;
234   bool IsVarArg = CLI.IsVarArg;
235   bool &IsTailCall = CLI.IsTailCall;
236
237   IsTailCall = false; // Do not support tail calls yet.
238
239   SmallVector<CCValAssign, 16> ArgLocs;
240   CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
241                  *DAG.getContext());
242
243   CCInfo.AnalyzeCallOperands(Outs, CC_ARC);
244
245   SmallVector<CCValAssign, 16> RVLocs;
246   // Analyze return values to determine the number of bytes of stack required.
247   CCState RetCCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
248                     *DAG.getContext());
249   RetCCInfo.AllocateStack(CCInfo.getNextStackOffset(), 4);
250   RetCCInfo.AnalyzeCallResult(Ins, RetCC_ARC);
251
252   // Get a count of how many bytes are to be pushed on the stack.
253   unsigned NumBytes = RetCCInfo.getNextStackOffset();
254   auto PtrVT = getPointerTy(DAG.getDataLayout());
255
256   Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, dl);
257
258   SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass;
259   SmallVector<SDValue, 12> MemOpChains;
260
261   SDValue StackPtr;
262   // Walk the register/memloc assignments, inserting copies/loads.
263   for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
264     CCValAssign &VA = ArgLocs[i];
265     SDValue Arg = OutVals[i];
266
267     // Promote the value if needed.
268     switch (VA.getLocInfo()) {
269     default:
270       llvm_unreachable("Unknown loc info!");
271     case CCValAssign::Full:
272       break;
273     case CCValAssign::SExt:
274       Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
275       break;
276     case CCValAssign::ZExt:
277       Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
278       break;
279     case CCValAssign::AExt:
280       Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
281       break;
282     }
283
284     // Arguments that can be passed on register must be kept at
285     // RegsToPass vector
286     if (VA.isRegLoc()) {
287       RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
288     } else {
289       assert(VA.isMemLoc() && "Must be register or memory argument.");
290       if (!StackPtr.getNode())
291         StackPtr = DAG.getCopyFromReg(Chain, dl, ARC::SP,
292                                       getPointerTy(DAG.getDataLayout()));
293       // Calculate the stack position.
294       SDValue SOffset = DAG.getIntPtrConstant(VA.getLocMemOffset(), dl);
295       SDValue PtrOff = DAG.getNode(
296           ISD::ADD, dl, getPointerTy(DAG.getDataLayout()), StackPtr, SOffset);
297
298       SDValue Store =
299           DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
300       MemOpChains.push_back(Store);
301       IsTailCall = false;
302     }
303   }
304
305   // Transform all store nodes into one single node because
306   // all store nodes are independent of each other.
307   if (!MemOpChains.empty())
308     Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
309
310   // Build a sequence of copy-to-reg nodes chained together with token
311   // chain and flag operands which copy the outgoing args into registers.
312   // The InFlag in necessary since all emitted instructions must be
313   // stuck together.
314   SDValue Glue;
315   for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
316     Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
317                              RegsToPass[i].second, Glue);
318     Glue = Chain.getValue(1);
319   }
320
321   // If the callee is a GlobalAddress node (quite common, every direct call is)
322   // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
323   // Likewise ExternalSymbol -> TargetExternalSymbol.
324   bool IsDirect = true;
325   if (auto *G = dyn_cast<GlobalAddressSDNode>(Callee))
326     Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32);
327   else if (auto *E = dyn_cast<ExternalSymbolSDNode>(Callee))
328     Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32);
329   else
330     IsDirect = false;
331   // Branch + Link = #chain, #target_address, #opt_in_flags...
332   //             = Chain, Callee, Reg#1, Reg#2, ...
333   //
334   // Returns a chain & a flag for retval copy to use.
335   SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
336   SmallVector<SDValue, 8> Ops;
337   Ops.push_back(Chain);
338   Ops.push_back(Callee);
339
340   for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
341     Ops.push_back(DAG.getRegister(RegsToPass[i].first,
342                                   RegsToPass[i].second.getValueType()));
343
344   // Add a register mask operand representing the call-preserved registers.
345   const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
346   const uint32_t *Mask =
347       TRI->getCallPreservedMask(DAG.getMachineFunction(), CallConv);
348   assert(Mask && "Missing call preserved mask for calling convention");
349   Ops.push_back(DAG.getRegisterMask(Mask));
350
351   if (Glue.getNode())
352     Ops.push_back(Glue);
353
354   Chain = DAG.getNode(IsDirect ? ARCISD::BL : ARCISD::JL, dl, NodeTys, Ops);
355   Glue = Chain.getValue(1);
356
357   // Create the CALLSEQ_END node.
358   Chain = DAG.getCALLSEQ_END(Chain, DAG.getConstant(NumBytes, dl, PtrVT, true),
359                              DAG.getConstant(0, dl, PtrVT, true), Glue, dl);
360   Glue = Chain.getValue(1);
361
362   // Handle result values, copying them out of physregs into vregs that we
363   // return.
364   if (IsTailCall)
365     return Chain;
366   return lowerCallResult(Chain, Glue, RVLocs, dl, DAG, InVals);
367 }
368
369 /// Lower the result values of a call into the appropriate copies out of
370 /// physical registers / memory locations.
371 static SDValue lowerCallResult(SDValue Chain, SDValue Glue,
372                                const SmallVectorImpl<CCValAssign> &RVLocs,
373                                SDLoc dl, SelectionDAG &DAG,
374                                SmallVectorImpl<SDValue> &InVals) {
375   SmallVector<std::pair<int, unsigned>, 4> ResultMemLocs;
376   // Copy results out of physical registers.
377   for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
378     const CCValAssign &VA = RVLocs[i];
379     if (VA.isRegLoc()) {
380       SDValue RetValue;
381       RetValue =
382           DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), VA.getValVT(), Glue);
383       Chain = RetValue.getValue(1);
384       Glue = RetValue.getValue(2);
385       InVals.push_back(RetValue);
386     } else {
387       assert(VA.isMemLoc() && "Must be memory location.");
388       ResultMemLocs.push_back(
389           std::make_pair(VA.getLocMemOffset(), InVals.size()));
390
391       // Reserve space for this result.
392       InVals.push_back(SDValue());
393     }
394   }
395
396   // Copy results out of memory.
397   SmallVector<SDValue, 4> MemOpChains;
398   for (unsigned i = 0, e = ResultMemLocs.size(); i != e; ++i) {
399     int Offset = ResultMemLocs[i].first;
400     unsigned Index = ResultMemLocs[i].second;
401     SDValue StackPtr = DAG.getRegister(ARC::SP, MVT::i32);
402     SDValue SpLoc = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr,
403                                 DAG.getConstant(Offset, dl, MVT::i32));
404     SDValue Load =
405         DAG.getLoad(MVT::i32, dl, Chain, SpLoc, MachinePointerInfo());
406     InVals[Index] = Load;
407     MemOpChains.push_back(Load.getValue(1));
408   }
409
410   // Transform all loads nodes into one single node because
411   // all load nodes are independent of each other.
412   if (!MemOpChains.empty())
413     Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
414
415   return Chain;
416 }
417
418 //===----------------------------------------------------------------------===//
419 //             Formal Arguments Calling Convention Implementation
420 //===----------------------------------------------------------------------===//
421
422 namespace {
423
424 struct ArgDataPair {
425   SDValue SDV;
426   ISD::ArgFlagsTy Flags;
427 };
428
429 } // end anonymous namespace
430
431 /// ARC formal arguments implementation
432 SDValue ARCTargetLowering::LowerFormalArguments(
433     SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
434     const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
435     SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
436   switch (CallConv) {
437   default:
438     llvm_unreachable("Unsupported calling convention");
439   case CallingConv::C:
440   case CallingConv::Fast:
441     return LowerCallArguments(Chain, CallConv, IsVarArg, Ins, dl, DAG, InVals);
442   }
443 }
444
445 /// Transform physical registers into virtual registers, and generate load
446 /// operations for argument places on the stack.
447 SDValue ARCTargetLowering::LowerCallArguments(
448     SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
449     const SmallVectorImpl<ISD::InputArg> &Ins, SDLoc dl, SelectionDAG &DAG,
450     SmallVectorImpl<SDValue> &InVals) const {
451   MachineFunction &MF = DAG.getMachineFunction();
452   MachineFrameInfo &MFI = MF.getFrameInfo();
453   MachineRegisterInfo &RegInfo = MF.getRegInfo();
454   auto *AFI = MF.getInfo<ARCFunctionInfo>();
455
456   // Assign locations to all of the incoming arguments.
457   SmallVector<CCValAssign, 16> ArgLocs;
458   CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
459                  *DAG.getContext());
460
461   CCInfo.AnalyzeFormalArguments(Ins, CC_ARC);
462
463   unsigned StackSlotSize = 4;
464
465   if (!IsVarArg)
466     AFI->setReturnStackOffset(CCInfo.getNextStackOffset());
467
468   // All getCopyFromReg ops must precede any getMemcpys to prevent the
469   // scheduler clobbering a register before it has been copied.
470   // The stages are:
471   // 1. CopyFromReg (and load) arg & vararg registers.
472   // 2. Chain CopyFromReg nodes into a TokenFactor.
473   // 3. Memcpy 'byVal' args & push final InVals.
474   // 4. Chain mem ops nodes into a TokenFactor.
475   SmallVector<SDValue, 4> CFRegNode;
476   SmallVector<ArgDataPair, 4> ArgData;
477   SmallVector<SDValue, 4> MemOps;
478
479   // 1a. CopyFromReg (and load) arg registers.
480   for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
481     CCValAssign &VA = ArgLocs[i];
482     SDValue ArgIn;
483
484     if (VA.isRegLoc()) {
485       // Arguments passed in registers
486       EVT RegVT = VA.getLocVT();
487       switch (RegVT.getSimpleVT().SimpleTy) {
488       default: {
489         LLVM_DEBUG(errs() << "LowerFormalArguments Unhandled argument type: "
490                           << (unsigned)RegVT.getSimpleVT().SimpleTy << "\n");
491         llvm_unreachable("Unhandled LowerFormalArguments type.");
492       }
493       case MVT::i32:
494         unsigned VReg = RegInfo.createVirtualRegister(&ARC::GPR32RegClass);
495         RegInfo.addLiveIn(VA.getLocReg(), VReg);
496         ArgIn = DAG.getCopyFromReg(Chain, dl, VReg, RegVT);
497         CFRegNode.push_back(ArgIn.getValue(ArgIn->getNumValues() - 1));
498       }
499     } else {
500       // sanity check
501       assert(VA.isMemLoc());
502       // Load the argument to a virtual register
503       unsigned ObjSize = VA.getLocVT().getStoreSize();
504       assert((ObjSize <= StackSlotSize) && "Unhandled argument");
505
506       // Create the frame index object for this incoming parameter...
507       int FI = MFI.CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);
508
509       // Create the SelectionDAG nodes corresponding to a load
510       // from this parameter
511       SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
512       ArgIn = DAG.getLoad(VA.getLocVT(), dl, Chain, FIN,
513                           MachinePointerInfo::getFixedStack(MF, FI));
514     }
515     const ArgDataPair ADP = {ArgIn, Ins[i].Flags};
516     ArgData.push_back(ADP);
517   }
518
519   // 1b. CopyFromReg vararg registers.
520   if (IsVarArg) {
521     // Argument registers
522     static const MCPhysReg ArgRegs[] = {ARC::R0, ARC::R1, ARC::R2, ARC::R3,
523                                         ARC::R4, ARC::R5, ARC::R6, ARC::R7};
524     auto *AFI = MF.getInfo<ARCFunctionInfo>();
525     unsigned FirstVAReg = CCInfo.getFirstUnallocated(ArgRegs);
526     if (FirstVAReg < array_lengthof(ArgRegs)) {
527       int Offset = 0;
528       // Save remaining registers, storing higher register numbers at a higher
529       // address
530       // There are (array_lengthof(ArgRegs) - FirstVAReg) registers which
531       // need to be saved.
532       int VarFI =
533           MFI.CreateFixedObject((array_lengthof(ArgRegs) - FirstVAReg) * 4,
534                                 CCInfo.getNextStackOffset(), true);
535       AFI->setVarArgsFrameIndex(VarFI);
536       SDValue FIN = DAG.getFrameIndex(VarFI, MVT::i32);
537       for (unsigned i = FirstVAReg; i < array_lengthof(ArgRegs); i++) {
538         // Move argument from phys reg -> virt reg
539         unsigned VReg = RegInfo.createVirtualRegister(&ARC::GPR32RegClass);
540         RegInfo.addLiveIn(ArgRegs[i], VReg);
541         SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32);
542         CFRegNode.push_back(Val.getValue(Val->getNumValues() - 1));
543         SDValue VAObj = DAG.getNode(ISD::ADD, dl, MVT::i32, FIN,
544                                     DAG.getConstant(Offset, dl, MVT::i32));
545         // Move argument from virt reg -> stack
546         SDValue Store =
547             DAG.getStore(Val.getValue(1), dl, Val, VAObj, MachinePointerInfo());
548         MemOps.push_back(Store);
549         Offset += 4;
550       }
551     } else {
552       llvm_unreachable("Too many var args parameters.");
553     }
554   }
555
556   // 2. Chain CopyFromReg nodes into a TokenFactor.
557   if (!CFRegNode.empty())
558     Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, CFRegNode);
559
560   // 3. Memcpy 'byVal' args & push final InVals.
561   // Aggregates passed "byVal" need to be copied by the callee.
562   // The callee will use a pointer to this copy, rather than the original
563   // pointer.
564   for (const auto &ArgDI : ArgData) {
565     if (ArgDI.Flags.isByVal() && ArgDI.Flags.getByValSize()) {
566       unsigned Size = ArgDI.Flags.getByValSize();
567       unsigned Align = std::max(StackSlotSize, ArgDI.Flags.getByValAlign());
568       // Create a new object on the stack and copy the pointee into it.
569       int FI = MFI.CreateStackObject(Size, Align, false);
570       SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
571       InVals.push_back(FIN);
572       MemOps.push_back(DAG.getMemcpy(
573           Chain, dl, FIN, ArgDI.SDV, DAG.getConstant(Size, dl, MVT::i32), Align,
574           false, false, false, MachinePointerInfo(), MachinePointerInfo()));
575     } else {
576       InVals.push_back(ArgDI.SDV);
577     }
578   }
579
580   // 4. Chain mem ops nodes into a TokenFactor.
581   if (!MemOps.empty()) {
582     MemOps.push_back(Chain);
583     Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOps);
584   }
585
586   return Chain;
587 }
588
589 //===----------------------------------------------------------------------===//
590 //               Return Value Calling Convention Implementation
591 //===----------------------------------------------------------------------===//
592
593 bool ARCTargetLowering::CanLowerReturn(
594     CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
595     const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const {
596   SmallVector<CCValAssign, 16> RVLocs;
597   CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
598   if (!CCInfo.CheckReturn(Outs, RetCC_ARC))
599     return false;
600   if (CCInfo.getNextStackOffset() != 0 && IsVarArg)
601     return false;
602   return true;
603 }
604
605 SDValue
606 ARCTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
607                                bool IsVarArg,
608                                const SmallVectorImpl<ISD::OutputArg> &Outs,
609                                const SmallVectorImpl<SDValue> &OutVals,
610                                const SDLoc &dl, SelectionDAG &DAG) const {
611   auto *AFI = DAG.getMachineFunction().getInfo<ARCFunctionInfo>();
612   MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
613
614   // CCValAssign - represent the assignment of
615   // the return value to a location
616   SmallVector<CCValAssign, 16> RVLocs;
617
618   // CCState - Info about the registers and stack slot.
619   CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
620                  *DAG.getContext());
621
622   // Analyze return values.
623   if (!IsVarArg)
624     CCInfo.AllocateStack(AFI->getReturnStackOffset(), 4);
625
626   CCInfo.AnalyzeReturn(Outs, RetCC_ARC);
627
628   SDValue Flag;
629   SmallVector<SDValue, 4> RetOps(1, Chain);
630   SmallVector<SDValue, 4> MemOpChains;
631   // Handle return values that must be copied to memory.
632   for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
633     CCValAssign &VA = RVLocs[i];
634     if (VA.isRegLoc())
635       continue;
636     assert(VA.isMemLoc());
637     if (IsVarArg) {
638       report_fatal_error("Can't return value from vararg function in memory");
639     }
640
641     int Offset = VA.getLocMemOffset();
642     unsigned ObjSize = VA.getLocVT().getStoreSize();
643     // Create the frame index object for the memory location.
644     int FI = MFI.CreateFixedObject(ObjSize, Offset, false);
645
646     // Create a SelectionDAG node corresponding to a store
647     // to this memory location.
648     SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
649     MemOpChains.push_back(DAG.getStore(
650         Chain, dl, OutVals[i], FIN,
651         MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI)));
652   }
653
654   // Transform all store nodes into one single node because
655   // all stores are independent of each other.
656   if (!MemOpChains.empty())
657     Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
658
659   // Now handle return values copied to registers.
660   for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
661     CCValAssign &VA = RVLocs[i];
662     if (!VA.isRegLoc())
663       continue;
664     // Copy the result values into the output registers.
665     Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), OutVals[i], Flag);
666
667     // guarantee that all emitted copies are
668     // stuck together, avoiding something bad
669     Flag = Chain.getValue(1);
670     RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
671   }
672
673   RetOps[0] = Chain; // Update chain.
674
675   // Add the flag if we have it.
676   if (Flag.getNode())
677     RetOps.push_back(Flag);
678
679   // What to do with the RetOps?
680   return DAG.getNode(ARCISD::RET, dl, MVT::Other, RetOps);
681 }
682
683 //===----------------------------------------------------------------------===//
684 // Target Optimization Hooks
685 //===----------------------------------------------------------------------===//
686
687 SDValue ARCTargetLowering::PerformDAGCombine(SDNode *N,
688                                              DAGCombinerInfo &DCI) const {
689   return {};
690 }
691
692 //===----------------------------------------------------------------------===//
693 //  Addressing mode description hooks
694 //===----------------------------------------------------------------------===//
695
696 /// Return true if the addressing mode represented by AM is legal for this
697 /// target, for a load/store of the specified type.
698 bool ARCTargetLowering::isLegalAddressingMode(const DataLayout &DL,
699                                               const AddrMode &AM, Type *Ty,
700                                               unsigned AS,
701                                               Instruction *I) const {
702   return AM.Scale == 0;
703 }
704
705 // Don't emit tail calls for the time being.
706 bool ARCTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const {
707   return false;
708 }
709
710 SDValue ARCTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
711   const ARCRegisterInfo &ARI = *Subtarget.getRegisterInfo();
712   MachineFunction &MF = DAG.getMachineFunction();
713   MachineFrameInfo &MFI = MF.getFrameInfo();
714   MFI.setFrameAddressIsTaken(true);
715
716   EVT VT = Op.getValueType();
717   SDLoc dl(Op);
718   assert(cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() == 0 &&
719          "Only support lowering frame addr of current frame.");
720   unsigned FrameReg = ARI.getFrameRegister(MF);
721   return DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
722 }
723
724 SDValue ARCTargetLowering::LowerGlobalAddress(SDValue Op,
725                                               SelectionDAG &DAG) const {
726   const GlobalAddressSDNode *GN = cast<GlobalAddressSDNode>(Op);
727   const GlobalValue *GV = GN->getGlobal();
728   SDLoc dl(GN);
729   int64_t Offset = GN->getOffset();
730   SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, Offset);
731   return DAG.getNode(ARCISD::GAWRAPPER, dl, MVT::i32, GA);
732 }
733
734 static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) {
735   MachineFunction &MF = DAG.getMachineFunction();
736   auto *FuncInfo = MF.getInfo<ARCFunctionInfo>();
737
738   // vastart just stores the address of the VarArgsFrameIndex slot into the
739   // memory location argument.
740   SDLoc dl(Op);
741   EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(DAG.getDataLayout());
742   SDValue FR = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);
743   const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
744   return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1),
745                       MachinePointerInfo(SV));
746 }
747
748 SDValue ARCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
749   switch (Op.getOpcode()) {
750   case ISD::GlobalAddress:
751     return LowerGlobalAddress(Op, DAG);
752   case ISD::FRAMEADDR:
753     return LowerFRAMEADDR(Op, DAG);
754   case ISD::SELECT_CC:
755     return LowerSELECT_CC(Op, DAG);
756   case ISD::BR_CC:
757     return LowerBR_CC(Op, DAG);
758   case ISD::SIGN_EXTEND_INREG:
759     return LowerSIGN_EXTEND_INREG(Op, DAG);
760   case ISD::JumpTable:
761     return LowerJumpTable(Op, DAG);
762   case ISD::VASTART:
763     return LowerVASTART(Op, DAG);
764   default:
765     llvm_unreachable("unimplemented operand");
766   }
767 }