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