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
ISDCCtoARCCC(ISD::CondCode isdCC)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
ARCTargetLowering(const TargetMachine & TM,const ARCSubtarget & Subtarget)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
getTargetNodeName(unsigned Opcode) const142 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
LowerSELECT_CC(SDValue Op,SelectionDAG & DAG) const164 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
LowerSIGN_EXTEND_INREG(SDValue Op,SelectionDAG & DAG) const178 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
LowerBR_CC(SDValue Op,SelectionDAG & DAG) const198 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
LowerJumpTable(SDValue Op,SelectionDAG & DAG) const211 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
LowerCall(TargetLowering::CallLoweringInfo & CLI,SmallVectorImpl<SDValue> & InVals) const224 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.
lowerCallResult(SDValue Chain,SDValue Glue,const SmallVectorImpl<CCValAssign> & RVLocs,SDLoc dl,SelectionDAG & DAG,SmallVectorImpl<SDValue> & InVals)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
LowerFormalArguments(SDValue Chain,CallingConv::ID CallConv,bool IsVarArg,const SmallVectorImpl<ISD::InputArg> & Ins,const SDLoc & dl,SelectionDAG & DAG,SmallVectorImpl<SDValue> & InVals) const432 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.
LowerCallArguments(SDValue Chain,CallingConv::ID CallConv,bool IsVarArg,const SmallVectorImpl<ISD::InputArg> & Ins,SDLoc dl,SelectionDAG & DAG,SmallVectorImpl<SDValue> & InVals) const447 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
CanLowerReturn(CallingConv::ID CallConv,MachineFunction & MF,bool IsVarArg,const SmallVectorImpl<ISD::OutputArg> & Outs,LLVMContext & Context) const593 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
LowerReturn(SDValue Chain,CallingConv::ID CallConv,bool IsVarArg,const SmallVectorImpl<ISD::OutputArg> & Outs,const SmallVectorImpl<SDValue> & OutVals,const SDLoc & dl,SelectionDAG & DAG) const606 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
PerformDAGCombine(SDNode * N,DAGCombinerInfo & DCI) const687 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.
isLegalAddressingMode(const DataLayout & DL,const AddrMode & AM,Type * Ty,unsigned AS,Instruction * I) const698 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.
mayBeEmittedAsTailCall(const CallInst * CI) const706 bool ARCTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const {
707 return false;
708 }
709
LowerFRAMEADDR(SDValue Op,SelectionDAG & DAG) const710 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
LowerGlobalAddress(SDValue Op,SelectionDAG & DAG) const724 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
LowerVASTART(SDValue Op,SelectionDAG & DAG)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
LowerOperation(SDValue Op,SelectionDAG & DAG) const748 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 }
768