LLVM 24.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 "XtensaInstrInfo.h"
19#include "XtensaSubtarget.h"
20#include "XtensaTargetMachine.h"
28#include "llvm/Support/Debug.h"
32#include <deque>
33
34using namespace llvm;
35
36#define DEBUG_TYPE "xtensa-lower"
37
38// Return true if we must use long (in fact, indirect) function call.
39// It's simplified version, production implimentation must
40// resolve a functions in ROM (usually glibc functions)
41static bool isLongCall(const char *str) {
42 // Currently always use long calls
43 return true;
44}
45
46// The calling conventions in XtensaCallingConv.td are described in terms of the
47// callee's register window. This function translates registers to the
48// corresponding caller window %o register.
49static unsigned toCallerWindow(unsigned Reg) {
50 if (Reg >= Xtensa::A2 && Reg <= Xtensa::A7)
51 return Reg - Xtensa::A2 + Xtensa::A10;
52 return Reg;
53}
54
56 const XtensaSubtarget &STI)
57 : TargetLowering(TM, STI), Subtarget(STI) {
58 MVT PtrVT = MVT::i32;
59 // Set up the register classes.
60 addRegisterClass(MVT::i32, &Xtensa::ARRegClass);
61
62 if (Subtarget.hasSingleFloat()) {
63 addRegisterClass(MVT::f32, &Xtensa::FPRRegClass);
64 }
65
66 if (Subtarget.hasBoolean()) {
67 addRegisterClass(MVT::v1i1, &Xtensa::BRRegClass);
68 }
69
70 // Set up special registers.
72
74
76
81
83
85 setOperationAction(ISD::SIGN_EXTEND_INREG, {MVT::i8, MVT::i16},
86 Subtarget.hasSEXT() ? Legal : Expand);
87
94
95 // No sign extend instructions for i1 and sign extend load i8
96 for (MVT VT : MVT::integer_valuetypes()) {
101 }
102
108
109 // Expand jump table branches as address arithmetic followed by an
110 // indirect jump.
112
114
117
121
122 if (Subtarget.hasSingleFloat()) {
125 } else {
128 }
129
132
137
138 if (Subtarget.hasMul32())
140 else
142
143 if (Subtarget.hasMul32High()) {
146 } else {
149 }
150
153
154 if (Subtarget.hasDiv32()) {
159 } else {
164 }
165
168
172
181
183 Subtarget.hasMINMAX() ? Legal : Expand);
184
185 // Implement custom stack allocations
187 // Implement custom stack save and restore
190
191 // VASTART, VAARG and VACOPY need to deal with the Xtensa-specific varargs
192 // structure, but VAEND is a no-op.
197
198 // Handle floating-point types.
199 for (unsigned I = MVT::FIRST_FP_VALUETYPE; I <= MVT::LAST_FP_VALUETYPE; ++I) {
201 if (isTypeLegal(VT)) {
202 if (VT.getSizeInBits() == 32 && Subtarget.hasSingleFloat()) {
209 } else {
216 }
217
218 // TODO: once implemented in InstrInfo uncomment
227 }
228 }
229
230 // Handle floating-point types.
231 if (Subtarget.hasSingleFloat()) {
238 } else {
245 }
246
247 for (MVT VT : MVT::fp_valuetypes()) {
248 setLoadExtAction(ISD::EXTLOAD, VT, MVT::f16, Expand);
249 }
250
255
256 // Floating-point truncation and stores need to be done separately.
257 setTruncStoreAction(MVT::f64, MVT::f32, Expand);
258 setTruncStoreAction(MVT::f64, MVT::f16, Expand);
259 setTruncStoreAction(MVT::f32, MVT::f16, Expand);
260
261 if (Subtarget.hasS32C1I()) {
264 } else if (Subtarget.hasForcedAtomics()) {
266 } else {
268 }
269
270 // Compute derived properties from the register classes
272}
273
275 ExceptionHandling EH, const Constant *PersonalityFn) const {
276 return Xtensa::A2;
277}
278
280 ExceptionHandling EH, const Constant *PersonalityFn) const {
281 return Xtensa::A3;
282}
283
285 const GlobalAddressSDNode *GA) const {
286 // The Xtensa target isn't yet aware of offsets.
287 return false;
288}
289
292 bool ForCodeSize) const {
294}
295
296//===----------------------------------------------------------------------===//
297// Inline asm support
298//===----------------------------------------------------------------------===//
301 if (Constraint.size() == 1) {
302 switch (Constraint[0]) {
303 case 'r':
304 case 'f':
305 return C_RegisterClass;
306 default:
307 break;
308 }
309 }
310 return TargetLowering::getConstraintType(Constraint);
311}
312
315 AsmOperandInfo &Info, const char *Constraint) const {
317 Value *CallOperandVal = Info.CallOperandVal;
318 // If we don't have a value, we can't do a match,
319 // but allow it at the lowest weight.
320 if (!CallOperandVal)
321 return CW_Default;
322
323 Type *Ty = CallOperandVal->getType();
324
325 // Look at the constraint type.
326 switch (*Constraint) {
327 default:
328 Weight = TargetLowering::getSingleConstraintMatchWeight(Info, Constraint);
329 break;
330 case 'r':
331 if (Ty->isIntegerTy())
332 Weight = CW_Register;
333 break;
334 case 'f':
335 if (Ty->isFloatingPointTy())
336 Weight = CW_Register;
337 break;
338 }
339 return Weight;
340}
341
342std::pair<unsigned, const TargetRegisterClass *>
344 const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
345 if (Constraint.size() == 1) {
346 // GCC Constraint Letters
347 switch (Constraint[0]) {
348 default:
349 break;
350 case 'r': // General-purpose register
351 return std::make_pair(0U, &Xtensa::ARRegClass);
352 case 'f': // Floating-point register
353 if (Subtarget.hasSingleFloat())
354 return std::make_pair(0U, &Xtensa::FPRRegClass);
355 }
356 }
358}
359
361 SDValue Op, StringRef Constraint, std::vector<SDValue> &Ops,
362 SelectionDAG &DAG) const {
363 SDLoc DL(Op);
364
365 // Only support length 1 constraints for now.
366 if (Constraint.size() > 1)
367 return;
368
370}
371
372//===----------------------------------------------------------------------===//
373// Calling conventions
374//===----------------------------------------------------------------------===//
375
376#define GET_CALLING_CONV_IMPL
377#include "XtensaGenCallingConv.inc"
378
379static const MCPhysReg IntRegs[] = {Xtensa::A2, Xtensa::A3, Xtensa::A4,
380 Xtensa::A5, Xtensa::A6, Xtensa::A7};
381
382static bool CC_Xtensa_Custom(unsigned ValNo, MVT ValVT, MVT LocVT,
383 CCValAssign::LocInfo LocInfo,
384 ISD::ArgFlagsTy ArgFlags, Type *OrigTy,
385 CCState &State) {
386 if (ArgFlags.isByVal()) {
387 Align ByValAlign = ArgFlags.getNonZeroByValAlign();
388 unsigned ByValSize = ArgFlags.getByValSize();
389 if (ByValSize < 4) {
390 ByValSize = 4;
391 }
392 if (ByValAlign < Align(4)) {
393 ByValAlign = Align(4);
394 }
395 unsigned Offset = State.AllocateStack(ByValSize, ByValAlign);
396 State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
397 // Mark all unused registers as allocated to avoid misuse
398 // of such registers.
399 while (State.AllocateReg(IntRegs))
400 ;
401 return false;
402 }
403
404 // Promote i8 and i16
405 if (LocVT == MVT::i8 || LocVT == MVT::i16) {
406 LocVT = MVT::i32;
407 if (ArgFlags.isSExt())
408 LocInfo = CCValAssign::SExt;
409 else if (ArgFlags.isZExt())
410 LocInfo = CCValAssign::ZExt;
411 else
412 LocInfo = CCValAssign::AExt;
413 }
414
415 unsigned Register;
416
417 Align OrigAlign = ArgFlags.getNonZeroOrigAlign();
418 bool needs64BitAlign = (ValVT == MVT::i32 && OrigAlign == Align(8));
419 bool needs128BitAlign = (ValVT == MVT::i32 && OrigAlign == Align(16));
420
421 if (ValVT == MVT::i32) {
422 Register = State.AllocateReg(IntRegs);
423 // If this is the first part of an i64 arg,
424 // the allocated register must be either A2, A4 or A6.
425 if (needs64BitAlign && (Register == Xtensa::A3 || Register == Xtensa::A5 ||
426 Register == Xtensa::A7))
427 Register = State.AllocateReg(IntRegs);
428 // arguments with 16byte alignment must be passed in the first register or
429 // passed via stack
430 if (needs128BitAlign && (Register != Xtensa::A2))
431 while ((Register = State.AllocateReg(IntRegs)))
432 ;
433 LocVT = MVT::i32;
434 } else if (ValVT == MVT::f64) {
435 // Allocate int register and shadow next int register.
436 Register = State.AllocateReg(IntRegs);
437 if (Register == Xtensa::A3 || Register == Xtensa::A5 ||
438 Register == Xtensa::A7)
439 Register = State.AllocateReg(IntRegs);
440 State.AllocateReg(IntRegs);
441 LocVT = MVT::i32;
442 } else {
443 report_fatal_error("Cannot handle this ValVT.");
444 }
445
446 if (!Register) {
447 unsigned Offset = State.AllocateStack(ValVT.getStoreSize(), OrigAlign);
448 State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
449 } else {
450 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Register, LocVT, LocInfo));
451 }
452
453 return false;
454}
455
456/// Return the register type for a given MVT
459 EVT VT) const {
460 if (VT.isFloatingPoint())
461 return MVT::i32;
462
463 return TargetLowering::getRegisterTypeForCallingConv(Context, CC, VT);
464}
465
466CCAssignFn *XtensaTargetLowering::CCAssignFnForCall(CallingConv::ID CC,
467 bool IsVarArg) const {
468 return CC_Xtensa_Custom;
469}
470
472 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
473 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
474 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
476 MachineFrameInfo &MFI = MF.getFrameInfo();
478
479 // Used with vargs to acumulate store chains.
480 std::vector<SDValue> OutChains;
481
482 // Assign locations to all of the incoming arguments.
484 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
485 *DAG.getContext());
486
487 CCInfo.AnalyzeFormalArguments(Ins, CCAssignFnForCall(CallConv, IsVarArg));
488
489 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
490 CCValAssign &VA = ArgLocs[i];
491 // Arguments stored on registers
492 if (VA.isRegLoc()) {
493 EVT RegVT = VA.getLocVT();
494
495 if (RegVT != MVT::i32)
496 report_fatal_error("RegVT not supported by FormalArguments Lowering");
497
498 // Transform the arguments stored on
499 // physical registers into virtual ones
500 Register Reg = 0;
501 MCRegister FrameReg = Subtarget.getRegisterInfo()->getFrameRegister(MF);
502
503 // Argument passed in FrameReg in Windowed ABI we save in A8 (in
504 // emitPrologue), so load argument from A8
505 if (Subtarget.isWindowedABI() && (VA.getLocReg() == FrameReg)) {
506 Reg = MF.addLiveIn(Xtensa::A8, &Xtensa::ARRegClass);
507 XtensaFI->setSaveFrameRegister();
508 } else {
509 Reg = MF.addLiveIn(VA.getLocReg(), &Xtensa::ARRegClass);
510 }
511
512 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, RegVT);
513
514 // If this is an 8 or 16-bit value, it has been passed promoted
515 // to 32 bits. Insert an assert[sz]ext to capture this, then
516 // truncate to the right size.
517 if (VA.getLocInfo() != CCValAssign::Full) {
518 unsigned Opcode = 0;
519 if (VA.getLocInfo() == CCValAssign::SExt)
520 Opcode = ISD::AssertSext;
521 else if (VA.getLocInfo() == CCValAssign::ZExt)
522 Opcode = ISD::AssertZext;
523 if (Opcode)
524 ArgValue = DAG.getNode(Opcode, DL, RegVT, ArgValue,
525 DAG.getValueType(VA.getValVT()));
526 ArgValue = DAG.getNode((VA.getValVT() == MVT::f32) ? ISD::BITCAST
528 DL, VA.getValVT(), ArgValue);
529 }
530
531 InVals.push_back(ArgValue);
532
533 } else {
534 assert(VA.isMemLoc());
535
536 EVT ValVT = VA.getValVT();
537
538 // The stack pointer offset is relative to the caller stack frame.
539 int FI = MFI.CreateFixedObject(ValVT.getStoreSize(), VA.getLocMemOffset(),
540 true);
541
542 if (Ins[VA.getValNo()].Flags.isByVal()) {
543 // Assume that in this case load operation is created
544 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
545 InVals.push_back(FIN);
546 } else {
547 // Create load nodes to retrieve arguments from the stack
548 SDValue FIN =
550 InVals.push_back(DAG.getLoad(
551 ValVT, DL, Chain, FIN,
553 }
554 }
555 }
556
557 if (IsVarArg) {
558 unsigned Idx = CCInfo.getFirstUnallocated(IntRegs);
559 unsigned ArgRegsNum = std::size(IntRegs);
560 const TargetRegisterClass *RC = &Xtensa::ARRegClass;
561 MachineFrameInfo &MFI = MF.getFrameInfo();
562 MachineRegisterInfo &RegInfo = MF.getRegInfo();
563 unsigned RegSize = 4;
564 MVT RegTy = MVT::i32;
565 MVT FITy = getFrameIndexTy(DAG.getDataLayout());
566
567 XtensaFI->setVarArgsFirstGPR(Idx + 2); // 2 - number of a2 register
568
570 MFI.CreateFixedObject(4, CCInfo.getStackSize(), true));
571
572 // Offset of the first variable argument from stack pointer, and size of
573 // the vararg save area. For now, the varargs save area is either zero or
574 // large enough to hold a0-a7.
575 int VaArgOffset, VarArgsSaveSize;
576
577 // If all registers are allocated, then all varargs must be passed on the
578 // stack and we don't need to save any argregs.
579 if (ArgRegsNum == Idx) {
580 VaArgOffset = CCInfo.getStackSize();
581 VarArgsSaveSize = 0;
582 } else {
583 VarArgsSaveSize = RegSize * (ArgRegsNum - Idx);
584 VaArgOffset = -VarArgsSaveSize;
585
586 // Record the frame index of the first variable argument
587 // which is a value necessary to VASTART.
588 int FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true);
589 XtensaFI->setVarArgsInRegsFrameIndex(FI);
590
591 // Copy the integer registers that may have been used for passing varargs
592 // to the vararg save area.
593 for (unsigned I = Idx; I < ArgRegsNum; ++I, VaArgOffset += RegSize) {
594 const Register Reg = RegInfo.createVirtualRegister(RC);
595 RegInfo.addLiveIn(IntRegs[I], Reg);
596
597 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, RegTy);
598 FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true);
599 SDValue PtrOff = DAG.getFrameIndex(FI, FITy);
600 SDValue Store = DAG.getStore(Chain, DL, ArgValue, PtrOff,
602 OutChains.push_back(Store);
603 }
604 }
605 }
606
607 // All stores are grouped in one node to allow the matching between
608 // the size of Ins and InVals. This only happens when on varg functions
609 if (!OutChains.empty()) {
610 OutChains.push_back(Chain);
611 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
612 }
613
614 return Chain;
615}
616
619 SmallVectorImpl<SDValue> &InVals) const {
620 SelectionDAG &DAG = CLI.DAG;
621 SDLoc &DL = CLI.DL;
623 SmallVector<SDValue, 32> &OutVals = CLI.OutVals;
625 SDValue Chain = CLI.Chain;
626 SDValue Callee = CLI.Callee;
627 bool &IsTailCall = CLI.IsTailCall;
628 CallingConv::ID CallConv = CLI.CallConv;
629 bool IsVarArg = CLI.IsVarArg;
630
632 EVT PtrVT = getPointerTy(DAG.getDataLayout());
633 const TargetFrameLowering *TFL = Subtarget.getFrameLowering();
634
635 // TODO: Support tail call optimization.
636 IsTailCall = false;
637
638 // Analyze the operands of the call, assigning locations to each operand.
640 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
641
642 CCAssignFn *CC = CCAssignFnForCall(CallConv, IsVarArg);
643
644 CCInfo.AnalyzeCallOperands(Outs, CC);
645
646 // Get a count of how many bytes are to be pushed on the stack.
647 unsigned NumBytes = CCInfo.getStackSize();
648
649 Align StackAlignment = TFL->getStackAlign();
650 unsigned NextStackOffset = alignTo(NumBytes, StackAlignment);
651
652 Chain = DAG.getCALLSEQ_START(Chain, NextStackOffset, 0, DL);
653
654 // Copy argument values to their designated locations.
655 std::deque<std::pair<unsigned, SDValue>> RegsToPass;
656 SmallVector<SDValue, 8> MemOpChains;
657 SDValue StackPtr;
658 for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) {
659 CCValAssign &VA = ArgLocs[I];
660 SDValue ArgValue = OutVals[I];
661 ISD::ArgFlagsTy Flags = Outs[I].Flags;
662
663 if (VA.isRegLoc())
664 // Queue up the argument copies and emit them at the end.
665 RegsToPass.push_back(std::make_pair(VA.getLocReg(), ArgValue));
666 else if (Flags.isByVal()) {
667 assert(VA.isMemLoc());
668 assert(Flags.getByValSize() &&
669 "ByVal args of size 0 should have been ignored by front-end.");
670 assert(!IsTailCall &&
671 "Do not tail-call optimize if there is a byval argument.");
672
673 if (!StackPtr.getNode())
674 StackPtr = DAG.getCopyFromReg(Chain, DL, Xtensa::SP, PtrVT);
675 unsigned Offset = VA.getLocMemOffset();
676 SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,
678 SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), DL, MVT::i32);
679 Align Alignment = Flags.getNonZeroByValAlign();
680 SDValue Memcpy = DAG.getMemcpy(
681 Chain, DL, Address, ArgValue, SizeNode, Alignment, Alignment,
682 /*isVolatile=*/false, /*AlwaysInline=*/false,
683 /*CI=*/nullptr, std::nullopt, MachinePointerInfo(),
685 MemOpChains.push_back(Memcpy);
686 } else {
687 assert(VA.isMemLoc() && "Argument not register or memory");
688
689 // Work out the address of the stack slot. Unpromoted ints and
690 // floats are passed as right-justified 8-byte values.
691 if (!StackPtr.getNode())
692 StackPtr = DAG.getCopyFromReg(Chain, DL, Xtensa::SP, PtrVT);
693 unsigned Offset = VA.getLocMemOffset();
694 SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,
696
697 // Emit the store.
698 MemOpChains.push_back(
699 DAG.getStore(Chain, DL, ArgValue, Address, MachinePointerInfo()));
700 }
701 }
702
703 // Join the stores, which are independent of one another.
704 if (!MemOpChains.empty())
705 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains);
706
707 // Build a sequence of copy-to-reg nodes, chained and glued together.
708 SDValue Glue;
709 for (unsigned I = 0, E = RegsToPass.size(); I != E; ++I) {
710 unsigned Reg = RegsToPass[I].first;
711 if (Subtarget.isWindowedABI())
712 Reg = toCallerWindow(Reg);
713 Chain = DAG.getCopyToReg(Chain, DL, Reg, RegsToPass[I].second, Glue);
714 Glue = Chain.getValue(1);
715 }
716 std::string name;
717 unsigned char TF = 0;
718
719 // Accept direct calls by converting symbolic call addresses to the
720 // associated Target* opcodes.
722 name = E->getSymbol();
723 TF = E->getTargetFlags();
724 if (isPositionIndependent()) {
725 report_fatal_error("PIC relocations is not supported");
726 } else
727 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, TF);
729 const GlobalValue *GV = G->getGlobal();
730 name = GV->getName().str();
731 }
732
733 if ((!name.empty()) && isLongCall(name.c_str())) {
734 // Create a constant pool entry for the callee address
736 XtensaMachineFunctionInfo *XtensaFI =
738 unsigned LabelId = XtensaFI->createCPLabelId();
739
741 *DAG.getContext(), name.c_str(), LabelId, false, Modifier);
742
743 // Get the address of the callee into a register
744 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4), 0, TF);
745 SDValue CPWrap = getAddrPCRel(CPAddr, DAG);
746 Callee = DAG.getLoad(
747 PtrVT, DL, DAG.getEntryNode(), CPWrap,
749 }
750
751 // The first call operand is the chain and the second is the target address.
753 Ops.push_back(Chain);
754 Ops.push_back(Callee);
755
756 // Add a register mask operand representing the call-preserved registers.
757 const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
758 const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv);
759 assert(Mask && "Missing call preserved mask for calling convention");
760 Ops.push_back(DAG.getRegisterMask(Mask));
761
762 // Add argument registers to the end of the list so that they are
763 // known live into the call.
764 for (unsigned I = 0, E = RegsToPass.size(); I != E; ++I) {
765 unsigned Reg = RegsToPass[I].first;
766 if (Subtarget.isWindowedABI())
767 Reg = toCallerWindow(Reg);
768 Ops.push_back(DAG.getRegister(Reg, RegsToPass[I].second.getValueType()));
769 }
770
771 // Glue the call to the argument copies, if any.
772 if (Glue.getNode())
773 Ops.push_back(Glue);
774
775 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
776 Chain = DAG.getNode(Subtarget.isWindowedABI() ? XtensaISD::CALLW8
777 : XtensaISD::CALL,
778 DL, NodeTys, Ops);
779 Glue = Chain.getValue(1);
780
781 // Mark the end of the call, which is glued to the call itself.
782 Chain = DAG.getCALLSEQ_END(Chain, DAG.getConstant(NumBytes, DL, PtrVT, true),
783 DAG.getConstant(0, DL, PtrVT, true), Glue, DL);
784 Glue = Chain.getValue(1);
785
786 // Assign locations to each value returned by this call.
788 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, *DAG.getContext());
789 RetCCInfo.AnalyzeCallResult(Ins, Subtarget.isWindowedABI() ? RetCCW8_Xtensa
790 : RetCC_Xtensa);
791
792 // Copy all of the result registers out of their specified physreg.
793 for (unsigned I = 0, E = RetLocs.size(); I != E; ++I) {
794 CCValAssign &VA = RetLocs[I];
795
796 // Copy the value out, gluing the copy to the end of the call sequence.
797 unsigned Reg = VA.getLocReg();
798 SDValue RetValue = DAG.getCopyFromReg(Chain, DL, Reg, VA.getLocVT(), Glue);
799 Chain = RetValue.getValue(1);
800 Glue = RetValue.getValue(2);
801
802 InVals.push_back(RetValue);
803 }
804 return Chain;
805}
806
808 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
809 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
810 const Type *RetTy) const {
812 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
813 return CCInfo.CheckReturn(Outs, RetCC_Xtensa);
814}
815
818 bool IsVarArg,
820 const SmallVectorImpl<SDValue> &OutVals,
821 const SDLoc &DL, SelectionDAG &DAG) const {
823
824 // Assign locations to each returned value.
826 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, *DAG.getContext());
827 RetCCInfo.AnalyzeReturn(Outs, RetCC_Xtensa);
828
829 SDValue Glue;
830 // Quick exit for void returns
831 if (RetLocs.empty())
832 return DAG.getNode(Subtarget.isWindowedABI() ? XtensaISD::RETW
833 : XtensaISD::RET,
834 DL, MVT::Other, Chain);
835
836 // Copy the result values into the output registers.
838 RetOps.push_back(Chain);
839 for (unsigned I = 0, E = RetLocs.size(); I != E; ++I) {
840 CCValAssign &VA = RetLocs[I];
841 SDValue RetValue = OutVals[I];
842
843 // Make the return register live on exit.
844 assert(VA.isRegLoc() && "Can only return in registers!");
845
846 // Chain and glue the copies together.
847 unsigned Register = VA.getLocReg();
848 Chain = DAG.getCopyToReg(Chain, DL, Register, RetValue, Glue);
849 Glue = Chain.getValue(1);
850 RetOps.push_back(DAG.getRegister(Register, VA.getLocVT()));
851 }
852
853 // Update chain and glue.
854 RetOps[0] = Chain;
855 if (Glue.getNode())
856 RetOps.push_back(Glue);
857
858 return DAG.getNode(Subtarget.isWindowedABI() ? XtensaISD::RETW
859 : XtensaISD::RET,
860 DL, MVT::Other, RetOps);
861}
862
864 switch (Cond) {
865 case ISD::SETEQ:
866 return Xtensa::BEQ;
867 case ISD::SETNE:
868 return Xtensa::BNE;
869 case ISD::SETLT:
870 return Xtensa::BLT;
871 case ISD::SETLE:
872 return Xtensa::BGE;
873 case ISD::SETGT:
874 return Xtensa::BLT;
875 case ISD::SETGE:
876 return Xtensa::BGE;
877 case ISD::SETULT:
878 return Xtensa::BLTU;
879 case ISD::SETULE:
880 return Xtensa::BGEU;
881 case ISD::SETUGT:
882 return Xtensa::BLTU;
883 case ISD::SETUGE:
884 return Xtensa::BGEU;
885 default:
886 llvm_unreachable("Unknown branch kind");
887 }
888}
889
890static std::pair<unsigned, unsigned> getFPBranchKind(ISD::CondCode Cond) {
891 switch (Cond) {
892 case ISD::SETUNE:
893 return std::make_pair(Xtensa::BF, Xtensa::OEQ_S);
894 case ISD::SETUO:
895 return std::make_pair(Xtensa::BT, Xtensa::UN_S);
896 case ISD::SETO:
897 return std::make_pair(Xtensa::BF, Xtensa::UN_S);
898 case ISD::SETUEQ:
899 return std::make_pair(Xtensa::BT, Xtensa::UEQ_S);
900 case ISD::SETULE:
901 return std::make_pair(Xtensa::BT, Xtensa::ULE_S);
902 case ISD::SETULT:
903 return std::make_pair(Xtensa::BT, Xtensa::ULT_S);
904 case ISD::SETEQ:
905 case ISD::SETOEQ:
906 return std::make_pair(Xtensa::BT, Xtensa::OEQ_S);
907 case ISD::SETNE:
908 return std::make_pair(Xtensa::BF, Xtensa::OEQ_S);
909 case ISD::SETLE:
910 case ISD::SETOLE:
911 return std::make_pair(Xtensa::BT, Xtensa::OLE_S);
912 case ISD::SETLT:
913 case ISD::SETOLT:
914 return std::make_pair(Xtensa::BT, Xtensa::OLT_S);
915 case ISD::SETGE:
916 return std::make_pair(Xtensa::BF, Xtensa::OLT_S);
917 case ISD::SETGT:
918 return std::make_pair(Xtensa::BF, Xtensa::OLE_S);
919 case ISD::SETOGT:
920 return std::make_pair(Xtensa::BF, Xtensa::ULE_S);
921 case ISD::SETOGE:
922 return std::make_pair(Xtensa::BF, Xtensa::ULT_S);
923 case ISD::SETONE:
924 return std::make_pair(Xtensa::BF, Xtensa::UEQ_S);
925 case ISD::SETUGT:
926 return std::make_pair(Xtensa::BF, Xtensa::OLE_S);
927 case ISD::SETUGE:
928 return std::make_pair(Xtensa::BF, Xtensa::OLT_S);
929 default:
930 llvm_unreachable("Invalid condition!");
931 }
932}
933
934SDValue XtensaTargetLowering::LowerSELECT_CC(SDValue Op,
935 SelectionDAG &DAG) const {
936 SDLoc DL(Op);
937 EVT Ty = Op.getValueType();
938 SDValue LHS = Op.getOperand(0);
939 SDValue RHS = Op.getOperand(1);
940 SDValue TrueValue = Op.getOperand(2);
941 SDValue FalseValue = Op.getOperand(3);
942 ISD::CondCode CC = cast<CondCodeSDNode>(Op->getOperand(4))->get();
943
944 if (LHS.getValueType() == MVT::i32) {
945 unsigned BrOpcode = getBranchOpcode(CC);
946 SDValue TargetCC = DAG.getConstant(BrOpcode, DL, MVT::i32);
947
948 SDValue Res = DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, LHS, RHS, TrueValue,
949 FalseValue, TargetCC, Op->getFlags());
950 return Res;
951 }
952 assert(LHS.getValueType() == MVT::f32 &&
953 "We expect MVT::f32 type of the LHS Operand in SELECT_CC");
954 unsigned BrOpcode;
955 unsigned CmpOpCode;
956 std::tie(BrOpcode, CmpOpCode) = getFPBranchKind(CC);
957 SDValue TargetCC = DAG.getConstant(CmpOpCode, DL, MVT::i32);
958 SDValue TargetBC = DAG.getConstant(BrOpcode, DL, MVT::i32);
959 return DAG.getNode(XtensaISD::SELECT_CC_FP, DL, Ty,
960 {LHS, RHS, TrueValue, FalseValue, TargetCC, TargetBC},
961 Op->getFlags());
962}
963
964SDValue XtensaTargetLowering::LowerRETURNADDR(SDValue Op,
965 SelectionDAG &DAG) const {
966 // This nodes represent llvm.returnaddress on the DAG.
967 // It takes one operand, the index of the return address to return.
968 // An index of zero corresponds to the current function's return address.
969 // An index of one to the parent's return address, and so on.
970 // Depths > 0 not supported yet!
971 if (Op.getConstantOperandVal(0) != 0)
972 return SDValue();
973
975 MachineFrameInfo &MFI = MF.getFrameInfo();
976 EVT VT = Op.getValueType();
977 MFI.setReturnAddressIsTaken(true);
978
979 // Return RA, which contains the return address. Mark it an implicit
980 // live-in.
981 Register RA = MF.addLiveIn(Xtensa::A0, getRegClassFor(MVT::i32));
982 return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), RA, VT);
983}
984
985SDValue XtensaTargetLowering::LowerImmediate(SDValue Op,
986 SelectionDAG &DAG) const {
987 const ConstantSDNode *CN = cast<ConstantSDNode>(Op);
988 SDLoc DL(CN);
989 APInt APVal = CN->getAPIntValue();
990 int64_t Value = APVal.getSExtValue();
991 if (Op.getValueType() == MVT::i32) {
992 // Check if use node maybe lowered to the MOVI instruction
993 if (Value > -2048 && Value <= 2047)
994 return Op;
995 // Check if use node maybe lowered to the ADDMI instruction
996 SDNode &OpNode = *Op.getNode();
997 if ((OpNode.hasOneUse() && OpNode.user_begin()->getOpcode() == ISD::ADD) &&
999 return Op;
1000 Type *Ty = Type::getInt32Ty(*DAG.getContext());
1002 SDValue CP = DAG.getConstantPool(CV, MVT::i32);
1003 SDValue Res =
1004 DAG.getLoad(MVT::i32, DL, DAG.getEntryNode(), CP, MachinePointerInfo());
1005 return Res;
1006 }
1007 return Op;
1008}
1009
1010SDValue XtensaTargetLowering::LowerGlobalAddress(SDValue Op,
1011 SelectionDAG &DAG) const {
1012 const GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(Op);
1013 SDLoc DL(Op);
1014 auto PtrVT = Op.getValueType();
1015 const GlobalValue *GV = G->getGlobal();
1016
1017 SDValue CPAddr = DAG.getTargetConstantPool(GV, PtrVT, Align(4));
1018 SDValue CPWrap = getAddrPCRel(CPAddr, DAG);
1019 SDValue Res = DAG.getLoad(
1020 PtrVT, DL, DAG.getEntryNode(), CPWrap,
1022 return Res;
1023}
1024
1025SDValue XtensaTargetLowering::LowerGlobalTLSAddress(SDValue Op,
1026 SelectionDAG &DAG) const {
1027 const GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(Op);
1028 SDLoc DL(Op);
1029 EVT PtrVT = Op.getValueType();
1030 const GlobalValue *GV = G->getGlobal();
1031
1032 if (DAG.getTarget().useEmulatedTLS())
1033 return LowerToTLSEmulatedModel(G, DAG);
1034
1036
1037 if (!Subtarget.hasTHREADPTR()) {
1038 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
1039 DAG.getMachineFunction().getFunction(), "only emulated TLS supported",
1040 DL.getDebugLoc()));
1041 return DAG.getPOISON(Op->getValueType(0));
1042 }
1043
1044 if (model == TLSModel::LocalExec || model == TLSModel::InitialExec) {
1045 bool Priv = GV->isPrivateLinkage(GV->getLinkage());
1047 XtensaMachineFunctionInfo *XtensaFI =
1048 MF.getInfo<XtensaMachineFunctionInfo>();
1049 unsigned LabelId = XtensaFI->createCPLabelId();
1050
1051 // Create a constant pool entry for the callee address
1052 XtensaConstantPoolValue *CPV = XtensaConstantPoolSymbol::Create(
1053 *DAG.getContext(), GV->getName().str().c_str(), LabelId, Priv,
1055
1056 // Get the address of the callee into a register
1057 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
1058 SDValue CPWrap = getAddrPCRel(CPAddr, DAG);
1059 SDValue Addr = DAG.getLoad(
1060 PtrVT, DL, DAG.getEntryNode(), CPWrap,
1062
1063 SDValue TPRegister = DAG.getRegister(Xtensa::THREADPTR, MVT::i32);
1064 SDValue ThreadPointer =
1065 DAG.getNode(XtensaISD::RUR, DL, MVT::i32, TPRegister);
1066
1067 return DAG.getNode(ISD::ADD, DL, PtrVT, ThreadPointer, Addr);
1068 }
1069
1070 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
1072 "only local-exec and initial-exec TLS mode supported", DL.getDebugLoc()));
1073
1074 return DAG.getPOISON(Op->getValueType(0));
1075}
1076
1077SDValue XtensaTargetLowering::LowerBlockAddress(SDValue Op,
1078 SelectionDAG &DAG) const {
1079 BlockAddressSDNode *Node = cast<BlockAddressSDNode>(Op);
1080 SDLoc DL(Op);
1081 const BlockAddress *BA = Node->getBlockAddress();
1082 EVT PtrVT = Op.getValueType();
1084 XtensaMachineFunctionInfo *XtensaFI = MF.getInfo<XtensaMachineFunctionInfo>();
1085 unsigned LabelId = XtensaFI->createCPLabelId();
1086
1087 XtensaConstantPoolValue *CPV =
1089 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
1090 SDValue CPWrap = getAddrPCRel(CPAddr, DAG);
1091 SDValue Res = DAG.getLoad(
1092 PtrVT, DL, DAG.getEntryNode(), CPWrap,
1094 return Res;
1095}
1096
1097SDValue XtensaTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) const {
1098 SDValue Chain = Op.getOperand(0);
1099 SDValue Table = Op.getOperand(1);
1100 SDValue Index = Op.getOperand(2);
1101 SDLoc DL(Op);
1102 JumpTableSDNode *JT = cast<JumpTableSDNode>(Table);
1104 const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
1105 SDValue TargetJT = DAG.getTargetJumpTable(JT->getIndex(), MVT::i32);
1106 const DataLayout &TD = DAG.getDataLayout();
1107 EVT PtrVT = Table.getValueType();
1108 unsigned EntrySize = MJTI->getEntrySize(TD);
1109
1110 assert((MJTI->getEntrySize(TD) == 4) && "Unsupported jump-table entry size");
1111
1112 Index = DAG.getNode(
1113 ISD::SHL, DL, Index.getValueType(), Index,
1114 DAG.getConstant(Log2_32(EntrySize), DL, Index.getValueType()));
1115
1116 SDValue Addr = DAG.getNode(ISD::ADD, DL, Index.getValueType(), Index, Table);
1117 SDValue LD =
1118 DAG.getLoad(PtrVT, DL, Chain, Addr,
1120
1121 return DAG.getNode(XtensaISD::BR_JT, DL, MVT::Other, LD.getValue(1), LD,
1122 TargetJT);
1123}
1124
1125SDValue XtensaTargetLowering::LowerJumpTable(SDValue Op,
1126 SelectionDAG &DAG) const {
1127 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
1128 EVT PtrVT = Op.getValueType();
1129 SDLoc DL(Op);
1130
1131 // Create a constant pool entry for the jumptable address
1132 XtensaConstantPoolValue *CPV =
1134
1135 // Get the address of the jumptable into a register
1136 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
1137
1138 SDValue Res = DAG.getLoad(
1139 PtrVT, DL, DAG.getEntryNode(), getAddrPCRel(CPAddr, DAG),
1141 return Res;
1142}
1143
1144SDValue XtensaTargetLowering::getAddrPCRel(SDValue Op,
1145 SelectionDAG &DAG) const {
1146 SDLoc DL(Op);
1147 EVT Ty = Op.getValueType();
1148 return DAG.getNode(XtensaISD::PCREL_WRAPPER, DL, Ty, Op);
1149}
1150
1151SDValue XtensaTargetLowering::LowerConstantPool(SDValue Op,
1152 SelectionDAG &DAG) const {
1153 EVT PtrVT = Op.getValueType();
1154 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
1155 SDValue Result;
1156
1157 if (!CP->isMachineConstantPoolEntry()) {
1158 Result = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, CP->getAlign(),
1159 CP->getOffset());
1160 } else {
1161 report_fatal_error("This constantpool type is not supported yet");
1162 }
1163
1164 return getAddrPCRel(Result, DAG);
1165}
1166
1167SDValue XtensaTargetLowering::LowerSTACKSAVE(SDValue Op,
1168 SelectionDAG &DAG) const {
1169 return DAG.getCopyFromReg(Op.getOperand(0), SDLoc(Op), Xtensa::SP,
1170 Op.getValueType());
1171}
1172
1173SDValue XtensaTargetLowering::LowerSTACKRESTORE(SDValue Op,
1174 SelectionDAG &DAG) const {
1175 SDValue Chain = Op.getOperand(0);
1176 SDValue NewSP = Op.getOperand(1);
1177
1178 if (Subtarget.isWindowedABI()) {
1179 return DAG.getNode(XtensaISD::MOVSP, SDLoc(Op), MVT::Other, Chain, NewSP);
1180 }
1181
1182 return DAG.getCopyToReg(Chain, SDLoc(Op), Xtensa::SP, NewSP);
1183}
1184
1185SDValue XtensaTargetLowering::LowerFRAMEADDR(SDValue Op,
1186 SelectionDAG &DAG) const {
1187 // This nodes represent llvm.frameaddress on the DAG.
1188 // It takes one operand, the index of the frame address to return.
1189 // An index of zero corresponds to the current function's frame address.
1190 // An index of one to the parent's frame address, and so on.
1191 // Depths > 0 not supported yet!
1192 if (Op.getConstantOperandVal(0) != 0)
1193 return SDValue();
1194
1196 MachineFrameInfo &MFI = MF.getFrameInfo();
1197 MFI.setFrameAddressIsTaken(true);
1198 EVT VT = Op.getValueType();
1199 SDLoc DL(Op);
1200
1201 MCRegister FrameRegister = Subtarget.getRegisterInfo()->getFrameRegister(MF);
1202 SDValue FrameAddr =
1203 DAG.getCopyFromReg(DAG.getEntryNode(), DL, FrameRegister, VT);
1204 return FrameAddr;
1205}
1206
1207SDValue XtensaTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
1208 SelectionDAG &DAG) const {
1209 SDValue Chain = Op.getOperand(0); // Legalize the chain.
1210 SDValue Size = Op.getOperand(1); // Legalize the size.
1211 EVT VT = Size->getValueType(0);
1212 SDLoc DL(Op);
1213
1214 // Round up Size to 32
1215 SDValue SizeTmp =
1216 DAG.getNode(ISD::ADD, DL, VT, Size, DAG.getConstant(31, DL, MVT::i32));
1217 SDValue SizeRoundUp = DAG.getNode(ISD::AND, DL, VT, SizeTmp,
1218 DAG.getSignedConstant(~31, DL, MVT::i32));
1219
1220 MCRegister SPReg = Xtensa::SP;
1221 SDValue SP = DAG.getCopyFromReg(Chain, DL, SPReg, VT);
1222 SDValue NewSP = DAG.getNode(ISD::SUB, DL, VT, SP, SizeRoundUp); // Value
1223 if (Subtarget.isWindowedABI()) {
1224 Chain = DAG.getNode(XtensaISD::MOVSP, SDLoc(Op), MVT::Other, SP.getValue(1),
1225 NewSP);
1226 } else {
1227 Chain = DAG.getCopyToReg(SP.getValue(1), DL, SPReg, NewSP); // Output chain
1228 }
1229
1230 SDValue NewVal = DAG.getCopyFromReg(Chain, DL, SPReg, MVT::i32);
1231 Chain = NewVal.getValue(1);
1232
1233 SDValue Ops[2] = {NewVal, Chain};
1234 return DAG.getMergeValues(Ops, DL);
1235}
1236
1237SDValue XtensaTargetLowering::LowerVASTART(SDValue Op,
1238 SelectionDAG &DAG) const {
1240 XtensaMachineFunctionInfo *XtensaFI = MF.getInfo<XtensaMachineFunctionInfo>();
1241 SDValue Chain = Op.getOperand(0);
1242 SDValue Addr = Op.getOperand(1);
1243 EVT PtrVT = Addr.getValueType();
1244 SDLoc DL(Op);
1245
1246 // Struct va_list_tag
1247 // int32 *va_stk - points to the arguments passed in memory
1248 // int32 *va_reg - points to the registers with arguments saved in memory
1249 // int32 va_ndx - offset from va_stk or va_reg pointers which points to the
1250 // next variable argument
1251
1252 SDValue VAIndex;
1253 SDValue StackOffsetFI =
1254 DAG.getFrameIndex(XtensaFI->getVarArgsOnStackFrameIndex(), PtrVT);
1255 unsigned ArgWords = XtensaFI->getVarArgsFirstGPR() - 2;
1256
1257 // If first variable argument passed in registers (maximum words in registers
1258 // is 6) then set va_ndx to the position of this argument in registers area
1259 // stored in memory (va_reg pointer). Otherwise va_ndx should point to the
1260 // position of the first variable argument on stack (va_stk pointer).
1261 if (ArgWords < 6) {
1262 VAIndex = DAG.getConstant(ArgWords * 4, DL, MVT::i32);
1263 } else {
1264 VAIndex = DAG.getConstant(32, DL, MVT::i32);
1265 }
1266
1267 SDValue FrameIndex =
1268 DAG.getFrameIndex(XtensaFI->getVarArgsInRegsFrameIndex(), PtrVT);
1269 uint64_t FrameOffset = PtrVT.getStoreSize();
1270 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
1271
1272 // Store pointer to arguments given on stack (va_stk)
1273 SDValue StackPtr = DAG.getNode(ISD::SUB, DL, PtrVT, StackOffsetFI,
1274 DAG.getConstant(32, DL, PtrVT));
1275
1276 SDValue StoreStackPtr =
1277 DAG.getStore(Chain, DL, StackPtr, Addr, MachinePointerInfo(SV));
1278
1279 uint64_t NextOffset = FrameOffset;
1280 SDValue NextPtr =
1281 DAG.getObjectPtrOffset(DL, Addr, TypeSize::getFixed(NextOffset));
1282
1283 // Store pointer to arguments given on registers (va_reg)
1284 SDValue StoreRegPtr = DAG.getStore(StoreStackPtr, DL, FrameIndex, NextPtr,
1285 MachinePointerInfo(SV, NextOffset));
1286 NextOffset += FrameOffset;
1287 NextPtr = DAG.getObjectPtrOffset(DL, Addr, TypeSize::getFixed(NextOffset));
1288
1289 // Store third word : position in bytes of the first VA argument (va_ndx)
1290 return DAG.getStore(StoreRegPtr, DL, VAIndex, NextPtr,
1291 MachinePointerInfo(SV, NextOffset));
1292}
1293
1294SDValue XtensaTargetLowering::LowerVACOPY(SDValue Op, SelectionDAG &DAG) const {
1295 // Size of the va_list_tag structure
1296 constexpr unsigned VAListSize = 3 * 4;
1297 SDValue Chain = Op.getOperand(0);
1298 SDValue DstPtr = Op.getOperand(1);
1299 SDValue SrcPtr = Op.getOperand(2);
1300 const Value *DstSV = cast<SrcValueSDNode>(Op.getOperand(3))->getValue();
1301 const Value *SrcSV = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
1302 SDLoc DL(Op);
1303
1304 return DAG.getMemcpy(Chain, DL, DstPtr, SrcPtr,
1305 DAG.getConstant(VAListSize, SDLoc(Op), MVT::i32),
1306 Align(4), Align(4), /*isVolatile*/ false,
1307 /*AlwaysInline*/ true,
1308 /*CI=*/nullptr, std::nullopt, MachinePointerInfo(DstSV),
1309 MachinePointerInfo(SrcSV));
1310}
1311
1312SDValue XtensaTargetLowering::LowerVAARG(SDValue Op, SelectionDAG &DAG) const {
1313 SDNode *Node = Op.getNode();
1314 EVT VT = Node->getValueType(0);
1315 Type *Ty = VT.getTypeForEVT(*DAG.getContext());
1316 EVT PtrVT = Op.getValueType();
1317 SDValue InChain = Node->getOperand(0);
1318 SDValue VAListPtr = Node->getOperand(1);
1319 const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
1320 SDLoc DL(Node);
1321 auto &TD = DAG.getDataLayout();
1322 Align ArgAlignment = TD.getABITypeAlign(Ty);
1323 unsigned ArgAlignInBytes = ArgAlignment.value();
1324 unsigned ArgSizeInBytes = TD.getTypeAllocSize(Ty);
1325 unsigned VASizeInBytes = llvm::alignTo(ArgSizeInBytes, 4);
1326
1327 // va_stk
1328 SDValue VAStack =
1329 DAG.getLoad(MVT::i32, DL, InChain, VAListPtr, MachinePointerInfo());
1330 InChain = VAStack.getValue(1);
1331
1332 // va_reg
1333 SDValue VARegPtr =
1334 DAG.getObjectPtrOffset(DL, VAListPtr, TypeSize::getFixed(4));
1335 SDValue VAReg =
1336 DAG.getLoad(MVT::i32, DL, InChain, VARegPtr, MachinePointerInfo());
1337 InChain = VAReg.getValue(1);
1338
1339 // va_ndx
1340 SDValue VarArgIndexPtr =
1341 DAG.getObjectPtrOffset(DL, VARegPtr, TypeSize::getFixed(4));
1342 SDValue VAIndex =
1343 DAG.getLoad(MVT::i32, DL, InChain, VarArgIndexPtr, MachinePointerInfo());
1344 InChain = VAIndex.getValue(1);
1345
1346 SDValue OrigIndex = VAIndex;
1347
1348 if (ArgAlignInBytes > 4) {
1349 OrigIndex = DAG.getNode(ISD::ADD, DL, PtrVT, OrigIndex,
1350 DAG.getConstant(ArgAlignInBytes - 1, DL, MVT::i32));
1351 OrigIndex =
1352 DAG.getNode(ISD::AND, DL, PtrVT, OrigIndex,
1353 DAG.getSignedConstant(-ArgAlignInBytes, DL, MVT::i32));
1354 }
1355
1356 VAIndex = DAG.getNode(ISD::ADD, DL, PtrVT, OrigIndex,
1357 DAG.getConstant(VASizeInBytes, DL, MVT::i32));
1358
1359 SDValue CC = DAG.getSetCC(DL, MVT::i32, OrigIndex,
1360 DAG.getConstant(6 * 4, DL, MVT::i32), ISD::SETLE);
1361
1362 SDValue StkIndex =
1363 DAG.getNode(ISD::ADD, DL, PtrVT, VAIndex,
1364 DAG.getConstant(32 + VASizeInBytes, DL, MVT::i32));
1365
1366 CC = DAG.getSetCC(DL, MVT::i32, VAIndex, DAG.getConstant(6 * 4, DL, MVT::i32),
1367 ISD::SETLE);
1368
1369 SDValue Array = DAG.getNode(ISD::SELECT, DL, MVT::i32, CC, VAReg, VAStack);
1370
1371 VAIndex = DAG.getNode(ISD::SELECT, DL, MVT::i32, CC, VAIndex, StkIndex);
1372
1373 CC = DAG.getSetCC(DL, MVT::i32, VAIndex, DAG.getConstant(6 * 4, DL, MVT::i32),
1374 ISD::SETLE);
1375
1376 SDValue VAIndexStore = DAG.getStore(InChain, DL, VAIndex, VarArgIndexPtr,
1377 MachinePointerInfo(SV));
1378 InChain = VAIndexStore;
1379
1380 SDValue Addr = DAG.getNode(ISD::SUB, DL, PtrVT, VAIndex,
1381 DAG.getConstant(VASizeInBytes, DL, MVT::i32));
1382
1383 Addr = DAG.getNode(ISD::ADD, DL, PtrVT, Array, Addr);
1384
1385 return DAG.getLoad(VT, DL, InChain, Addr, MachinePointerInfo());
1386}
1387
1388SDValue XtensaTargetLowering::LowerShiftLeftParts(SDValue Op,
1389 SelectionDAG &DAG) const {
1390 SDLoc DL(Op);
1391 MVT VT = MVT::i32;
1392 SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1);
1393 SDValue Shamt = Op.getOperand(2);
1394
1395 // if Shamt - register size < 0: // Shamt < register size
1396 // Lo = Lo << Shamt
1397 // Hi = (Hi << Shamt) | (Lo >>u (register size - Shamt))
1398 // else:
1399 // Lo = 0
1400 // Hi = Lo << (Shamt - register size)
1401
1402 SDValue MinusRegisterSize = DAG.getSignedConstant(-32, DL, VT);
1403 SDValue ShamtMinusRegisterSize =
1404 DAG.getNode(ISD::ADD, DL, VT, Shamt, MinusRegisterSize);
1405
1406 SDValue LoTrue = DAG.getNode(ISD::SHL, DL, VT, Lo, Shamt);
1407 SDValue HiTrue = DAG.getNode(XtensaISD::SRCL, DL, VT, Hi, Lo, Shamt);
1408 SDValue Zero = DAG.getConstant(0, DL, VT);
1409 SDValue HiFalse = DAG.getNode(ISD::SHL, DL, VT, Lo, ShamtMinusRegisterSize);
1410
1411 SDValue Cond = DAG.getSetCC(DL, VT, ShamtMinusRegisterSize, Zero, ISD::SETLT);
1412 Lo = DAG.getNode(ISD::SELECT, DL, VT, Cond, LoTrue, Zero);
1413 Hi = DAG.getNode(ISD::SELECT, DL, VT, Cond, HiTrue, HiFalse);
1414
1415 return DAG.getMergeValues({Lo, Hi}, DL);
1416}
1417
1418SDValue XtensaTargetLowering::LowerShiftRightParts(SDValue Op,
1419 SelectionDAG &DAG,
1420 bool IsSRA) const {
1421 SDLoc DL(Op);
1422 SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1);
1423 SDValue Shamt = Op.getOperand(2);
1424 MVT VT = MVT::i32;
1425
1426 // SRA expansion:
1427 // if Shamt - register size < 0: // Shamt < register size
1428 // Lo = (Lo >>u Shamt) | (Hi << u (register size - Shamt))
1429 // Hi = Hi >>s Shamt
1430 // else:
1431 // Lo = Hi >>s (Shamt - register size);
1432 // Hi = Hi >>s (register size - 1)
1433 //
1434 // SRL expansion:
1435 // if Shamt - register size < 0: // Shamt < register size
1436 // Lo = (Lo >>u Shamt) | (Hi << u (register size - Shamt))
1437 // Hi = Hi >>u Shamt
1438 // else:
1439 // Lo = Hi >>u (Shamt - register size);
1440 // Hi = 0;
1441
1442 unsigned ShiftRightOp = IsSRA ? ISD::SRA : ISD::SRL;
1443 SDValue MinusRegisterSize = DAG.getSignedConstant(-32, DL, VT);
1444 SDValue RegisterSizeMinus1 = DAG.getConstant(32 - 1, DL, VT);
1445 SDValue ShamtMinusRegisterSize =
1446 DAG.getNode(ISD::ADD, DL, VT, Shamt, MinusRegisterSize);
1447
1448 SDValue LoTrue = DAG.getNode(XtensaISD::SRCR, DL, VT, Hi, Lo, Shamt);
1449 SDValue HiTrue = DAG.getNode(ShiftRightOp, DL, VT, Hi, Shamt);
1450 SDValue Zero = DAG.getConstant(0, DL, VT);
1451 SDValue LoFalse =
1452 DAG.getNode(ShiftRightOp, DL, VT, Hi, ShamtMinusRegisterSize);
1453 SDValue HiFalse;
1454
1455 if (IsSRA) {
1456 HiFalse = DAG.getNode(ShiftRightOp, DL, VT, Hi, RegisterSizeMinus1);
1457 } else {
1458 HiFalse = Zero;
1459 }
1460
1461 SDValue Cond = DAG.getSetCC(DL, VT, ShamtMinusRegisterSize, Zero, ISD::SETLT);
1462 Lo = DAG.getNode(ISD::SELECT, DL, VT, Cond, LoTrue, LoFalse);
1463 Hi = DAG.getNode(ISD::SELECT, DL, VT, Cond, HiTrue, HiFalse);
1464
1465 return DAG.getMergeValues({Lo, Hi}, DL);
1466}
1467
1468SDValue XtensaTargetLowering::LowerCTPOP(SDValue Op, SelectionDAG &DAG) const {
1469 auto &TLI = DAG.getTargetLoweringInfo();
1470 return TLI.expandCTPOP(Op.getNode(), DAG);
1471}
1472
1474 SDValue C) const {
1475 APInt Imm;
1476 unsigned EltSizeInBits;
1477
1478 if (ISD::isConstantSplatVector(C.getNode(), Imm)) {
1479 EltSizeInBits = VT.getScalarSizeInBits();
1480 } else if (VT.isScalarInteger()) {
1481 EltSizeInBits = VT.getSizeInBits();
1482 if (auto *ConstNode = dyn_cast<ConstantSDNode>(C.getNode()))
1483 Imm = ConstNode->getAPIntValue();
1484 else
1485 return false;
1486 } else {
1487 return false;
1488 }
1489
1490 // Omit if data size exceeds.
1491 if (EltSizeInBits > 32)
1492 return false;
1493
1494 // Convert MULT to LSL.
1495 if (Imm.isPowerOf2() && Imm.isIntN(5))
1496 return true;
1497
1498 return false;
1499}
1500
1502 SelectionDAG &DAG) const {
1503 switch (Op.getOpcode()) {
1504 case ISD::BR_JT:
1505 return LowerBR_JT(Op, DAG);
1506 case ISD::Constant:
1507 return LowerImmediate(Op, DAG);
1508 case ISD::RETURNADDR:
1509 return LowerRETURNADDR(Op, DAG);
1510 case ISD::GlobalAddress:
1511 return LowerGlobalAddress(Op, DAG);
1513 return LowerGlobalTLSAddress(Op, DAG);
1514 case ISD::BlockAddress:
1515 return LowerBlockAddress(Op, DAG);
1516 case ISD::JumpTable:
1517 return LowerJumpTable(Op, DAG);
1518 case ISD::CTPOP:
1519 return LowerCTPOP(Op, DAG);
1520 case ISD::ConstantPool:
1521 return LowerConstantPool(Op, DAG);
1522 case ISD::SELECT_CC:
1523 return LowerSELECT_CC(Op, DAG);
1524 case ISD::STACKSAVE:
1525 return LowerSTACKSAVE(Op, DAG);
1526 case ISD::STACKRESTORE:
1527 return LowerSTACKRESTORE(Op, DAG);
1528 case ISD::FRAMEADDR:
1529 return LowerFRAMEADDR(Op, DAG);
1531 return LowerDYNAMIC_STACKALLOC(Op, DAG);
1532 case ISD::VASTART:
1533 return LowerVASTART(Op, DAG);
1534 case ISD::VAARG:
1535 return LowerVAARG(Op, DAG);
1536 case ISD::VACOPY:
1537 return LowerVACOPY(Op, DAG);
1538 case ISD::SHL_PARTS:
1539 return LowerShiftLeftParts(Op, DAG);
1540 case ISD::SRA_PARTS:
1541 return LowerShiftRightParts(Op, DAG, true);
1542 case ISD::SRL_PARTS:
1543 return LowerShiftRightParts(Op, DAG, false);
1544 default:
1545 report_fatal_error("Unexpected node to lower");
1546 }
1547}
1548
1553
1554//===----------------------------------------------------------------------===//
1555// Custom insertion
1556//===----------------------------------------------------------------------===//
1557
1559XtensaTargetLowering::emitSelectCC(MachineInstr &MI,
1560 MachineBasicBlock *MBB) const {
1561 const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
1562 DebugLoc DL = MI.getDebugLoc();
1563
1564 MachineOperand &LHS = MI.getOperand(1);
1565 MachineOperand &RHS = MI.getOperand(2);
1566 MachineOperand &TrueValue = MI.getOperand(3);
1567 MachineOperand &FalseValue = MI.getOperand(4);
1568
1569 // To "insert" a SELECT_CC instruction, we actually have to insert
1570 // CopyMBB and SinkMBB blocks and add branch to MBB. We build phi
1571 // operation in SinkMBB like phi (TrueVakue,FalseValue), where TrueValue
1572 // is passed from MMB and FalseValue is passed from CopyMBB.
1573 // MBB
1574 // | \
1575 // | CopyMBB
1576 // | /
1577 // SinkMBB
1578 // The incoming instruction knows the
1579 // destination vreg to set, the condition code register to branch on, the
1580 // true/false values to select between, and a branch opcode to use.
1581 const BasicBlock *LLVM_BB = MBB->getBasicBlock();
1582 MachineFunction::iterator It = ++MBB->getIterator();
1583
1584 MachineFunction *F = MBB->getParent();
1585 MachineBasicBlock *CopyMBB = F->CreateMachineBasicBlock(LLVM_BB);
1586 MachineBasicBlock *SinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
1587
1588 F->insert(It, CopyMBB);
1589 F->insert(It, SinkMBB);
1590
1591 // Transfer the remainder of MBB and its successor edges to SinkMBB.
1592 SinkMBB->splice(SinkMBB->begin(), MBB,
1593 std::next(MachineBasicBlock::iterator(MI)), MBB->end());
1595
1596 MBB->addSuccessor(CopyMBB);
1597 MBB->addSuccessor(SinkMBB);
1598
1599 if (MI.getOpcode() == Xtensa::SELECT_CC_FP_FP ||
1600 MI.getOpcode() == Xtensa::SELECT_CC_FP_INT) {
1601 unsigned CmpKind = MI.getOperand(5).getImm();
1602 unsigned BrKind = MI.getOperand(6).getImm();
1603 MCPhysReg BReg = Xtensa::B0;
1604
1605 BuildMI(MBB, DL, TII.get(CmpKind), BReg)
1606 .addReg(LHS.getReg())
1607 .addReg(RHS.getReg());
1608 BuildMI(MBB, DL, TII.get(BrKind))
1609 .addReg(BReg, RegState::Kill)
1610 .addMBB(SinkMBB);
1611 } else {
1612 unsigned BrKind = MI.getOperand(5).getImm();
1613 BuildMI(MBB, DL, TII.get(BrKind))
1614 .addReg(LHS.getReg())
1615 .addReg(RHS.getReg())
1616 .addMBB(SinkMBB);
1617 }
1618
1619 CopyMBB->addSuccessor(SinkMBB);
1620
1621 // SinkMBB:
1622 // %Result = phi [ %FalseValue, CopyMBB ], [ %TrueValue, MBB ]
1623 // ...
1624
1625 BuildMI(*SinkMBB, SinkMBB->begin(), DL, TII.get(Xtensa::PHI),
1626 MI.getOperand(0).getReg())
1627 .addReg(FalseValue.getReg())
1628 .addMBB(CopyMBB)
1629 .addReg(TrueValue.getReg())
1630 .addMBB(MBB);
1631
1632 MI.eraseFromParent(); // The pseudo instruction is gone now.
1633 return SinkMBB;
1634}
1635
1638 DebugLoc DL = MI.getDebugLoc();
1639 const XtensaInstrInfo &TII = *Subtarget.getInstrInfo();
1640
1641 switch (MI.getOpcode()) {
1642 case Xtensa::BRCC_FP: {
1643 MachineOperand &Cond = MI.getOperand(0);
1644 MachineOperand &LHS = MI.getOperand(1);
1645 MachineOperand &RHS = MI.getOperand(2);
1646 MachineBasicBlock *TargetBB = MI.getOperand(3).getMBB();
1647 unsigned BrKind = 0;
1648 unsigned CmpKind = 0;
1649 ISD::CondCode CondCode = (ISD::CondCode)Cond.getImm();
1650 MCPhysReg BReg = Xtensa::B0;
1651
1652 std::tie(BrKind, CmpKind) = getFPBranchKind(CondCode);
1653 BuildMI(*MBB, MI, DL, TII.get(CmpKind), BReg)
1654 .addReg(LHS.getReg())
1655 .addReg(RHS.getReg());
1656 BuildMI(*MBB, MI, DL, TII.get(BrKind))
1657 .addReg(BReg, RegState::Kill)
1658 .addMBB(TargetBB);
1659
1660 MI.eraseFromParent();
1661 return MBB;
1662 }
1663 case Xtensa::SELECT_CC_FP_FP:
1664 case Xtensa::SELECT_CC_FP_INT:
1665 case Xtensa::SELECT_CC_INT_FP:
1666 case Xtensa::SELECT:
1667 return emitSelectCC(MI, MBB);
1668 case Xtensa::S8I:
1669 case Xtensa::S16I:
1670 case Xtensa::S32I:
1671 case Xtensa::S32I_N:
1672 case Xtensa::SSI:
1673 case Xtensa::SSIP:
1674 case Xtensa::SSX:
1675 case Xtensa::SSXP:
1676 case Xtensa::L8UI:
1677 case Xtensa::L16SI:
1678 case Xtensa::L16UI:
1679 case Xtensa::L32I:
1680 case Xtensa::L32I_N:
1681 case Xtensa::LSI:
1682 case Xtensa::LSIP:
1683 case Xtensa::LSX:
1684 case Xtensa::LSXP: {
1685 // Insert memory wait instruction "memw" before volatile load/store as it is
1686 // implemented in gcc. If memoperands is empty then assume that it aslo
1687 // maybe volatile load/store and insert "memw".
1688 if (MI.memoperands_empty() || (*MI.memoperands_begin())->isVolatile()) {
1689 BuildMI(*MBB, MI, DL, TII.get(Xtensa::MEMW));
1690 }
1691 return MBB;
1692 }
1693 case Xtensa::MOVSP_P: {
1694 MachineOperand &NewSP = MI.getOperand(0);
1695
1696 BuildMI(*MBB, MI, DL, TII.get(Xtensa::MOVSP), Xtensa::SP)
1697 .addReg(NewSP.getReg());
1698 MI.eraseFromParent();
1699
1700 return MBB;
1701 }
1702 case Xtensa::ATOMIC_CMP_SWAP_32_P: {
1703 MachineOperand &R = MI.getOperand(0);
1704 MachineOperand &Addr = MI.getOperand(1);
1705 MachineOperand &Cmp = MI.getOperand(2);
1706 MachineOperand &Swap = MI.getOperand(3);
1707
1708 BuildMI(*MBB, MI, DL, TII.get(Xtensa::WSR), Xtensa::SCOMPARE1)
1709 .addReg(Cmp.getReg());
1710
1711 BuildMI(*MBB, MI, DL, TII.get(Xtensa::S32C1I), R.getReg())
1712 .addReg(Swap.getReg())
1713 .addReg(Addr.getReg())
1714 .addImm(0);
1715
1716 MI.eraseFromParent();
1717 return MBB;
1718 }
1719 default:
1720 llvm_unreachable("Unexpected instr type to insert");
1721 }
1722}
unsigned RegSize
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
uint64_t Imm
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > & Cond
SI optimize exec mask operations pre RA
static const char * name
static const MCPhysReg IntRegs[32]
static unsigned toCallerWindow(unsigned Reg)
Value * RHS
Value * LHS
static bool isLongCall(const char *str)
static unsigned toCallerWindow(unsigned Reg)
static std::pair< unsigned, unsigned > getFPBranchKind(ISD::CondCode Cond)
static unsigned getBranchOpcode(ISD::CondCode Cond)
static bool CC_Xtensa_Custom(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
Class for arbitrary precision integers.
Definition APInt.h:78
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1582
an instruction that atomically reads a memory location, combines it with another value,...
LLVM Basic Block Representation.
Definition BasicBlock.h:62
CCState - This class holds information needed while lowering arguments and return values.
unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const
getFirstUnallocated - Return the index of the first unallocated register in the set,...
LLVM_ABI void AnalyzeCallResult(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeCallResult - Analyze the return values of a call, incorporating info about the passed values i...
LLVM_ABI 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 ...
LLVM_ABI void AnalyzeReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeReturn - Analyze the returned values of a return, incorporating info about the result values i...
LLVM_ABI 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.
LLVM_ABI void AnalyzeFormalArguments(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeFormalArguments - Analyze an array of argument values, incorporating info about the formals in...
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
int64_t getLocMemOffset() const
unsigned getValNo() const
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
Definition Constants.h:135
const Constant * getConstVal() const
const APInt & getAPIntValue() const
This is an important base class in LLVM.
Definition Constant.h:44
LLVM_ABI Align getABITypeAlign(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
LLVM_ABI TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
A debug info location.
Definition DebugLoc.h:126
LinkageTypes getLinkage() const
static bool isPrivateLinkage(LinkageTypes Linkage)
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
Machine Value Type.
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
static auto fp_valuetypes()
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
void setFrameAddressIsTaken(bool T)
void setReturnAddressIsTaken(bool s)
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
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.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
LLVM_ABI unsigned getEntrySize(const DataLayout &TD) const
getEntrySize - Return the size of each entry in the jump table.
MachineOperand class - Representation of each machine instruction operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
Definition Register.h:20
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
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.
user_iterator user_begin() const
Provide iteration support to walk over all users 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...
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offs=0, bool isT=false, unsigned TargetFlags=0)
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false, SDNodeFlags Flags={})
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align DstAlign, Align SrcAlign, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
const TargetLowering & getTargetLoweringInfo() const
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
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 getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
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 ...
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Loads are not normal binary operators: their result type is not determined by their operands,...
const TargetMachine & getTarget() const
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
MachineFunction & getMachineFunction() const
SDValue getPOISON(EVT VT)
Return a POISON node. POISON does not have a useful SDLoc.
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
LLVM_ABI 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)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::string str() const
Get the contents as an std::string.
Definition StringRef.h:222
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
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...
TargetInstrInfo - Interface to description of machine instruction set.
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...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
const TargetMachine & getTargetMachine() const
virtual MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
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.
bool isTypeLegal(EVT VT) const
Return true if the target has native support 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...
FPImmAction
How the legalizer should materialize a floating-point immediate.
@ ConstantPool
Load the immediate from the constant pool.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
void setMinCmpXchgSizeInBits(unsigned SizeInBits)
Sets the minimum cmpxchg or ll/sc size supported by the backend.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
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.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
SDValue expandCTPOP(SDNode *N, SelectionDAG &DAG) const
Expand CTPOP nodes.
bool isPositionIndependent() const
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
TargetLowering(const TargetLowering &)=delete
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
Primary interface to the complete machine description for the target machine.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:348
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:299
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:315
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 XtensaInstrInfo * getInstrInfo() const override
const XtensaRegisterInfo * getRegisterInfo() const override
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, LLVMContext &Context, const Type *RetTy) const override
This hook should be implemented to check whether the return values described by the Outs array can fi...
TargetLowering::ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &Info, const char *Constraint) const override
Examine constraint string and operand type and determine a weight value.
AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
Register getExceptionSelectorRegister(ExceptionHandling EH, const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
FPImmAction getFPImmAction(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns how the legalizer should materialize the specified FP immediate.
TargetLowering::ConstraintType getConstraintType(StringRef Constraint) const override
Given a constraint, return the type of constraint it is for this target.
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
bool decomposeMulByConstant(LLVMContext &Context, EVT VT, SDValue C) const override
Return true if it is profitable to transform an integer multiplication-by-constant into simpler opera...
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *BB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
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)
Register getExceptionPointerRegister(ExceptionHandling EH, const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
Lower the specified operand into the Ops vector.
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
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,...
MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const override
Return the register type for a given MVT.
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...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h:845
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition ISDOpcodes.h:277
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:805
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:266
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
Definition ISDOpcodes.h:523
@ GlobalAddress
Definition ISDOpcodes.h:90
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition ISDOpcodes.h:906
@ FADD
Simple binary floating point operators.
Definition ISDOpcodes.h:420
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition ISDOpcodes.h:282
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ GlobalTLSAddress
Definition ISDOpcodes.h:91
@ CTLZ_ZERO_POISON
Definition ISDOpcodes.h:814
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ BR_JT
BR_JT - Jumptable branch.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:822
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:714
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:787
@ DEBUGTRAP
DEBUGTRAP - Trap intended to get the attention of a debugger.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition ISDOpcodes.h:837
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition ISDOpcodes.h:914
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition ISDOpcodes.h:745
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition ISDOpcodes.h:112
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:952
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:757
@ TRAP
TRAP - Trapping instruction.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition ISDOpcodes.h:55
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
Definition ISDOpcodes.h:813
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:882
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
Definition ISDOpcodes.h:859
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition ISDOpcodes.h:64
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
Definition ISDOpcodes.h:539
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
constexpr MCPhysReg SP
NodeAddr< NodeBase * > Node
Definition RDFGraph.h:381
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
@ Kill
The last use of a register.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
@ Store
The extracted value is stored (ExtractElement only).
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:326
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:149
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
DWARFExpression::Operation Op
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
Definition MathExtras.h:183
ExceptionHandling
Definition CodeGen.h:54
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:82
Extended Value Type.
Definition ValueTypes.h:35
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
Definition ValueTypes.h:418
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
Definition ValueTypes.h:155
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:396
uint64_t getScalarSizeInBits() const
Definition ValueTypes.h:408
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
Definition ValueTypes.h:165
Align getNonZeroOrigAlign() const
unsigned getByValSize() const
Align getNonZeroByValAlign() const
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getJumpTable(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a jump table entry.
static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
static LLVM_ABI 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 contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
SmallVector< ISD::OutputArg, 32 > Outs