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
83
84 // Expand jump table branches as address arithmetic followed by an
85 // indirect jump.
87
88 setOperationPromotedToType(ISD::BR_CC, MVT::i1, MVT::i32);
92
93 // Implement custom stack allocations
95 // Implement custom stack save and restore
98
99 // Compute derived properties from the register classes
101}
102
104 const GlobalAddressSDNode *GA) const {
105 // The Xtensa target isn't yet aware of offsets.
106 return false;
107}
108
109//===----------------------------------------------------------------------===//
110// Calling conventions
111//===----------------------------------------------------------------------===//
112
113#include "XtensaGenCallingConv.inc"
114
115static bool CC_Xtensa_Custom(unsigned ValNo, MVT ValVT, MVT LocVT,
116 CCValAssign::LocInfo LocInfo,
117 ISD::ArgFlagsTy ArgFlags, CCState &State) {
118 static const MCPhysReg IntRegs[] = {Xtensa::A2, Xtensa::A3, Xtensa::A4,
119 Xtensa::A5, Xtensa::A6, Xtensa::A7};
120
121 if (ArgFlags.isByVal()) {
122 Align ByValAlign = ArgFlags.getNonZeroByValAlign();
123 unsigned ByValSize = ArgFlags.getByValSize();
124 if (ByValSize < 4) {
125 ByValSize = 4;
126 }
127 if (ByValAlign < Align(4)) {
128 ByValAlign = Align(4);
129 }
130 unsigned Offset = State.AllocateStack(ByValSize, ByValAlign);
131 State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
132 // Mark all unused registers as allocated to avoid misuse
133 // of such registers.
134 while (State.AllocateReg(IntRegs))
135 ;
136 return false;
137 }
138
139 // Promote i8 and i16
140 if (LocVT == MVT::i8 || LocVT == MVT::i16) {
141 LocVT = MVT::i32;
142 if (ArgFlags.isSExt())
143 LocInfo = CCValAssign::SExt;
144 else if (ArgFlags.isZExt())
145 LocInfo = CCValAssign::ZExt;
146 else
147 LocInfo = CCValAssign::AExt;
148 }
149
150 unsigned Register;
151
152 Align OrigAlign = ArgFlags.getNonZeroOrigAlign();
153 bool needs64BitAlign = (ValVT == MVT::i32 && OrigAlign == Align(8));
154 bool needs128BitAlign = (ValVT == MVT::i32 && OrigAlign == Align(16));
155
156 if (ValVT == MVT::i32) {
158 // If this is the first part of an i64 arg,
159 // the allocated register must be either A2, A4 or A6.
160 if (needs64BitAlign && (Register == Xtensa::A3 || Register == Xtensa::A5 ||
161 Register == Xtensa::A7))
163 // arguments with 16byte alignment must be passed in the first register or
164 // passed via stack
165 if (needs128BitAlign && (Register != Xtensa::A2))
166 while ((Register = State.AllocateReg(IntRegs)))
167 ;
168 LocVT = MVT::i32;
169 } else if (ValVT == MVT::f64) {
170 // Allocate int register and shadow next int register.
172 if (Register == Xtensa::A3 || Register == Xtensa::A5 ||
173 Register == Xtensa::A7)
175 State.AllocateReg(IntRegs);
176 LocVT = MVT::i32;
177 } else {
178 report_fatal_error("Cannot handle this ValVT.");
179 }
180
181 if (!Register) {
182 unsigned Offset = State.AllocateStack(ValVT.getStoreSize(), OrigAlign);
183 State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
184 } else {
185 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Register, LocVT, LocInfo));
186 }
187
188 return false;
189}
190
191CCAssignFn *XtensaTargetLowering::CCAssignFnForCall(CallingConv::ID CC,
192 bool IsVarArg) const {
193 return CC_Xtensa_Custom;
194}
195
197 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
198 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
199 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
201 MachineFrameInfo &MFI = MF.getFrameInfo();
202
203 // Used with vargs to acumulate store chains.
204 std::vector<SDValue> OutChains;
205
206 if (IsVarArg)
207 report_fatal_error("Var arg not supported by FormalArguments Lowering");
208
209 // Assign locations to all of the incoming arguments.
211 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
212 *DAG.getContext());
213
214 CCInfo.AnalyzeFormalArguments(Ins, CCAssignFnForCall(CallConv, IsVarArg));
215
216 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
217 CCValAssign &VA = ArgLocs[i];
218 // Arguments stored on registers
219 if (VA.isRegLoc()) {
220 EVT RegVT = VA.getLocVT();
221 const TargetRegisterClass *RC;
222
223 if (RegVT == MVT::i32)
224 RC = &Xtensa::ARRegClass;
225 else
226 report_fatal_error("RegVT not supported by FormalArguments Lowering");
227
228 // Transform the arguments stored on
229 // physical registers into virtual ones
230 unsigned Register = MF.addLiveIn(VA.getLocReg(), RC);
231 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Register, RegVT);
232
233 // If this is an 8 or 16-bit value, it has been passed promoted
234 // to 32 bits. Insert an assert[sz]ext to capture this, then
235 // truncate to the right size.
236 if (VA.getLocInfo() != CCValAssign::Full) {
237 unsigned Opcode = 0;
238 if (VA.getLocInfo() == CCValAssign::SExt)
239 Opcode = ISD::AssertSext;
240 else if (VA.getLocInfo() == CCValAssign::ZExt)
241 Opcode = ISD::AssertZext;
242 if (Opcode)
243 ArgValue = DAG.getNode(Opcode, DL, RegVT, ArgValue,
244 DAG.getValueType(VA.getValVT()));
245 ArgValue = DAG.getNode((VA.getValVT() == MVT::f32) ? ISD::BITCAST
247 DL, VA.getValVT(), ArgValue);
248 }
249
250 InVals.push_back(ArgValue);
251
252 } else {
253 assert(VA.isMemLoc());
254
255 EVT ValVT = VA.getValVT();
256
257 // The stack pointer offset is relative to the caller stack frame.
258 int FI = MFI.CreateFixedObject(ValVT.getStoreSize(), VA.getLocMemOffset(),
259 true);
260
261 if (Ins[VA.getValNo()].Flags.isByVal()) {
262 // Assume that in this case load operation is created
263 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
264 InVals.push_back(FIN);
265 } else {
266 // Create load nodes to retrieve arguments from the stack
267 SDValue FIN =
269 InVals.push_back(DAG.getLoad(
270 ValVT, DL, Chain, FIN,
272 }
273 }
274 }
275
276 // All stores are grouped in one node to allow the matching between
277 // the size of Ins and InVals. This only happens when on varg functions
278 if (!OutChains.empty()) {
279 OutChains.push_back(Chain);
280 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
281 }
282
283 return Chain;
284}
285
288 SmallVectorImpl<SDValue> &InVals) const {
289 SelectionDAG &DAG = CLI.DAG;
290 SDLoc &DL = CLI.DL;
292 SmallVector<SDValue, 32> &OutVals = CLI.OutVals;
294 SDValue Chain = CLI.Chain;
295 SDValue Callee = CLI.Callee;
296 bool &IsTailCall = CLI.IsTailCall;
297 CallingConv::ID CallConv = CLI.CallConv;
298 bool IsVarArg = CLI.IsVarArg;
299
301 EVT PtrVT = getPointerTy(DAG.getDataLayout());
302 const TargetFrameLowering *TFL = Subtarget.getFrameLowering();
303
304 // TODO: Support tail call optimization.
305 IsTailCall = false;
306
307 // Analyze the operands of the call, assigning locations to each operand.
309 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
310
311 CCAssignFn *CC = CCAssignFnForCall(CallConv, IsVarArg);
312
313 CCInfo.AnalyzeCallOperands(Outs, CC);
314
315 // Get a count of how many bytes are to be pushed on the stack.
316 unsigned NumBytes = CCInfo.getStackSize();
317
318 Align StackAlignment = TFL->getStackAlign();
319 unsigned NextStackOffset = alignTo(NumBytes, StackAlignment);
320
321 Chain = DAG.getCALLSEQ_START(Chain, NextStackOffset, 0, DL);
322
323 // Copy argument values to their designated locations.
324 std::deque<std::pair<unsigned, SDValue>> RegsToPass;
325 SmallVector<SDValue, 8> MemOpChains;
326 SDValue StackPtr;
327 for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) {
328 CCValAssign &VA = ArgLocs[I];
329 SDValue ArgValue = OutVals[I];
330 ISD::ArgFlagsTy Flags = Outs[I].Flags;
331
332 if (VA.isRegLoc())
333 // Queue up the argument copies and emit them at the end.
334 RegsToPass.push_back(std::make_pair(VA.getLocReg(), ArgValue));
335 else if (Flags.isByVal()) {
336 assert(VA.isMemLoc());
337 assert(Flags.getByValSize() &&
338 "ByVal args of size 0 should have been ignored by front-end.");
339 assert(!IsTailCall &&
340 "Do not tail-call optimize if there is a byval argument.");
341
342 if (!StackPtr.getNode())
343 StackPtr = DAG.getCopyFromReg(Chain, DL, Xtensa::SP, PtrVT);
344 unsigned Offset = VA.getLocMemOffset();
345 SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,
347 SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), DL, MVT::i32);
348 SDValue Memcpy = DAG.getMemcpy(
349 Chain, DL, Address, ArgValue, SizeNode, Flags.getNonZeroByValAlign(),
350 /*isVolatile=*/false, /*AlwaysInline=*/false,
351 /*isTailCall=*/false, MachinePointerInfo(), MachinePointerInfo());
352 MemOpChains.push_back(Memcpy);
353 } else {
354 assert(VA.isMemLoc() && "Argument not register or memory");
355
356 // Work out the address of the stack slot. Unpromoted ints and
357 // floats are passed as right-justified 8-byte values.
358 if (!StackPtr.getNode())
359 StackPtr = DAG.getCopyFromReg(Chain, DL, Xtensa::SP, PtrVT);
360 unsigned Offset = VA.getLocMemOffset();
361 SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,
363
364 // Emit the store.
365 MemOpChains.push_back(
366 DAG.getStore(Chain, DL, ArgValue, Address, MachinePointerInfo()));
367 }
368 }
369
370 // Join the stores, which are independent of one another.
371 if (!MemOpChains.empty())
372 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains);
373
374 // Build a sequence of copy-to-reg nodes, chained and glued together.
375 SDValue Glue;
376 for (unsigned I = 0, E = RegsToPass.size(); I != E; ++I) {
377 unsigned Reg = RegsToPass[I].first;
378 Chain = DAG.getCopyToReg(Chain, DL, Reg, RegsToPass[I].second, Glue);
379 Glue = Chain.getValue(1);
380 }
381 std::string name;
382 unsigned char TF = 0;
383
384 // Accept direct calls by converting symbolic call addresses to the
385 // associated Target* opcodes.
386 if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
387 name = E->getSymbol();
388 TF = E->getTargetFlags();
389 if (isPositionIndependent()) {
390 report_fatal_error("PIC relocations is not supported");
391 } else
392 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, TF);
393 } else if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
394 const GlobalValue *GV = G->getGlobal();
395 name = GV->getName().str();
396 }
397
398 if ((!name.empty()) && isLongCall(name.c_str())) {
399 // Create a constant pool entry for the callee address
401
403 *DAG.getContext(), name.c_str(), 0 /* XtensaCLabelIndex */, false,
404 Modifier);
405
406 // Get the address of the callee into a register
407 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4), 0, TF);
408 SDValue CPWrap = getAddrPCRel(CPAddr, DAG);
409 Callee = CPWrap;
410 }
411
412 // The first call operand is the chain and the second is the target address.
414 Ops.push_back(Chain);
415 Ops.push_back(Callee);
416
417 // Add a register mask operand representing the call-preserved registers.
418 const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
419 const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv);
420 assert(Mask && "Missing call preserved mask for calling convention");
421 Ops.push_back(DAG.getRegisterMask(Mask));
422
423 // Add argument registers to the end of the list so that they are
424 // known live into the call.
425 for (unsigned I = 0, E = RegsToPass.size(); I != E; ++I) {
426 unsigned Reg = RegsToPass[I].first;
427 Ops.push_back(DAG.getRegister(Reg, RegsToPass[I].second.getValueType()));
428 }
429
430 // Glue the call to the argument copies, if any.
431 if (Glue.getNode())
432 Ops.push_back(Glue);
433
434 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
435 Chain = DAG.getNode(XtensaISD::CALL, DL, NodeTys, Ops);
436 Glue = Chain.getValue(1);
437
438 // Mark the end of the call, which is glued to the call itself.
439 Chain = DAG.getCALLSEQ_END(Chain, DAG.getConstant(NumBytes, DL, PtrVT, true),
440 DAG.getConstant(0, DL, PtrVT, true), Glue, DL);
441 Glue = Chain.getValue(1);
442
443 // Assign locations to each value returned by this call.
445 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, *DAG.getContext());
446 RetCCInfo.AnalyzeCallResult(Ins, RetCC_Xtensa);
447
448 // Copy all of the result registers out of their specified physreg.
449 for (unsigned I = 0, E = RetLocs.size(); I != E; ++I) {
450 CCValAssign &VA = RetLocs[I];
451
452 // Copy the value out, gluing the copy to the end of the call sequence.
453 unsigned Reg = VA.getLocReg();
454 SDValue RetValue = DAG.getCopyFromReg(Chain, DL, Reg, VA.getLocVT(), Glue);
455 Chain = RetValue.getValue(1);
456 Glue = RetValue.getValue(2);
457
458 InVals.push_back(RetValue);
459 }
460 return Chain;
461}
462
464 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
465 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const {
467 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
468 return CCInfo.CheckReturn(Outs, RetCC_Xtensa);
469}
470
473 bool IsVarArg,
475 const SmallVectorImpl<SDValue> &OutVals,
476 const SDLoc &DL, SelectionDAG &DAG) const {
477 if (IsVarArg)
478 report_fatal_error("VarArg not supported");
479
481
482 // Assign locations to each returned value.
484 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, *DAG.getContext());
485 RetCCInfo.AnalyzeReturn(Outs, RetCC_Xtensa);
486
487 SDValue Glue;
488 // Quick exit for void returns
489 if (RetLocs.empty())
490 return DAG.getNode(XtensaISD::RET, DL, MVT::Other, Chain);
491
492 // Copy the result values into the output registers.
494 RetOps.push_back(Chain);
495 for (unsigned I = 0, E = RetLocs.size(); I != E; ++I) {
496 CCValAssign &VA = RetLocs[I];
497 SDValue RetValue = OutVals[I];
498
499 // Make the return register live on exit.
500 assert(VA.isRegLoc() && "Can only return in registers!");
501
502 // Chain and glue the copies together.
503 unsigned Register = VA.getLocReg();
504 Chain = DAG.getCopyToReg(Chain, DL, Register, RetValue, Glue);
505 Glue = Chain.getValue(1);
506 RetOps.push_back(DAG.getRegister(Register, VA.getLocVT()));
507 }
508
509 // Update chain and glue.
510 RetOps[0] = Chain;
511 if (Glue.getNode())
512 RetOps.push_back(Glue);
513
514 return DAG.getNode(XtensaISD::RET, DL, MVT::Other, RetOps);
515}
516
517SDValue XtensaTargetLowering::LowerImmediate(SDValue Op,
518 SelectionDAG &DAG) const {
519 const ConstantSDNode *CN = cast<ConstantSDNode>(Op);
520 SDLoc DL(CN);
521 APInt APVal = CN->getAPIntValue();
522 int64_t Value = APVal.getSExtValue();
523 if (Op.getValueType() == MVT::i32) {
524 // Check if use node maybe lowered to the MOVI instruction
525 if (Value > -2048 && Value <= 2047)
526 return Op;
527 // Check if use node maybe lowered to the ADDMI instruction
528 SDNode &OpNode = *Op.getNode();
529 if ((OpNode.hasOneUse() && OpNode.use_begin()->getOpcode() == ISD::ADD) &&
530 isShiftedInt<16, 8>(Value))
531 return Op;
532 Type *Ty = Type::getInt32Ty(*DAG.getContext());
533 Constant *CV = ConstantInt::get(Ty, Value);
534 SDValue CP = DAG.getConstantPool(CV, MVT::i32);
535 return CP;
536 }
537 return Op;
538}
539
540SDValue XtensaTargetLowering::LowerGlobalAddress(SDValue Op,
541 SelectionDAG &DAG) const {
542 const GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(Op);
543 SDLoc DL(Op);
544 auto PtrVT = Op.getValueType();
545 const GlobalValue *GV = G->getGlobal();
546
547 SDValue CPAddr = DAG.getTargetConstantPool(GV, PtrVT, Align(4));
548 SDValue CPWrap = getAddrPCRel(CPAddr, DAG);
549
550 return CPWrap;
551}
552
553SDValue XtensaTargetLowering::LowerBlockAddress(SDValue Op,
554 SelectionDAG &DAG) const {
555 BlockAddressSDNode *Node = cast<BlockAddressSDNode>(Op);
556 const BlockAddress *BA = Node->getBlockAddress();
557 EVT PtrVT = Op.getValueType();
558
561 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
562 SDValue CPWrap = getAddrPCRel(CPAddr, DAG);
563
564 return CPWrap;
565}
566
567SDValue XtensaTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) const {
568 SDValue Chain = Op.getOperand(0);
569 SDValue Table = Op.getOperand(1);
570 SDValue Index = Op.getOperand(2);
571 SDLoc DL(Op);
572 JumpTableSDNode *JT = cast<JumpTableSDNode>(Table);
574 const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
575 SDValue TargetJT = DAG.getTargetJumpTable(JT->getIndex(), MVT::i32);
576 const DataLayout &TD = DAG.getDataLayout();
577 EVT PtrVT = Table.getValueType();
578 unsigned EntrySize = MJTI->getEntrySize(TD);
579
580 Index = DAG.getNode(ISD::MUL, DL, Index.getValueType(), Index,
581 DAG.getConstant(EntrySize, DL, Index.getValueType()));
582 SDValue Addr = DAG.getNode(ISD::ADD, DL, Index.getValueType(), Index, Table);
583 SDValue LD =
584 DAG.getLoad(PtrVT, DL, Chain, Addr,
586
587 return DAG.getNode(XtensaISD::BR_JT, DL, MVT::Other, LD.getValue(1), LD,
588 TargetJT);
589}
590
591SDValue XtensaTargetLowering::LowerJumpTable(SDValue Op,
592 SelectionDAG &DAG) const {
593 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
594 EVT PtrVT = Op.getValueType();
595
596 // Create a constant pool entry for the callee address
599
600 // Get the address of the callee into a register
601 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
602
603 return getAddrPCRel(CPAddr, DAG);
604}
605
606SDValue XtensaTargetLowering::getAddrPCRel(SDValue Op,
607 SelectionDAG &DAG) const {
608 SDLoc DL(Op);
609 EVT Ty = Op.getValueType();
610 return DAG.getNode(XtensaISD::PCREL_WRAPPER, DL, Ty, Op);
611}
612
613SDValue XtensaTargetLowering::LowerConstantPool(ConstantPoolSDNode *CP,
614 SelectionDAG &DAG) const {
615 EVT PtrVT = getPointerTy(DAG.getDataLayout());
617 if (!CP->isMachineConstantPoolEntry()) {
618 Result = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, CP->getAlign(),
619 CP->getOffset());
620 } else {
621 report_fatal_error("This constantpool type is not supported yet");
622 }
623
624 return getAddrPCRel(Result, DAG);
625}
626
627SDValue XtensaTargetLowering::LowerSTACKSAVE(SDValue Op,
628 SelectionDAG &DAG) const {
629 return DAG.getCopyFromReg(Op.getOperand(0), SDLoc(Op), Xtensa::SP,
630 Op.getValueType());
631}
632
633SDValue XtensaTargetLowering::LowerSTACKRESTORE(SDValue Op,
634 SelectionDAG &DAG) const {
635 return DAG.getCopyToReg(Op.getOperand(0), SDLoc(Op), Xtensa::SP,
636 Op.getOperand(1));
637}
638
639SDValue XtensaTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
640 SelectionDAG &DAG) const {
641 SDValue Chain = Op.getOperand(0); // Legalize the chain.
642 SDValue Size = Op.getOperand(1); // Legalize the size.
643 EVT VT = Size->getValueType(0);
644 SDLoc DL(Op);
645
646 // Round up Size to 32
647 SDValue SizeTmp =
648 DAG.getNode(ISD::ADD, DL, VT, Size, DAG.getConstant(31, DL, MVT::i32));
649 SDValue SizeRoundUp = DAG.getNode(ISD::AND, DL, VT, SizeTmp,
650 DAG.getConstant(~31, DL, MVT::i32));
651
652 unsigned SPReg = Xtensa::SP;
653 SDValue SP = DAG.getCopyFromReg(Chain, DL, SPReg, VT);
654 SDValue NewSP = DAG.getNode(ISD::SUB, DL, VT, SP, SizeRoundUp); // Value
655 Chain = DAG.getCopyToReg(SP.getValue(1), DL, SPReg, NewSP); // Output chain
656
657 SDValue NewVal = DAG.getCopyFromReg(Chain, DL, SPReg, MVT::i32);
658 Chain = NewVal.getValue(1);
659
660 SDValue Ops[2] = {NewVal, Chain};
661 return DAG.getMergeValues(Ops, DL);
662}
663
665 SelectionDAG &DAG) const {
666 switch (Op.getOpcode()) {
667 case ISD::BR_JT:
668 return LowerBR_JT(Op, DAG);
669 case ISD::Constant:
670 return LowerImmediate(Op, DAG);
672 return LowerGlobalAddress(Op, DAG);
674 return LowerBlockAddress(Op, DAG);
675 case ISD::JumpTable:
676 return LowerJumpTable(Op, DAG);
678 return LowerConstantPool(cast<ConstantPoolSDNode>(Op), DAG);
679 case ISD::STACKSAVE:
680 return LowerSTACKSAVE(Op, DAG);
682 return LowerSTACKRESTORE(Op, DAG);
684 return LowerDYNAMIC_STACKALLOC(Op, DAG);
685 default:
686 report_fatal_error("Unexpected node to lower");
687 }
688}
689
690const char *XtensaTargetLowering::getTargetNodeName(unsigned Opcode) const {
691 switch (Opcode) {
692 case XtensaISD::BR_JT:
693 return "XtensaISD::BR_JT";
694 case XtensaISD::CALL:
695 return "XtensaISD::CALL";
697 return "XtensaISD::PCREL_WRAPPER";
698 case XtensaISD::RET:
699 return "XtensaISD::RET";
700 }
701 return nullptr;
702}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
uint64_t Addr
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
The address of a basic block.
Definition: Constants.h:890
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.
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:110
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...
const MachineJumpTableInfo * getJumpTableInfo() const
getJumpTableInfo - Return the jump table info object for the current function.
unsigned getEntrySize(const DataLayout &TD) const
getEntrySize - Return the size of each entry in the jump table.
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
EVT getValueType() const
Return the ValueType of the referenced return value.
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 getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
Definition: SelectionDAG.h:746
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 setOperationPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
Convenience method to set an operation to Promote and specify the type in a single call.
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:77
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 XtensaConstantPoolConstant * Create(const Constant *C, unsigned ID, XtensaCP::XtensaCPKind Kind)
static XtensaConstantPoolJumpTable * Create(LLVMContext &C, unsigned Idx)
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.
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
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:1147
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition: ISDOpcodes.h:1143
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:246
@ GlobalAddress
Definition: ISDOpcodes.h:78
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition: ISDOpcodes.h:804
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
Definition: ISDOpcodes.h:917
@ BR_CC
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:1098
@ BR_JT
BR_JT - Jumptable branch.
Definition: ISDOpcodes.h:1077
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
Definition: ISDOpcodes.h:1062
@ 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:812
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition: ISDOpcodes.h:850
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:694
@ 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:800
@ BlockAddress
Definition: ISDOpcodes.h:84
@ 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:480
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 getJumpTable(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a jump table entry.
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