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