LLVM 19.0.0git
XtensaISelLowering.cpp
Go to the documentation of this file.
1//===- XtensaISelLowering.cpp - Xtensa DAG Lowering Implementation --------===//
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 defines the interfaces that Xtensa uses to lower LLVM code into a
10// selection DAG.
11//
12//===----------------------------------------------------------------------===//
13
14#include "XtensaISelLowering.h"
16#include "XtensaSubtarget.h"
17#include "XtensaTargetMachine.h"
24#include "llvm/Support/Debug.h"
28#include <deque>
29
30using namespace llvm;
31
32#define DEBUG_TYPE "xtensa-lower"
33
34// Return true if we must use long (in fact, indirect) function call.
35// It's simplified version, production implimentation must
36// resolve a functions in ROM (usually glibc functions)
37static bool isLongCall(const char *str) {
38 // Currently always use long calls
39 return true;
40}
41
43 const XtensaSubtarget &STI)
44 : TargetLowering(TM), Subtarget(STI) {
45 MVT PtrVT = MVT::i32;
46 // Set up the register classes.
47 addRegisterClass(MVT::i32, &Xtensa::ARRegClass);
48
49 // Set up special registers.
51
53
55
58
60
64
71
72 // No sign extend instructions for i1
73 for (MVT VT : MVT::integer_valuetypes()) {
77 }
78
80
81 // Implement custom stack allocations
83 // Implement custom stack save and restore
86
87 // Compute derived properties from the register classes
89}
90
91//===----------------------------------------------------------------------===//
92// Calling conventions
93//===----------------------------------------------------------------------===//
94
95#include "XtensaGenCallingConv.inc"
96
97static bool CC_Xtensa_Custom(unsigned ValNo, MVT ValVT, MVT LocVT,
99 ISD::ArgFlagsTy ArgFlags, CCState &State) {
100 static const MCPhysReg IntRegs[] = {Xtensa::A2, Xtensa::A3, Xtensa::A4,
101 Xtensa::A5, Xtensa::A6, Xtensa::A7};
102
103 if (ArgFlags.isByVal()) {
104 Align ByValAlign = ArgFlags.getNonZeroByValAlign();
105 unsigned ByValSize = ArgFlags.getByValSize();
106 if (ByValSize < 4) {
107 ByValSize = 4;
108 }
109 if (ByValAlign < Align(4)) {
110 ByValAlign = Align(4);
111 }
112 unsigned Offset = State.AllocateStack(ByValSize, ByValAlign);
113 State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
114 // Mark all unused registers as allocated to avoid misuse
115 // of such registers.
116 while (State.AllocateReg(IntRegs))
117 ;
118 return false;
119 }
120
121 // Promote i8 and i16
122 if (LocVT == MVT::i8 || LocVT == MVT::i16) {
123 LocVT = MVT::i32;
124 if (ArgFlags.isSExt())
125 LocInfo = CCValAssign::SExt;
126 else if (ArgFlags.isZExt())
127 LocInfo = CCValAssign::ZExt;
128 else
129 LocInfo = CCValAssign::AExt;
130 }
131
132 unsigned Register;
133
134 Align OrigAlign = ArgFlags.getNonZeroOrigAlign();
135 bool needs64BitAlign = (ValVT == MVT::i32 && OrigAlign == Align(8));
136 bool needs128BitAlign = (ValVT == MVT::i32 && OrigAlign == Align(16));
137
138 if (ValVT == MVT::i32) {
140 // If this is the first part of an i64 arg,
141 // the allocated register must be either A2, A4 or A6.
142 if (needs64BitAlign && (Register == Xtensa::A3 || Register == Xtensa::A5 ||
143 Register == Xtensa::A7))
145 // arguments with 16byte alignment must be passed in the first register or
146 // passed via stack
147 if (needs128BitAlign && (Register != Xtensa::A2))
148 while ((Register = State.AllocateReg(IntRegs)))
149 ;
150 LocVT = MVT::i32;
151 } else if (ValVT == MVT::f64) {
152 // Allocate int register and shadow next int register.
154 if (Register == Xtensa::A3 || Register == Xtensa::A5 ||
155 Register == Xtensa::A7)
157 State.AllocateReg(IntRegs);
158 LocVT = MVT::i32;
159 } else {
160 report_fatal_error("Cannot handle this ValVT.");
161 }
162
163 if (!Register) {
164 unsigned Offset = State.AllocateStack(ValVT.getStoreSize(), OrigAlign);
165 State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
166 } else {
167 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Register, LocVT, LocInfo));
168 }
169
170 return false;
171}
172
173CCAssignFn *XtensaTargetLowering::CCAssignFnForCall(CallingConv::ID CC,
174 bool IsVarArg) const {
175 return CC_Xtensa_Custom;
176}
177
179 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
180 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
181 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
183 MachineFrameInfo &MFI = MF.getFrameInfo();
184
185 // Used with vargs to acumulate store chains.
186 std::vector<SDValue> OutChains;
187
188 if (IsVarArg)
189 report_fatal_error("Var arg not supported by FormalArguments Lowering");
190
191 // Assign locations to all of the incoming arguments.
193 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
194 *DAG.getContext());
195
196 CCInfo.AnalyzeFormalArguments(Ins, CCAssignFnForCall(CallConv, IsVarArg));
197
198 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
199 CCValAssign &VA = ArgLocs[i];
200 // Arguments stored on registers
201 if (VA.isRegLoc()) {
202 EVT RegVT = VA.getLocVT();
203 const TargetRegisterClass *RC;
204
205 if (RegVT == MVT::i32)
206 RC = &Xtensa::ARRegClass;
207 else
208 report_fatal_error("RegVT not supported by FormalArguments Lowering");
209
210 // Transform the arguments stored on
211 // physical registers into virtual ones
212 unsigned Register = MF.addLiveIn(VA.getLocReg(), RC);
213 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Register, RegVT);
214
215 // If this is an 8 or 16-bit value, it has been passed promoted
216 // to 32 bits. Insert an assert[sz]ext to capture this, then
217 // truncate to the right size.
218 if (VA.getLocInfo() != CCValAssign::Full) {
219 unsigned Opcode = 0;
220 if (VA.getLocInfo() == CCValAssign::SExt)
221 Opcode = ISD::AssertSext;
222 else if (VA.getLocInfo() == CCValAssign::ZExt)
223 Opcode = ISD::AssertZext;
224 if (Opcode)
225 ArgValue = DAG.getNode(Opcode, DL, RegVT, ArgValue,
226 DAG.getValueType(VA.getValVT()));
227 ArgValue = DAG.getNode((VA.getValVT() == MVT::f32) ? ISD::BITCAST
229 DL, VA.getValVT(), ArgValue);
230 }
231
232 InVals.push_back(ArgValue);
233
234 } else {
235 assert(VA.isMemLoc());
236
237 EVT ValVT = VA.getValVT();
238
239 // The stack pointer offset is relative to the caller stack frame.
240 int FI = MFI.CreateFixedObject(ValVT.getStoreSize(), VA.getLocMemOffset(),
241 true);
242
243 if (Ins[VA.getValNo()].Flags.isByVal()) {
244 // Assume that in this case load operation is created
245 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
246 InVals.push_back(FIN);
247 } else {
248 // Create load nodes to retrieve arguments from the stack
249 SDValue FIN =
251 InVals.push_back(DAG.getLoad(
252 ValVT, DL, Chain, FIN,
254 }
255 }
256 }
257
258 // All stores are grouped in one node to allow the matching between
259 // the size of Ins and InVals. This only happens when on varg functions
260 if (!OutChains.empty()) {
261 OutChains.push_back(Chain);
262 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
263 }
264
265 return Chain;
266}
267
270 SmallVectorImpl<SDValue> &InVals) const {
271 SelectionDAG &DAG = CLI.DAG;
272 SDLoc &DL = CLI.DL;
274 SmallVector<SDValue, 32> &OutVals = CLI.OutVals;
276 SDValue Chain = CLI.Chain;
277 SDValue Callee = CLI.Callee;
278 bool &IsTailCall = CLI.IsTailCall;
279 CallingConv::ID CallConv = CLI.CallConv;
280 bool IsVarArg = CLI.IsVarArg;
281
283 EVT PtrVT = getPointerTy(DAG.getDataLayout());
284 const TargetFrameLowering *TFL = Subtarget.getFrameLowering();
285
286 // TODO: Support tail call optimization.
287 IsTailCall = false;
288
289 // Analyze the operands of the call, assigning locations to each operand.
291 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
292
293 CCAssignFn *CC = CCAssignFnForCall(CallConv, IsVarArg);
294
295 CCInfo.AnalyzeCallOperands(Outs, CC);
296
297 // Get a count of how many bytes are to be pushed on the stack.
298 unsigned NumBytes = CCInfo.getStackSize();
299
300 Align StackAlignment = TFL->getStackAlign();
301 unsigned NextStackOffset = alignTo(NumBytes, StackAlignment);
302
303 Chain = DAG.getCALLSEQ_START(Chain, NextStackOffset, 0, DL);
304
305 // Copy argument values to their designated locations.
306 std::deque<std::pair<unsigned, SDValue>> RegsToPass;
307 SmallVector<SDValue, 8> MemOpChains;
308 SDValue StackPtr;
309 for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) {
310 CCValAssign &VA = ArgLocs[I];
311 SDValue ArgValue = OutVals[I];
312 ISD::ArgFlagsTy Flags = Outs[I].Flags;
313
314 if (VA.isRegLoc())
315 // Queue up the argument copies and emit them at the end.
316 RegsToPass.push_back(std::make_pair(VA.getLocReg(), ArgValue));
317 else if (Flags.isByVal()) {
318 assert(VA.isMemLoc());
319 assert(Flags.getByValSize() &&
320 "ByVal args of size 0 should have been ignored by front-end.");
321 assert(!IsTailCall &&
322 "Do not tail-call optimize if there is a byval argument.");
323
324 if (!StackPtr.getNode())
325 StackPtr = DAG.getCopyFromReg(Chain, DL, Xtensa::SP, PtrVT);
326 unsigned Offset = VA.getLocMemOffset();
327 SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,
329 SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), DL, MVT::i32);
330 SDValue Memcpy = DAG.getMemcpy(
331 Chain, DL, Address, ArgValue, SizeNode, Flags.getNonZeroByValAlign(),
332 /*isVolatile=*/false, /*AlwaysInline=*/false,
333 /*isTailCall=*/false, MachinePointerInfo(), MachinePointerInfo());
334 MemOpChains.push_back(Memcpy);
335 } else {
336 assert(VA.isMemLoc() && "Argument not register or memory");
337
338 // Work out the address of the stack slot. Unpromoted ints and
339 // floats are passed as right-justified 8-byte values.
340 if (!StackPtr.getNode())
341 StackPtr = DAG.getCopyFromReg(Chain, DL, Xtensa::SP, PtrVT);
342 unsigned Offset = VA.getLocMemOffset();
343 SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,
345
346 // Emit the store.
347 MemOpChains.push_back(
348 DAG.getStore(Chain, DL, ArgValue, Address, MachinePointerInfo()));
349 }
350 }
351
352 // Join the stores, which are independent of one another.
353 if (!MemOpChains.empty())
354 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains);
355
356 // Build a sequence of copy-to-reg nodes, chained and glued together.
357 SDValue Glue;
358 for (unsigned I = 0, E = RegsToPass.size(); I != E; ++I) {
359 unsigned Reg = RegsToPass[I].first;
360 Chain = DAG.getCopyToReg(Chain, DL, Reg, RegsToPass[I].second, Glue);
361 Glue = Chain.getValue(1);
362 }
363 std::string name;
364 unsigned char TF = 0;
365
366 // Accept direct calls by converting symbolic call addresses to the
367 // associated Target* opcodes.
368 if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
369 name = E->getSymbol();
370 TF = E->getTargetFlags();
371 if (isPositionIndependent()) {
372 report_fatal_error("PIC relocations is not supported");
373 } else
374 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, TF);
375 } else if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
376 const GlobalValue *GV = G->getGlobal();
377 name = GV->getName().str();
378 }
379
380 if ((!name.empty()) && isLongCall(name.c_str())) {
381 // Create a constant pool entry for the callee address
383
385 *DAG.getContext(), name.c_str(), 0 /* XtensaCLabelIndex */, false,
386 Modifier);
387
388 // Get the address of the callee into a register
389 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4), 0, TF);
390 SDValue CPWrap = getAddrPCRel(CPAddr, DAG);
391 Callee = CPWrap;
392 }
393
394 // The first call operand is the chain and the second is the target address.
396 Ops.push_back(Chain);
397 Ops.push_back(Callee);
398
399 // Add a register mask operand representing the call-preserved registers.
400 const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
401 const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv);
402 assert(Mask && "Missing call preserved mask for calling convention");
403 Ops.push_back(DAG.getRegisterMask(Mask));
404
405 // Add argument registers to the end of the list so that they are
406 // known live into the call.
407 for (unsigned I = 0, E = RegsToPass.size(); I != E; ++I) {
408 unsigned Reg = RegsToPass[I].first;
409 Ops.push_back(DAG.getRegister(Reg, RegsToPass[I].second.getValueType()));
410 }
411
412 // Glue the call to the argument copies, if any.
413 if (Glue.getNode())
414 Ops.push_back(Glue);
415
416 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
417 Chain = DAG.getNode(XtensaISD::CALL, DL, NodeTys, Ops);
418 Glue = Chain.getValue(1);
419
420 // Mark the end of the call, which is glued to the call itself.
421 Chain = DAG.getCALLSEQ_END(Chain, DAG.getConstant(NumBytes, DL, PtrVT, true),
422 DAG.getConstant(0, DL, PtrVT, true), Glue, DL);
423 Glue = Chain.getValue(1);
424
425 // Assign locations to each value returned by this call.
427 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, *DAG.getContext());
428 RetCCInfo.AnalyzeCallResult(Ins, RetCC_Xtensa);
429
430 // Copy all of the result registers out of their specified physreg.
431 for (unsigned I = 0, E = RetLocs.size(); I != E; ++I) {
432 CCValAssign &VA = RetLocs[I];
433
434 // Copy the value out, gluing the copy to the end of the call sequence.
435 unsigned Reg = VA.getLocReg();
436 SDValue RetValue = DAG.getCopyFromReg(Chain, DL, Reg, VA.getLocVT(), Glue);
437 Chain = RetValue.getValue(1);
438 Glue = RetValue.getValue(2);
439
440 InVals.push_back(RetValue);
441 }
442 return Chain;
443}
444
446 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
447 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const {
449 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
450 return CCInfo.CheckReturn(Outs, RetCC_Xtensa);
451}
452
455 bool IsVarArg,
457 const SmallVectorImpl<SDValue> &OutVals,
458 const SDLoc &DL, SelectionDAG &DAG) const {
459 if (IsVarArg)
460 report_fatal_error("VarArg not supported");
461
463
464 // Assign locations to each returned value.
466 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, *DAG.getContext());
467 RetCCInfo.AnalyzeReturn(Outs, RetCC_Xtensa);
468
469 SDValue Glue;
470 // Quick exit for void returns
471 if (RetLocs.empty())
472 return DAG.getNode(XtensaISD::RET, DL, MVT::Other, Chain);
473
474 // Copy the result values into the output registers.
476 RetOps.push_back(Chain);
477 for (unsigned I = 0, E = RetLocs.size(); I != E; ++I) {
478 CCValAssign &VA = RetLocs[I];
479 SDValue RetValue = OutVals[I];
480
481 // Make the return register live on exit.
482 assert(VA.isRegLoc() && "Can only return in registers!");
483
484 // Chain and glue the copies together.
485 unsigned Register = VA.getLocReg();
486 Chain = DAG.getCopyToReg(Chain, DL, Register, RetValue, Glue);
487 Glue = Chain.getValue(1);
488 RetOps.push_back(DAG.getRegister(Register, VA.getLocVT()));
489 }
490
491 // Update chain and glue.
492 RetOps[0] = Chain;
493 if (Glue.getNode())
494 RetOps.push_back(Glue);
495
496 return DAG.getNode(XtensaISD::RET, DL, MVT::Other, RetOps);
497}
498
499SDValue XtensaTargetLowering::LowerImmediate(SDValue Op,
500 SelectionDAG &DAG) const {
501 const ConstantSDNode *CN = cast<ConstantSDNode>(Op);
502 SDLoc DL(CN);
503 APInt APVal = CN->getAPIntValue();
504 int64_t Value = APVal.getSExtValue();
505 if (Op.getValueType() == MVT::i32) {
506 // Check if use node maybe lowered to the MOVI instruction
507 if (Value > -2048 && Value <= 2047)
508 return Op;
509 // Check if use node maybe lowered to the ADDMI instruction
510 SDNode &OpNode = *Op.getNode();
511 if ((OpNode.hasOneUse() && OpNode.use_begin()->getOpcode() == ISD::ADD) &&
512 isShiftedInt<16, 8>(Value))
513 return Op;
514 Type *Ty = Type::getInt32Ty(*DAG.getContext());
515 Constant *CV = ConstantInt::get(Ty, Value);
516 SDValue CP = DAG.getConstantPool(CV, MVT::i32);
517 return CP;
518 }
519 return Op;
520}
521
522SDValue XtensaTargetLowering::getAddrPCRel(SDValue Op,
523 SelectionDAG &DAG) const {
524 SDLoc DL(Op);
525 EVT Ty = Op.getValueType();
526 return DAG.getNode(XtensaISD::PCREL_WRAPPER, DL, Ty, Op);
527}
528
529SDValue XtensaTargetLowering::LowerConstantPool(ConstantPoolSDNode *CP,
530 SelectionDAG &DAG) const {
531 EVT PtrVT = getPointerTy(DAG.getDataLayout());
533 if (!CP->isMachineConstantPoolEntry()) {
534 Result = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, CP->getAlign(),
535 CP->getOffset());
536 } else {
537 report_fatal_error("This constantpool type is not supported yet");
538 }
539
540 return getAddrPCRel(Result, DAG);
541}
542
543SDValue XtensaTargetLowering::LowerSTACKSAVE(SDValue Op,
544 SelectionDAG &DAG) const {
545 return DAG.getCopyFromReg(Op.getOperand(0), SDLoc(Op), Xtensa::SP,
546 Op.getValueType());
547}
548
549SDValue XtensaTargetLowering::LowerSTACKRESTORE(SDValue Op,
550 SelectionDAG &DAG) const {
551 return DAG.getCopyToReg(Op.getOperand(0), SDLoc(Op), Xtensa::SP,
552 Op.getOperand(1));
553}
554
555SDValue XtensaTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
556 SelectionDAG &DAG) const {
557 SDValue Chain = Op.getOperand(0); // Legalize the chain.
558 SDValue Size = Op.getOperand(1); // Legalize the size.
559 EVT VT = Size->getValueType(0);
560 SDLoc DL(Op);
561
562 // Round up Size to 32
563 SDValue SizeTmp =
564 DAG.getNode(ISD::ADD, DL, VT, Size, DAG.getConstant(31, DL, MVT::i32));
565 SDValue SizeRoundUp = DAG.getNode(ISD::AND, DL, VT, SizeTmp,
566 DAG.getConstant(~31, DL, MVT::i32));
567
568 unsigned SPReg = Xtensa::SP;
569 SDValue SP = DAG.getCopyFromReg(Chain, DL, SPReg, VT);
570 SDValue NewSP = DAG.getNode(ISD::SUB, DL, VT, SP, SizeRoundUp); // Value
571 Chain = DAG.getCopyToReg(SP.getValue(1), DL, SPReg, NewSP); // Output chain
572
573 SDValue NewVal = DAG.getCopyFromReg(Chain, DL, SPReg, MVT::i32);
574 Chain = NewVal.getValue(1);
575
576 SDValue Ops[2] = {NewVal, Chain};
577 return DAG.getMergeValues(Ops, DL);
578}
579
581 SelectionDAG &DAG) const {
582 switch (Op.getOpcode()) {
583 case ISD::Constant:
584 return LowerImmediate(Op, DAG);
586 return LowerConstantPool(cast<ConstantPoolSDNode>(Op), DAG);
587 case ISD::STACKSAVE:
588 return LowerSTACKSAVE(Op, DAG);
590 return LowerSTACKRESTORE(Op, DAG);
592 return LowerDYNAMIC_STACKALLOC(Op, DAG);
593 default:
594 report_fatal_error("Unexpected node to lower");
595 }
596}
597
598const char *XtensaTargetLowering::getTargetNodeName(unsigned Opcode) const {
599 switch (Opcode) {
600 case XtensaISD::CALL:
601 return "XtensaISD::CALL";
603 return "XtensaISD::PCREL_WRAPPER";
604 case XtensaISD::RET:
605 return "XtensaISD::RET";
606 }
607 return nullptr;
608}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
uint64_t Size
#define I(x, y, z)
Definition: MD5.cpp:58
#define G(x, y, z)
Definition: MD5.cpp:56
unsigned const TargetRegisterInfo * TRI
const char LLVMTargetMachineRef TM
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const char * name
Definition: SMEABIPass.cpp:49
static const MCPhysReg IntRegs[32]
static bool CC_Xtensa_Custom(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
static bool isLongCall(const char *str)
Class for arbitrary precision integers.
Definition: APInt.h:77
int64_t getSExtValue() const
Get sign extended value.
Definition: APInt.h:1521
CCState - This class holds information needed while lowering arguments and return values.
void AnalyzeCallResult(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeCallResult - Analyze the return values of a call, incorporating info about the passed values i...
MCRegister AllocateReg(MCPhysReg Reg)
AllocateReg - Attempt to allocate one register.
bool CheckReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
CheckReturn - Analyze the return values of a function, returning true if the return can be performed ...
void AnalyzeReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeReturn - Analyze the returned values of a return, incorporating info about the result values i...
int64_t AllocateStack(unsigned Size, Align Alignment)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
void AnalyzeCallOperands(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeCallOperands - Analyze the outgoing arguments to a call, incorporating info about the passed v...
uint64_t getStackSize() const
Returns the size of the currently allocated portion of the stack.
void AnalyzeFormalArguments(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeFormalArguments - Analyze an array of argument values, incorporating info about the formals in...
void addLoc(const CCValAssign &V)
CCValAssign - Represent assignment of one arg/retval to a location.
bool isRegLoc() const
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP, bool IsCustom=false)
bool isMemLoc() const
int64_t getLocMemOffset() const
unsigned getValNo() const
const APInt & getAPIntValue() const
This is an important base class in LLVM.
Definition: Constant.h:41
This class represents an Operation in the Expression.
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
Machine Value Type.
static auto integer_valuetypes()
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:227
SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
SDValue getConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offs=0, bool isT=false, unsigned TargetFlags=0)
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), AAResults *AA=nullptr)
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:486
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
SDValue getRegister(unsigned Reg, EVT VT)
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
Definition: SelectionDAG.h:787
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
SDValue getValueType(EVT)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:481
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
Definition: SelectionDAG.h:813
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
SDValue getRegisterMask(const uint32_t *RegMask)
LLVMContext * getContext() const
Definition: SelectionDAG.h:499
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:753
bool empty() const
Definition: SmallVector.h:94
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:223
Information about stack frame layout on the target.
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
MVT getFrameIndexTy(const DataLayout &DL) const
Return the type for frame index, which is determined by the alloca address space specified through th...
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
bool isPositionIndependent() const
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:76
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
static IntegerType * getInt32Ty(LLVMContext &C)
LLVM Value Representation.
Definition: Value.h:74
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:309
static XtensaConstantPoolSymbol * Create(LLVMContext &C, const char *S, unsigned ID, bool PrivLinkage, XtensaCP::XtensaCPModifier Modifier=XtensaCP::no_modifier)
XtensaConstantPoolValue - Xtensa specific constantpool value.
const XtensaRegisterInfo * getRegisterInfo() const override
const TargetFrameLowering * getFrameLowering() const override
const char * getTargetNodeName(unsigned Opcode) const override
This method returns the name of a target specific DAG node.
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl< ISD::InputArg > &Ins, const SDLoc &DL, SelectionDAG &DAG, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower the incoming (formal) arguments, described by the Ins array,...
SDValue LowerCall(CallLoweringInfo &CLI, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower calls into the specified DAG.
XtensaTargetLowering(const TargetMachine &TM, const XtensaSubtarget &STI)
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, const SmallVectorImpl< SDValue > &OutVals, const SDLoc &DL, SelectionDAG &DAG) const override
This hook must be implemented to lower outgoing return values, described by the Outs array,...
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, LLVMContext &Context) const override
This hook should be implemented to check whether the return values described by the Outs array can fi...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
Definition: ISDOpcodes.h:1135
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition: ISDOpcodes.h:1131
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:240
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition: ISDOpcodes.h:792
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
Definition: ISDOpcodes.h:905
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
Definition: ISDOpcodes.h:1050
@ ConstantPool
Definition: ISDOpcodes.h:82
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition: ISDOpcodes.h:800
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition: ISDOpcodes.h:838
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:682
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition: ISDOpcodes.h:52
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition: ISDOpcodes.h:788
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition: ISDOpcodes.h:61
@ AssertZext
Definition: ISDOpcodes.h:62
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:456
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
DWARFExpression::Operation Op
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
Extended Value Type.
Definition: ValueTypes.h:34
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
Definition: ValueTypes.h:380
Align getNonZeroOrigAlign() const
unsigned getByValSize() const
Align getNonZeroByValAlign() const
This class contains a discriminated union of information about pointers in memory operands,...
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals