1 //===- ARCISelLowering.cpp - ARC DAG Lowering Impl --------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements the ARCTargetLowering class.
11 //===----------------------------------------------------------------------===//
13 #include "ARCISelLowering.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"
31 #define DEBUG_TYPE "arc-lower"
35 static SDValue
lowerCallResult(SDValue Chain
, SDValue InFlag
,
36 const SmallVectorImpl
<CCValAssign
> &RVLocs
,
37 SDLoc dl
, SelectionDAG
&DAG
,
38 SmallVectorImpl
<SDValue
> &InVals
);
40 static ARCCC::CondCode
ISDCCtoARCCC(ISD::CondCode isdCC
) {
67 llvm_unreachable("Unhandled ISDCC code.");
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
);
77 // Compute derived properties from the register classes
78 computeRegisterProperties(Subtarget
.getRegisterInfo());
80 setStackPointerRegisterToSaveRestore(ARC::SP
);
82 setSchedulingPreference(Sched::Source
);
84 // Use i32 for setcc operations results (slt, sgt, ...).
85 setBooleanContents(ZeroOrOneBooleanContent
);
86 setBooleanVectorContents(ZeroOrOneBooleanContent
);
88 for (unsigned Opc
= 0; Opc
< ISD::BUILTIN_OP_END
; ++Opc
)
89 setOperationAction(Opc
, MVT::i32
, Expand
);
91 // Operations to get us off of the ground.
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
);
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
);
105 setOperationAction(ISD::Constant
, MVT::i32
, Legal
);
106 setOperationAction(ISD::UNDEF
, MVT::i32
, Legal
);
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
);
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
);
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
);
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
);
133 setOperationAction(ISD::STACKSAVE
, MVT::Other
, Expand
);
134 setOperationAction(ISD::STACKRESTORE
, MVT::Other
, Expand
);
137 setOperationAction(ISD::SIGN_EXTEND_INREG
, MVT::i1
, Custom
);
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
);
145 const char *ARCTargetLowering::getTargetNodeName(unsigned Opcode
) const {
150 return "ARCISD::CMOV";
152 return "ARCISD::CMP";
154 return "ARCISD::BRcc";
156 return "ARCISD::RET";
157 case ARCISD::GAWRAPPER
:
158 return "ARCISD::GAWRAPPER";
163 //===----------------------------------------------------------------------===//
164 // Misc Lower Operation implementation
165 //===----------------------------------------------------------------------===//
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);
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
);
181 SDValue
ARCTargetLowering::LowerSIGN_EXTEND_INREG(SDValue Op
,
182 SelectionDAG
&DAG
) const {
183 SDValue Op0
= Op
.getOperand(0);
185 assert(Op
.getValueType() == MVT::i32
&&
186 "Unhandled target sign_extend_inreg.");
188 unsigned Width
= cast
<VTSDNode
>(Op
.getOperand(1))->getVT().getSizeInBits();
189 if (Width
== 16 || Width
== 8)
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
));
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);
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
));
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
);
220 #include "ARCGenCallingConv.inc"
222 //===----------------------------------------------------------------------===//
223 // Call Calling Convention Implementation
224 //===----------------------------------------------------------------------===//
226 /// ARC call implementation
227 SDValue
ARCTargetLowering::LowerCall(TargetLowering::CallLoweringInfo
&CLI
,
228 SmallVectorImpl
<SDValue
> &InVals
) const {
229 SelectionDAG
&DAG
= CLI
.DAG
;
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
;
240 IsTailCall
= false; // Do not support tail calls yet.
242 SmallVector
<CCValAssign
, 16> ArgLocs
;
243 CCState
CCInfo(CallConv
, IsVarArg
, DAG
.getMachineFunction(), ArgLocs
,
246 CCInfo
.AnalyzeCallOperands(Outs
, CC_ARC
);
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
,
252 RetCCInfo
.AllocateStack(CCInfo
.getNextStackOffset(), Align(4));
253 RetCCInfo
.AnalyzeCallResult(Ins
, RetCC_ARC
);
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());
259 Chain
= DAG
.getCALLSEQ_START(Chain
, NumBytes
, 0, dl
);
261 SmallVector
<std::pair
<unsigned, SDValue
>, 4> RegsToPass
;
262 SmallVector
<SDValue
, 12> MemOpChains
;
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
];
270 // Promote the value if needed.
271 switch (VA
.getLocInfo()) {
273 llvm_unreachable("Unknown loc info!");
274 case CCValAssign::Full
:
276 case CCValAssign::SExt
:
277 Arg
= DAG
.getNode(ISD::SIGN_EXTEND
, dl
, VA
.getLocVT(), Arg
);
279 case CCValAssign::ZExt
:
280 Arg
= DAG
.getNode(ISD::ZERO_EXTEND
, dl
, VA
.getLocVT(), Arg
);
282 case CCValAssign::AExt
:
283 Arg
= DAG
.getNode(ISD::ANY_EXTEND
, dl
, VA
.getLocVT(), Arg
);
287 // Arguments that can be passed on register must be kept at
290 RegsToPass
.push_back(std::make_pair(VA
.getLocReg(), Arg
));
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
);
302 DAG
.getStore(Chain
, dl
, Arg
, PtrOff
, MachinePointerInfo());
303 MemOpChains
.push_back(Store
);
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
);
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
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);
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
);
334 // Branch + Link = #chain, #target_address, #opt_in_flags...
335 // = Chain, Callee, Reg#1, Reg#2, ...
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
);
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()));
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
));
357 Chain
= DAG
.getNode(IsDirect
? ARCISD::BL
: ARCISD::JL
, dl
, NodeTys
, Ops
);
358 Glue
= Chain
.getValue(1);
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);
365 // Handle result values, copying them out of physregs into vregs that we
369 return lowerCallResult(Chain
, Glue
, RVLocs
, dl
, DAG
, InVals
);
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
];
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
);
390 assert(VA
.isMemLoc() && "Must be memory location.");
391 ResultMemLocs
.push_back(
392 std::make_pair(VA
.getLocMemOffset(), InVals
.size()));
394 // Reserve space for this result.
395 InVals
.push_back(SDValue());
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
));
408 DAG
.getLoad(MVT::i32
, dl
, Chain
, SpLoc
, MachinePointerInfo());
409 InVals
[Index
] = Load
;
410 MemOpChains
.push_back(Load
.getValue(1));
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
);
421 //===----------------------------------------------------------------------===//
422 // Formal Arguments Calling Convention Implementation
423 //===----------------------------------------------------------------------===//
429 ISD::ArgFlagsTy Flags
;
432 } // end anonymous namespace
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 {
441 llvm_unreachable("Unsupported calling convention");
443 case CallingConv::Fast
:
444 return LowerCallArguments(Chain
, CallConv
, IsVarArg
, Ins
, dl
, DAG
, InVals
);
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
>();
459 // Assign locations to all of the incoming arguments.
460 SmallVector
<CCValAssign
, 16> ArgLocs
;
461 CCState
CCInfo(CallConv
, IsVarArg
, DAG
.getMachineFunction(), ArgLocs
,
464 CCInfo
.AnalyzeFormalArguments(Ins
, CC_ARC
);
466 unsigned StackSlotSize
= 4;
469 AFI
->setReturnStackOffset(CCInfo
.getNextStackOffset());
471 // All getCopyFromReg ops must precede any getMemcpys to prevent the
472 // scheduler clobbering a register before it has been copied.
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
;
482 // 1a. CopyFromReg (and load) arg registers.
483 for (unsigned i
= 0, e
= ArgLocs
.size(); i
!= e
; ++i
) {
484 CCValAssign
&VA
= ArgLocs
[i
];
488 // Arguments passed in registers
489 EVT RegVT
= VA
.getLocVT();
490 switch (RegVT
.getSimpleVT().SimpleTy
) {
492 LLVM_DEBUG(errs() << "LowerFormalArguments Unhandled argument type: "
493 << (unsigned)RegVT
.getSimpleVT().SimpleTy
<< "\n");
494 llvm_unreachable("Unhandled LowerFormalArguments type.");
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));
504 assert(VA
.isMemLoc());
505 // Load the argument to a virtual register
506 unsigned ObjSize
= VA
.getLocVT().getStoreSize();
507 assert((ObjSize
<= StackSlotSize
) && "Unhandled argument");
509 // Create the frame index object for this incoming parameter...
510 int FI
= MFI
.CreateFixedObject(ObjSize
, VA
.getLocMemOffset(), true);
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
));
518 const ArgDataPair ADP
= {ArgIn
, Ins
[i
].Flags
};
519 ArgData
.push_back(ADP
);
522 // 1b. CopyFromReg vararg registers.
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
)) {
531 // Save remaining registers, storing higher register numbers at a higher
533 // There are (array_lengthof(ArgRegs) - FirstVAReg) registers which
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
550 DAG
.getStore(Val
.getValue(1), dl
, Val
, VAObj
, MachinePointerInfo());
551 MemOps
.push_back(Store
);
555 llvm_unreachable("Too many var args parameters.");
559 // 2. Chain CopyFromReg nodes into a TokenFactor.
560 if (!CFRegNode
.empty())
561 Chain
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
, CFRegNode
);
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
567 for (const auto &ArgDI
: ArgData
) {
568 if (ArgDI
.Flags
.isByVal() && ArgDI
.Flags
.getByValSize()) {
569 unsigned Size
= ArgDI
.Flags
.getByValSize();
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()));
581 InVals
.push_back(ArgDI
.SDV
);
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
);
594 //===----------------------------------------------------------------------===//
595 // Return Value Calling Convention Implementation
596 //===----------------------------------------------------------------------===//
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
))
605 if (CCInfo
.getNextStackOffset() != 0 && IsVarArg
)
611 ARCTargetLowering::LowerReturn(SDValue Chain
, CallingConv::ID CallConv
,
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();
619 // CCValAssign - represent the assignment of
620 // the return value to a location
621 SmallVector
<CCValAssign
, 16> RVLocs
;
623 // CCState - Info about the registers and stack slot.
624 CCState
CCInfo(CallConv
, IsVarArg
, DAG
.getMachineFunction(), RVLocs
,
627 // Analyze return values.
629 CCInfo
.AllocateStack(AFI
->getReturnStackOffset(), Align(4));
631 CCInfo
.AnalyzeReturn(Outs
, RetCC_ARC
);
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
];
641 assert(VA
.isMemLoc());
643 report_fatal_error("Can't return value from vararg function in memory");
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);
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
)));
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
);
664 // Now handle return values copied to registers.
665 for (unsigned i
= 0, e
= RVLocs
.size(); i
!= e
; ++i
) {
666 CCValAssign
&VA
= RVLocs
[i
];
669 // Copy the result values into the output registers.
670 Chain
= DAG
.getCopyToReg(Chain
, dl
, VA
.getLocReg(), OutVals
[i
], Flag
);
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()));
678 RetOps
[0] = Chain
; // Update chain.
680 // Add the flag if we have it.
682 RetOps
.push_back(Flag
);
684 // What to do with the RetOps?
685 return DAG
.getNode(ARCISD::RET
, dl
, MVT::Other
, RetOps
);
688 //===----------------------------------------------------------------------===//
689 // Target Optimization Hooks
690 //===----------------------------------------------------------------------===//
692 SDValue
ARCTargetLowering::PerformDAGCombine(SDNode
*N
,
693 DAGCombinerInfo
&DCI
) const {
697 //===----------------------------------------------------------------------===//
698 // Addressing mode description hooks
699 //===----------------------------------------------------------------------===//
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
,
706 Instruction
*I
) const {
707 return AM
.Scale
== 0;
710 // Don't emit tail calls for the time being.
711 bool ARCTargetLowering::mayBeEmittedAsTailCall(const CallInst
*CI
) const {
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);
721 EVT VT
= Op
.getValueType();
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
);
729 SDValue
ARCTargetLowering::LowerGlobalAddress(SDValue Op
,
730 SelectionDAG
&DAG
) const {
731 const GlobalAddressSDNode
*GN
= cast
<GlobalAddressSDNode
>(Op
);
732 const GlobalValue
*GV
= GN
->getGlobal();
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
);
739 static SDValue
LowerVASTART(SDValue Op
, SelectionDAG
&DAG
) {
740 MachineFunction
&MF
= DAG
.getMachineFunction();
741 auto *FuncInfo
= MF
.getInfo
<ARCFunctionInfo
>();
743 // vastart just stores the address of the VarArgsFrameIndex slot into the
744 // memory location argument.
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
));
753 SDValue
ARCTargetLowering::LowerOperation(SDValue Op
, SelectionDAG
&DAG
) const {
754 switch (Op
.getOpcode()) {
755 case ISD::GlobalAddress
:
756 return LowerGlobalAddress(Op
, DAG
);
758 return LowerFRAMEADDR(Op
, DAG
);
760 return LowerSELECT_CC(Op
, DAG
);
762 return LowerBR_CC(Op
, DAG
);
763 case ISD::SIGN_EXTEND_INREG
:
764 return LowerSIGN_EXTEND_INREG(Op
, DAG
);
766 return LowerJumpTable(Op
, DAG
);
768 return LowerVASTART(Op
, DAG
);
770 llvm_unreachable("unimplemented operand");