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 const Constant *PersonalityFn) const {
276 return Xtensa::A2;
277}
278
280 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
291 bool ForCodeSize) const {
292 return false;
293}
294
295//===----------------------------------------------------------------------===//
296// Inline asm support
297//===----------------------------------------------------------------------===//
300 if (Constraint.size() == 1) {
301 switch (Constraint[0]) {
302 case 'r':
303 case 'f':
304 return C_RegisterClass;
305 default:
306 break;
307 }
308 }
309 return TargetLowering::getConstraintType(Constraint);
310}
311
314 AsmOperandInfo &Info, const char *Constraint) const {
316 Value *CallOperandVal = Info.CallOperandVal;
317 // If we don't have a value, we can't do a match,
318 // but allow it at the lowest weight.
319 if (!CallOperandVal)
320 return CW_Default;
321
322 Type *Ty = CallOperandVal->getType();
323
324 // Look at the constraint type.
325 switch (*Constraint) {
326 default:
327 Weight = TargetLowering::getSingleConstraintMatchWeight(Info, Constraint);
328 break;
329 case 'r':
330 if (Ty->isIntegerTy())
331 Weight = CW_Register;
332 break;
333 case 'f':
334 if (Ty->isFloatingPointTy())
335 Weight = CW_Register;
336 break;
337 }
338 return Weight;
339}
340
341std::pair<unsigned, const TargetRegisterClass *>
343 const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
344 if (Constraint.size() == 1) {
345 // GCC Constraint Letters
346 switch (Constraint[0]) {
347 default:
348 break;
349 case 'r': // General-purpose register
350 return std::make_pair(0U, &Xtensa::ARRegClass);
351 case 'f': // Floating-point register
352 if (Subtarget.hasSingleFloat())
353 return std::make_pair(0U, &Xtensa::FPRRegClass);
354 }
355 }
357}
358
360 SDValue Op, StringRef Constraint, std::vector<SDValue> &Ops,
361 SelectionDAG &DAG) const {
362 SDLoc DL(Op);
363
364 // Only support length 1 constraints for now.
365 if (Constraint.size() > 1)
366 return;
367
369}
370
371//===----------------------------------------------------------------------===//
372// Calling conventions
373//===----------------------------------------------------------------------===//
374
375#define GET_CALLING_CONV_IMPL
376#include "XtensaGenCallingConv.inc"
377
378static const MCPhysReg IntRegs[] = {Xtensa::A2, Xtensa::A3, Xtensa::A4,
379 Xtensa::A5, Xtensa::A6, Xtensa::A7};
380
381static bool CC_Xtensa_Custom(unsigned ValNo, MVT ValVT, MVT LocVT,
382 CCValAssign::LocInfo LocInfo,
383 ISD::ArgFlagsTy ArgFlags, Type *OrigTy,
384 CCState &State) {
385 if (ArgFlags.isByVal()) {
386 Align ByValAlign = ArgFlags.getNonZeroByValAlign();
387 unsigned ByValSize = ArgFlags.getByValSize();
388 if (ByValSize < 4) {
389 ByValSize = 4;
390 }
391 if (ByValAlign < Align(4)) {
392 ByValAlign = Align(4);
393 }
394 unsigned Offset = State.AllocateStack(ByValSize, ByValAlign);
395 State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
396 // Mark all unused registers as allocated to avoid misuse
397 // of such registers.
398 while (State.AllocateReg(IntRegs))
399 ;
400 return false;
401 }
402
403 // Promote i8 and i16
404 if (LocVT == MVT::i8 || LocVT == MVT::i16) {
405 LocVT = MVT::i32;
406 if (ArgFlags.isSExt())
407 LocInfo = CCValAssign::SExt;
408 else if (ArgFlags.isZExt())
409 LocInfo = CCValAssign::ZExt;
410 else
411 LocInfo = CCValAssign::AExt;
412 }
413
414 unsigned Register;
415
416 Align OrigAlign = ArgFlags.getNonZeroOrigAlign();
417 bool needs64BitAlign = (ValVT == MVT::i32 && OrigAlign == Align(8));
418 bool needs128BitAlign = (ValVT == MVT::i32 && OrigAlign == Align(16));
419
420 if (ValVT == MVT::i32) {
421 Register = State.AllocateReg(IntRegs);
422 // If this is the first part of an i64 arg,
423 // the allocated register must be either A2, A4 or A6.
424 if (needs64BitAlign && (Register == Xtensa::A3 || Register == Xtensa::A5 ||
425 Register == Xtensa::A7))
426 Register = State.AllocateReg(IntRegs);
427 // arguments with 16byte alignment must be passed in the first register or
428 // passed via stack
429 if (needs128BitAlign && (Register != Xtensa::A2))
430 while ((Register = State.AllocateReg(IntRegs)))
431 ;
432 LocVT = MVT::i32;
433 } else if (ValVT == MVT::f64) {
434 // Allocate int register and shadow next int register.
435 Register = State.AllocateReg(IntRegs);
436 if (Register == Xtensa::A3 || Register == Xtensa::A5 ||
437 Register == Xtensa::A7)
438 Register = State.AllocateReg(IntRegs);
439 State.AllocateReg(IntRegs);
440 LocVT = MVT::i32;
441 } else {
442 report_fatal_error("Cannot handle this ValVT.");
443 }
444
445 if (!Register) {
446 unsigned Offset = State.AllocateStack(ValVT.getStoreSize(), OrigAlign);
447 State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
448 } else {
449 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Register, LocVT, LocInfo));
450 }
451
452 return false;
453}
454
455/// Return the register type for a given MVT
458 EVT VT) const {
459 if (VT.isFloatingPoint())
460 return MVT::i32;
461
462 return TargetLowering::getRegisterTypeForCallingConv(Context, CC, VT);
463}
464
465CCAssignFn *XtensaTargetLowering::CCAssignFnForCall(CallingConv::ID CC,
466 bool IsVarArg) const {
467 return CC_Xtensa_Custom;
468}
469
471 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
472 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
473 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
475 MachineFrameInfo &MFI = MF.getFrameInfo();
477
478 // Used with vargs to acumulate store chains.
479 std::vector<SDValue> OutChains;
480
481 // Assign locations to all of the incoming arguments.
483 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
484 *DAG.getContext());
485
486 CCInfo.AnalyzeFormalArguments(Ins, CCAssignFnForCall(CallConv, IsVarArg));
487
488 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
489 CCValAssign &VA = ArgLocs[i];
490 // Arguments stored on registers
491 if (VA.isRegLoc()) {
492 EVT RegVT = VA.getLocVT();
493
494 if (RegVT != MVT::i32)
495 report_fatal_error("RegVT not supported by FormalArguments Lowering");
496
497 // Transform the arguments stored on
498 // physical registers into virtual ones
499 Register Reg = 0;
500 MCRegister FrameReg = Subtarget.getRegisterInfo()->getFrameRegister(MF);
501
502 // Argument passed in FrameReg in Windowed ABI we save in A8 (in
503 // emitPrologue), so load argument from A8
504 if (Subtarget.isWindowedABI() && (VA.getLocReg() == FrameReg)) {
505 Reg = MF.addLiveIn(Xtensa::A8, &Xtensa::ARRegClass);
506 XtensaFI->setSaveFrameRegister();
507 } else {
508 Reg = MF.addLiveIn(VA.getLocReg(), &Xtensa::ARRegClass);
509 }
510
511 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, RegVT);
512
513 // If this is an 8 or 16-bit value, it has been passed promoted
514 // to 32 bits. Insert an assert[sz]ext to capture this, then
515 // truncate to the right size.
516 if (VA.getLocInfo() != CCValAssign::Full) {
517 unsigned Opcode = 0;
518 if (VA.getLocInfo() == CCValAssign::SExt)
519 Opcode = ISD::AssertSext;
520 else if (VA.getLocInfo() == CCValAssign::ZExt)
521 Opcode = ISD::AssertZext;
522 if (Opcode)
523 ArgValue = DAG.getNode(Opcode, DL, RegVT, ArgValue,
524 DAG.getValueType(VA.getValVT()));
525 ArgValue = DAG.getNode((VA.getValVT() == MVT::f32) ? ISD::BITCAST
527 DL, VA.getValVT(), ArgValue);
528 }
529
530 InVals.push_back(ArgValue);
531
532 } else {
533 assert(VA.isMemLoc());
534
535 EVT ValVT = VA.getValVT();
536
537 // The stack pointer offset is relative to the caller stack frame.
538 int FI = MFI.CreateFixedObject(ValVT.getStoreSize(), VA.getLocMemOffset(),
539 true);
540
541 if (Ins[VA.getValNo()].Flags.isByVal()) {
542 // Assume that in this case load operation is created
543 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
544 InVals.push_back(FIN);
545 } else {
546 // Create load nodes to retrieve arguments from the stack
547 SDValue FIN =
549 InVals.push_back(DAG.getLoad(
550 ValVT, DL, Chain, FIN,
552 }
553 }
554 }
555
556 if (IsVarArg) {
557 unsigned Idx = CCInfo.getFirstUnallocated(IntRegs);
558 unsigned ArgRegsNum = std::size(IntRegs);
559 const TargetRegisterClass *RC = &Xtensa::ARRegClass;
560 MachineFrameInfo &MFI = MF.getFrameInfo();
561 MachineRegisterInfo &RegInfo = MF.getRegInfo();
562 unsigned RegSize = 4;
563 MVT RegTy = MVT::i32;
564 MVT FITy = getFrameIndexTy(DAG.getDataLayout());
565
566 XtensaFI->setVarArgsFirstGPR(Idx + 2); // 2 - number of a2 register
567
569 MFI.CreateFixedObject(4, CCInfo.getStackSize(), true));
570
571 // Offset of the first variable argument from stack pointer, and size of
572 // the vararg save area. For now, the varargs save area is either zero or
573 // large enough to hold a0-a7.
574 int VaArgOffset, VarArgsSaveSize;
575
576 // If all registers are allocated, then all varargs must be passed on the
577 // stack and we don't need to save any argregs.
578 if (ArgRegsNum == Idx) {
579 VaArgOffset = CCInfo.getStackSize();
580 VarArgsSaveSize = 0;
581 } else {
582 VarArgsSaveSize = RegSize * (ArgRegsNum - Idx);
583 VaArgOffset = -VarArgsSaveSize;
584
585 // Record the frame index of the first variable argument
586 // which is a value necessary to VASTART.
587 int FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true);
588 XtensaFI->setVarArgsInRegsFrameIndex(FI);
589
590 // Copy the integer registers that may have been used for passing varargs
591 // to the vararg save area.
592 for (unsigned I = Idx; I < ArgRegsNum; ++I, VaArgOffset += RegSize) {
593 const Register Reg = RegInfo.createVirtualRegister(RC);
594 RegInfo.addLiveIn(IntRegs[I], Reg);
595
596 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, RegTy);
597 FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true);
598 SDValue PtrOff = DAG.getFrameIndex(FI, FITy);
599 SDValue Store = DAG.getStore(Chain, DL, ArgValue, PtrOff,
601 OutChains.push_back(Store);
602 }
603 }
604 }
605
606 // All stores are grouped in one node to allow the matching between
607 // the size of Ins and InVals. This only happens when on varg functions
608 if (!OutChains.empty()) {
609 OutChains.push_back(Chain);
610 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
611 }
612
613 return Chain;
614}
615
618 SmallVectorImpl<SDValue> &InVals) const {
619 SelectionDAG &DAG = CLI.DAG;
620 SDLoc &DL = CLI.DL;
622 SmallVector<SDValue, 32> &OutVals = CLI.OutVals;
624 SDValue Chain = CLI.Chain;
625 SDValue Callee = CLI.Callee;
626 bool &IsTailCall = CLI.IsTailCall;
627 CallingConv::ID CallConv = CLI.CallConv;
628 bool IsVarArg = CLI.IsVarArg;
629
631 EVT PtrVT = getPointerTy(DAG.getDataLayout());
632 const TargetFrameLowering *TFL = Subtarget.getFrameLowering();
633
634 // TODO: Support tail call optimization.
635 IsTailCall = false;
636
637 // Analyze the operands of the call, assigning locations to each operand.
639 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
640
641 CCAssignFn *CC = CCAssignFnForCall(CallConv, IsVarArg);
642
643 CCInfo.AnalyzeCallOperands(Outs, CC);
644
645 // Get a count of how many bytes are to be pushed on the stack.
646 unsigned NumBytes = CCInfo.getStackSize();
647
648 Align StackAlignment = TFL->getStackAlign();
649 unsigned NextStackOffset = alignTo(NumBytes, StackAlignment);
650
651 Chain = DAG.getCALLSEQ_START(Chain, NextStackOffset, 0, DL);
652
653 // Copy argument values to their designated locations.
654 std::deque<std::pair<unsigned, SDValue>> RegsToPass;
655 SmallVector<SDValue, 8> MemOpChains;
656 SDValue StackPtr;
657 for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) {
658 CCValAssign &VA = ArgLocs[I];
659 SDValue ArgValue = OutVals[I];
660 ISD::ArgFlagsTy Flags = Outs[I].Flags;
661
662 if (VA.isRegLoc())
663 // Queue up the argument copies and emit them at the end.
664 RegsToPass.push_back(std::make_pair(VA.getLocReg(), ArgValue));
665 else if (Flags.isByVal()) {
666 assert(VA.isMemLoc());
667 assert(Flags.getByValSize() &&
668 "ByVal args of size 0 should have been ignored by front-end.");
669 assert(!IsTailCall &&
670 "Do not tail-call optimize if there is a byval argument.");
671
672 if (!StackPtr.getNode())
673 StackPtr = DAG.getCopyFromReg(Chain, DL, Xtensa::SP, PtrVT);
674 unsigned Offset = VA.getLocMemOffset();
675 SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,
677 SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), DL, MVT::i32);
678 Align Alignment = Flags.getNonZeroByValAlign();
679 SDValue Memcpy = DAG.getMemcpy(
680 Chain, DL, Address, ArgValue, SizeNode, Alignment, Alignment,
681 /*isVolatile=*/false, /*AlwaysInline=*/false,
682 /*CI=*/nullptr, std::nullopt, MachinePointerInfo(),
684 MemOpChains.push_back(Memcpy);
685 } else {
686 assert(VA.isMemLoc() && "Argument not register or memory");
687
688 // Work out the address of the stack slot. Unpromoted ints and
689 // floats are passed as right-justified 8-byte values.
690 if (!StackPtr.getNode())
691 StackPtr = DAG.getCopyFromReg(Chain, DL, Xtensa::SP, PtrVT);
692 unsigned Offset = VA.getLocMemOffset();
693 SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,
695
696 // Emit the store.
697 MemOpChains.push_back(
698 DAG.getStore(Chain, DL, ArgValue, Address, MachinePointerInfo()));
699 }
700 }
701
702 // Join the stores, which are independent of one another.
703 if (!MemOpChains.empty())
704 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains);
705
706 // Build a sequence of copy-to-reg nodes, chained and glued together.
707 SDValue Glue;
708 for (unsigned I = 0, E = RegsToPass.size(); I != E; ++I) {
709 unsigned Reg = RegsToPass[I].first;
710 if (Subtarget.isWindowedABI())
711 Reg = toCallerWindow(Reg);
712 Chain = DAG.getCopyToReg(Chain, DL, Reg, RegsToPass[I].second, Glue);
713 Glue = Chain.getValue(1);
714 }
715 std::string name;
716 unsigned char TF = 0;
717
718 // Accept direct calls by converting symbolic call addresses to the
719 // associated Target* opcodes.
721 name = E->getSymbol();
722 TF = E->getTargetFlags();
723 if (isPositionIndependent()) {
724 report_fatal_error("PIC relocations is not supported");
725 } else
726 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, TF);
728 const GlobalValue *GV = G->getGlobal();
729 name = GV->getName().str();
730 }
731
732 if ((!name.empty()) && isLongCall(name.c_str())) {
733 // Create a constant pool entry for the callee address
735 XtensaMachineFunctionInfo *XtensaFI =
737 unsigned LabelId = XtensaFI->createCPLabelId();
738
740 *DAG.getContext(), name.c_str(), LabelId, false, Modifier);
741
742 // Get the address of the callee into a register
743 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4), 0, TF);
744 SDValue CPWrap = getAddrPCRel(CPAddr, DAG);
745 Callee = DAG.getLoad(
746 PtrVT, DL, DAG.getEntryNode(), CPWrap,
748 }
749
750 // The first call operand is the chain and the second is the target address.
752 Ops.push_back(Chain);
753 Ops.push_back(Callee);
754
755 // Add a register mask operand representing the call-preserved registers.
756 const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
757 const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv);
758 assert(Mask && "Missing call preserved mask for calling convention");
759 Ops.push_back(DAG.getRegisterMask(Mask));
760
761 // Add argument registers to the end of the list so that they are
762 // known live into the call.
763 for (unsigned I = 0, E = RegsToPass.size(); I != E; ++I) {
764 unsigned Reg = RegsToPass[I].first;
765 if (Subtarget.isWindowedABI())
766 Reg = toCallerWindow(Reg);
767 Ops.push_back(DAG.getRegister(Reg, RegsToPass[I].second.getValueType()));
768 }
769
770 // Glue the call to the argument copies, if any.
771 if (Glue.getNode())
772 Ops.push_back(Glue);
773
774 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
775 Chain = DAG.getNode(Subtarget.isWindowedABI() ? XtensaISD::CALLW8
776 : XtensaISD::CALL,
777 DL, NodeTys, Ops);
778 Glue = Chain.getValue(1);
779
780 // Mark the end of the call, which is glued to the call itself.
781 Chain = DAG.getCALLSEQ_END(Chain, DAG.getConstant(NumBytes, DL, PtrVT, true),
782 DAG.getConstant(0, DL, PtrVT, true), Glue, DL);
783 Glue = Chain.getValue(1);
784
785 // Assign locations to each value returned by this call.
787 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, *DAG.getContext());
788 RetCCInfo.AnalyzeCallResult(Ins, Subtarget.isWindowedABI() ? RetCCW8_Xtensa
789 : RetCC_Xtensa);
790
791 // Copy all of the result registers out of their specified physreg.
792 for (unsigned I = 0, E = RetLocs.size(); I != E; ++I) {
793 CCValAssign &VA = RetLocs[I];
794
795 // Copy the value out, gluing the copy to the end of the call sequence.
796 unsigned Reg = VA.getLocReg();
797 SDValue RetValue = DAG.getCopyFromReg(Chain, DL, Reg, VA.getLocVT(), Glue);
798 Chain = RetValue.getValue(1);
799 Glue = RetValue.getValue(2);
800
801 InVals.push_back(RetValue);
802 }
803 return Chain;
804}
805
807 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
808 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
809 const Type *RetTy) const {
811 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
812 return CCInfo.CheckReturn(Outs, RetCC_Xtensa);
813}
814
817 bool IsVarArg,
819 const SmallVectorImpl<SDValue> &OutVals,
820 const SDLoc &DL, SelectionDAG &DAG) const {
822
823 // Assign locations to each returned value.
825 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, *DAG.getContext());
826 RetCCInfo.AnalyzeReturn(Outs, RetCC_Xtensa);
827
828 SDValue Glue;
829 // Quick exit for void returns
830 if (RetLocs.empty())
831 return DAG.getNode(Subtarget.isWindowedABI() ? XtensaISD::RETW
832 : XtensaISD::RET,
833 DL, MVT::Other, Chain);
834
835 // Copy the result values into the output registers.
837 RetOps.push_back(Chain);
838 for (unsigned I = 0, E = RetLocs.size(); I != E; ++I) {
839 CCValAssign &VA = RetLocs[I];
840 SDValue RetValue = OutVals[I];
841
842 // Make the return register live on exit.
843 assert(VA.isRegLoc() && "Can only return in registers!");
844
845 // Chain and glue the copies together.
846 unsigned Register = VA.getLocReg();
847 Chain = DAG.getCopyToReg(Chain, DL, Register, RetValue, Glue);
848 Glue = Chain.getValue(1);
849 RetOps.push_back(DAG.getRegister(Register, VA.getLocVT()));
850 }
851
852 // Update chain and glue.
853 RetOps[0] = Chain;
854 if (Glue.getNode())
855 RetOps.push_back(Glue);
856
857 return DAG.getNode(Subtarget.isWindowedABI() ? XtensaISD::RETW
858 : XtensaISD::RET,
859 DL, MVT::Other, RetOps);
860}
861
863 switch (Cond) {
864 case ISD::SETEQ:
865 return Xtensa::BEQ;
866 case ISD::SETNE:
867 return Xtensa::BNE;
868 case ISD::SETLT:
869 return Xtensa::BLT;
870 case ISD::SETLE:
871 return Xtensa::BGE;
872 case ISD::SETGT:
873 return Xtensa::BLT;
874 case ISD::SETGE:
875 return Xtensa::BGE;
876 case ISD::SETULT:
877 return Xtensa::BLTU;
878 case ISD::SETULE:
879 return Xtensa::BGEU;
880 case ISD::SETUGT:
881 return Xtensa::BLTU;
882 case ISD::SETUGE:
883 return Xtensa::BGEU;
884 default:
885 llvm_unreachable("Unknown branch kind");
886 }
887}
888
889static std::pair<unsigned, unsigned> getFPBranchKind(ISD::CondCode Cond) {
890 switch (Cond) {
891 case ISD::SETUNE:
892 return std::make_pair(Xtensa::BF, Xtensa::OEQ_S);
893 case ISD::SETUO:
894 return std::make_pair(Xtensa::BT, Xtensa::UN_S);
895 case ISD::SETO:
896 return std::make_pair(Xtensa::BF, Xtensa::UN_S);
897 case ISD::SETUEQ:
898 return std::make_pair(Xtensa::BT, Xtensa::UEQ_S);
899 case ISD::SETULE:
900 return std::make_pair(Xtensa::BT, Xtensa::ULE_S);
901 case ISD::SETULT:
902 return std::make_pair(Xtensa::BT, Xtensa::ULT_S);
903 case ISD::SETEQ:
904 case ISD::SETOEQ:
905 return std::make_pair(Xtensa::BT, Xtensa::OEQ_S);
906 case ISD::SETNE:
907 return std::make_pair(Xtensa::BF, Xtensa::OEQ_S);
908 case ISD::SETLE:
909 case ISD::SETOLE:
910 return std::make_pair(Xtensa::BT, Xtensa::OLE_S);
911 case ISD::SETLT:
912 case ISD::SETOLT:
913 return std::make_pair(Xtensa::BT, Xtensa::OLT_S);
914 case ISD::SETGE:
915 return std::make_pair(Xtensa::BF, Xtensa::OLT_S);
916 case ISD::SETGT:
917 return std::make_pair(Xtensa::BF, Xtensa::OLE_S);
918 case ISD::SETOGT:
919 return std::make_pair(Xtensa::BF, Xtensa::ULE_S);
920 case ISD::SETOGE:
921 return std::make_pair(Xtensa::BF, Xtensa::ULT_S);
922 case ISD::SETONE:
923 return std::make_pair(Xtensa::BF, Xtensa::UEQ_S);
924 case ISD::SETUGT:
925 return std::make_pair(Xtensa::BF, Xtensa::OLE_S);
926 case ISD::SETUGE:
927 return std::make_pair(Xtensa::BF, Xtensa::OLT_S);
928 default:
929 llvm_unreachable("Invalid condition!");
930 }
931}
932
933SDValue XtensaTargetLowering::LowerSELECT_CC(SDValue Op,
934 SelectionDAG &DAG) const {
935 SDLoc DL(Op);
936 EVT Ty = Op.getValueType();
937 SDValue LHS = Op.getOperand(0);
938 SDValue RHS = Op.getOperand(1);
939 SDValue TrueValue = Op.getOperand(2);
940 SDValue FalseValue = Op.getOperand(3);
941 ISD::CondCode CC = cast<CondCodeSDNode>(Op->getOperand(4))->get();
942
943 if (LHS.getValueType() == MVT::i32) {
944 unsigned BrOpcode = getBranchOpcode(CC);
945 SDValue TargetCC = DAG.getConstant(BrOpcode, DL, MVT::i32);
946
947 SDValue Res = DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, LHS, RHS, TrueValue,
948 FalseValue, TargetCC, Op->getFlags());
949 return Res;
950 }
951 assert(LHS.getValueType() == MVT::f32 &&
952 "We expect MVT::f32 type of the LHS Operand in SELECT_CC");
953 unsigned BrOpcode;
954 unsigned CmpOpCode;
955 std::tie(BrOpcode, CmpOpCode) = getFPBranchKind(CC);
956 SDValue TargetCC = DAG.getConstant(CmpOpCode, DL, MVT::i32);
957 SDValue TargetBC = DAG.getConstant(BrOpcode, DL, MVT::i32);
958 return DAG.getNode(XtensaISD::SELECT_CC_FP, DL, Ty,
959 {LHS, RHS, TrueValue, FalseValue, TargetCC, TargetBC},
960 Op->getFlags());
961}
962
963SDValue XtensaTargetLowering::LowerRETURNADDR(SDValue Op,
964 SelectionDAG &DAG) const {
965 // This nodes represent llvm.returnaddress on the DAG.
966 // It takes one operand, the index of the return address to return.
967 // An index of zero corresponds to the current function's return address.
968 // An index of one to the parent's return address, and so on.
969 // Depths > 0 not supported yet!
970 if (Op.getConstantOperandVal(0) != 0)
971 return SDValue();
972
973 MachineFunction &MF = DAG.getMachineFunction();
974 MachineFrameInfo &MFI = MF.getFrameInfo();
975 EVT VT = Op.getValueType();
976 MFI.setReturnAddressIsTaken(true);
977
978 // Return RA, which contains the return address. Mark it an implicit
979 // live-in.
980 Register RA = MF.addLiveIn(Xtensa::A0, getRegClassFor(MVT::i32));
981 return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), RA, VT);
982}
983
984SDValue XtensaTargetLowering::LowerImmediate(SDValue Op,
985 SelectionDAG &DAG) const {
986 const ConstantSDNode *CN = cast<ConstantSDNode>(Op);
987 SDLoc DL(CN);
988 APInt APVal = CN->getAPIntValue();
989 int64_t Value = APVal.getSExtValue();
990 if (Op.getValueType() == MVT::i32) {
991 // Check if use node maybe lowered to the MOVI instruction
992 if (Value > -2048 && Value <= 2047)
993 return Op;
994 // Check if use node maybe lowered to the ADDMI instruction
995 SDNode &OpNode = *Op.getNode();
996 if ((OpNode.hasOneUse() && OpNode.user_begin()->getOpcode() == ISD::ADD) &&
998 return Op;
999 Type *Ty = Type::getInt32Ty(*DAG.getContext());
1001 SDValue CP = DAG.getConstantPool(CV, MVT::i32);
1002 SDValue Res =
1003 DAG.getLoad(MVT::i32, DL, DAG.getEntryNode(), CP, MachinePointerInfo());
1004 return Res;
1005 }
1006 return Op;
1007}
1008
1009SDValue XtensaTargetLowering::LowerGlobalAddress(SDValue Op,
1010 SelectionDAG &DAG) const {
1011 const GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(Op);
1012 SDLoc DL(Op);
1013 auto PtrVT = Op.getValueType();
1014 const GlobalValue *GV = G->getGlobal();
1015
1016 SDValue CPAddr = DAG.getTargetConstantPool(GV, PtrVT, Align(4));
1017 SDValue CPWrap = getAddrPCRel(CPAddr, DAG);
1018 SDValue Res = DAG.getLoad(
1019 PtrVT, DL, DAG.getEntryNode(), CPWrap,
1021 return Res;
1022}
1023
1024SDValue XtensaTargetLowering::LowerGlobalTLSAddress(SDValue Op,
1025 SelectionDAG &DAG) const {
1026 const GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(Op);
1027 SDLoc DL(Op);
1028 EVT PtrVT = Op.getValueType();
1029 const GlobalValue *GV = G->getGlobal();
1030
1031 if (DAG.getTarget().useEmulatedTLS())
1032 return LowerToTLSEmulatedModel(G, DAG);
1033
1035
1036 if (!Subtarget.hasTHREADPTR()) {
1037 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
1038 DAG.getMachineFunction().getFunction(), "only emulated TLS supported",
1039 DL.getDebugLoc()));
1040 return DAG.getPOISON(Op->getValueType(0));
1041 }
1042
1043 if (model == TLSModel::LocalExec || model == TLSModel::InitialExec) {
1044 bool Priv = GV->isPrivateLinkage(GV->getLinkage());
1045 MachineFunction &MF = DAG.getMachineFunction();
1046 XtensaMachineFunctionInfo *XtensaFI =
1047 MF.getInfo<XtensaMachineFunctionInfo>();
1048 unsigned LabelId = XtensaFI->createCPLabelId();
1049
1050 // Create a constant pool entry for the callee address
1051 XtensaConstantPoolValue *CPV = XtensaConstantPoolSymbol::Create(
1052 *DAG.getContext(), GV->getName().str().c_str(), LabelId, Priv,
1054
1055 // Get the address of the callee into a register
1056 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
1057 SDValue CPWrap = getAddrPCRel(CPAddr, DAG);
1058 SDValue Addr = DAG.getLoad(
1059 PtrVT, DL, DAG.getEntryNode(), CPWrap,
1061
1062 SDValue TPRegister = DAG.getRegister(Xtensa::THREADPTR, MVT::i32);
1063 SDValue ThreadPointer =
1064 DAG.getNode(XtensaISD::RUR, DL, MVT::i32, TPRegister);
1065
1066 return DAG.getNode(ISD::ADD, DL, PtrVT, ThreadPointer, Addr);
1067 }
1068
1069 DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
1071 "only local-exec and initial-exec TLS mode supported", DL.getDebugLoc()));
1072
1073 return DAG.getPOISON(Op->getValueType(0));
1074}
1075
1076SDValue XtensaTargetLowering::LowerBlockAddress(SDValue Op,
1077 SelectionDAG &DAG) const {
1078 BlockAddressSDNode *Node = cast<BlockAddressSDNode>(Op);
1079 SDLoc DL(Op);
1080 const BlockAddress *BA = Node->getBlockAddress();
1081 EVT PtrVT = Op.getValueType();
1082 MachineFunction &MF = DAG.getMachineFunction();
1083 XtensaMachineFunctionInfo *XtensaFI = MF.getInfo<XtensaMachineFunctionInfo>();
1084 unsigned LabelId = XtensaFI->createCPLabelId();
1085
1086 XtensaConstantPoolValue *CPV =
1088 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
1089 SDValue CPWrap = getAddrPCRel(CPAddr, DAG);
1090 SDValue Res = DAG.getLoad(
1091 PtrVT, DL, DAG.getEntryNode(), CPWrap,
1093 return Res;
1094}
1095
1096SDValue XtensaTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) const {
1097 SDValue Chain = Op.getOperand(0);
1098 SDValue Table = Op.getOperand(1);
1099 SDValue Index = Op.getOperand(2);
1100 SDLoc DL(Op);
1101 JumpTableSDNode *JT = cast<JumpTableSDNode>(Table);
1102 MachineFunction &MF = DAG.getMachineFunction();
1103 const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
1104 SDValue TargetJT = DAG.getTargetJumpTable(JT->getIndex(), MVT::i32);
1105 const DataLayout &TD = DAG.getDataLayout();
1106 EVT PtrVT = Table.getValueType();
1107 unsigned EntrySize = MJTI->getEntrySize(TD);
1108
1109 assert((MJTI->getEntrySize(TD) == 4) && "Unsupported jump-table entry size");
1110
1111 Index = DAG.getNode(
1112 ISD::SHL, DL, Index.getValueType(), Index,
1113 DAG.getConstant(Log2_32(EntrySize), DL, Index.getValueType()));
1114
1115 SDValue Addr = DAG.getNode(ISD::ADD, DL, Index.getValueType(), Index, Table);
1116 SDValue LD =
1117 DAG.getLoad(PtrVT, DL, Chain, Addr,
1119
1120 return DAG.getNode(XtensaISD::BR_JT, DL, MVT::Other, LD.getValue(1), LD,
1121 TargetJT);
1122}
1123
1124SDValue XtensaTargetLowering::LowerJumpTable(SDValue Op,
1125 SelectionDAG &DAG) const {
1126 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
1127 EVT PtrVT = Op.getValueType();
1128 SDLoc DL(Op);
1129
1130 // Create a constant pool entry for the jumptable address
1131 XtensaConstantPoolValue *CPV =
1133
1134 // Get the address of the jumptable into a register
1135 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
1136
1137 SDValue Res = DAG.getLoad(
1138 PtrVT, DL, DAG.getEntryNode(), getAddrPCRel(CPAddr, DAG),
1140 return Res;
1141}
1142
1143SDValue XtensaTargetLowering::getAddrPCRel(SDValue Op,
1144 SelectionDAG &DAG) const {
1145 SDLoc DL(Op);
1146 EVT Ty = Op.getValueType();
1147 return DAG.getNode(XtensaISD::PCREL_WRAPPER, DL, Ty, Op);
1148}
1149
1150SDValue XtensaTargetLowering::LowerConstantPool(SDValue Op,
1151 SelectionDAG &DAG) const {
1152 EVT PtrVT = Op.getValueType();
1153 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
1155
1156 if (!CP->isMachineConstantPoolEntry()) {
1157 Result = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, CP->getAlign(),
1158 CP->getOffset());
1159 } else {
1160 report_fatal_error("This constantpool type is not supported yet");
1161 }
1162
1163 return getAddrPCRel(Result, DAG);
1164}
1165
1166SDValue XtensaTargetLowering::LowerSTACKSAVE(SDValue Op,
1167 SelectionDAG &DAG) const {
1168 return DAG.getCopyFromReg(Op.getOperand(0), SDLoc(Op), Xtensa::SP,
1169 Op.getValueType());
1170}
1171
1172SDValue XtensaTargetLowering::LowerSTACKRESTORE(SDValue Op,
1173 SelectionDAG &DAG) const {
1174 SDValue Chain = Op.getOperand(0);
1175 SDValue NewSP = Op.getOperand(1);
1176
1177 if (Subtarget.isWindowedABI()) {
1178 return DAG.getNode(XtensaISD::MOVSP, SDLoc(Op), MVT::Other, Chain, NewSP);
1179 }
1180
1181 return DAG.getCopyToReg(Chain, SDLoc(Op), Xtensa::SP, NewSP);
1182}
1183
1184SDValue XtensaTargetLowering::LowerFRAMEADDR(SDValue Op,
1185 SelectionDAG &DAG) const {
1186 // This nodes represent llvm.frameaddress on the DAG.
1187 // It takes one operand, the index of the frame address to return.
1188 // An index of zero corresponds to the current function's frame address.
1189 // An index of one to the parent's frame address, and so on.
1190 // Depths > 0 not supported yet!
1191 if (Op.getConstantOperandVal(0) != 0)
1192 return SDValue();
1193
1194 MachineFunction &MF = DAG.getMachineFunction();
1195 MachineFrameInfo &MFI = MF.getFrameInfo();
1196 MFI.setFrameAddressIsTaken(true);
1197 EVT VT = Op.getValueType();
1198 SDLoc DL(Op);
1199
1200 MCRegister FrameRegister = Subtarget.getRegisterInfo()->getFrameRegister(MF);
1201 SDValue FrameAddr =
1202 DAG.getCopyFromReg(DAG.getEntryNode(), DL, FrameRegister, VT);
1203 return FrameAddr;
1204}
1205
1206SDValue XtensaTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
1207 SelectionDAG &DAG) const {
1208 SDValue Chain = Op.getOperand(0); // Legalize the chain.
1209 SDValue Size = Op.getOperand(1); // Legalize the size.
1210 EVT VT = Size->getValueType(0);
1211 SDLoc DL(Op);
1212
1213 // Round up Size to 32
1214 SDValue SizeTmp =
1215 DAG.getNode(ISD::ADD, DL, VT, Size, DAG.getConstant(31, DL, MVT::i32));
1216 SDValue SizeRoundUp = DAG.getNode(ISD::AND, DL, VT, SizeTmp,
1217 DAG.getSignedConstant(~31, DL, MVT::i32));
1218
1219 MCRegister SPReg = Xtensa::SP;
1220 SDValue SP = DAG.getCopyFromReg(Chain, DL, SPReg, VT);
1221 SDValue NewSP = DAG.getNode(ISD::SUB, DL, VT, SP, SizeRoundUp); // Value
1222 if (Subtarget.isWindowedABI()) {
1223 Chain = DAG.getNode(XtensaISD::MOVSP, SDLoc(Op), MVT::Other, SP.getValue(1),
1224 NewSP);
1225 } else {
1226 Chain = DAG.getCopyToReg(SP.getValue(1), DL, SPReg, NewSP); // Output chain
1227 }
1228
1229 SDValue NewVal = DAG.getCopyFromReg(Chain, DL, SPReg, MVT::i32);
1230 Chain = NewVal.getValue(1);
1231
1232 SDValue Ops[2] = {NewVal, Chain};
1233 return DAG.getMergeValues(Ops, DL);
1234}
1235
1236SDValue XtensaTargetLowering::LowerVASTART(SDValue Op,
1237 SelectionDAG &DAG) const {
1238 MachineFunction &MF = DAG.getMachineFunction();
1239 XtensaMachineFunctionInfo *XtensaFI = MF.getInfo<XtensaMachineFunctionInfo>();
1240 SDValue Chain = Op.getOperand(0);
1241 SDValue Addr = Op.getOperand(1);
1242 EVT PtrVT = Addr.getValueType();
1243 SDLoc DL(Op);
1244
1245 // Struct va_list_tag
1246 // int32 *va_stk - points to the arguments passed in memory
1247 // int32 *va_reg - points to the registers with arguments saved in memory
1248 // int32 va_ndx - offset from va_stk or va_reg pointers which points to the
1249 // next variable argument
1250
1251 SDValue VAIndex;
1252 SDValue StackOffsetFI =
1253 DAG.getFrameIndex(XtensaFI->getVarArgsOnStackFrameIndex(), PtrVT);
1254 unsigned ArgWords = XtensaFI->getVarArgsFirstGPR() - 2;
1255
1256 // If first variable argument passed in registers (maximum words in registers
1257 // is 6) then set va_ndx to the position of this argument in registers area
1258 // stored in memory (va_reg pointer). Otherwise va_ndx should point to the
1259 // position of the first variable argument on stack (va_stk pointer).
1260 if (ArgWords < 6) {
1261 VAIndex = DAG.getConstant(ArgWords * 4, DL, MVT::i32);
1262 } else {
1263 VAIndex = DAG.getConstant(32, DL, MVT::i32);
1264 }
1265
1267 DAG.getFrameIndex(XtensaFI->getVarArgsInRegsFrameIndex(), PtrVT);
1268 uint64_t FrameOffset = PtrVT.getStoreSize();
1269 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
1270
1271 // Store pointer to arguments given on stack (va_stk)
1272 SDValue StackPtr = DAG.getNode(ISD::SUB, DL, PtrVT, StackOffsetFI,
1273 DAG.getConstant(32, DL, PtrVT));
1274
1275 SDValue StoreStackPtr =
1276 DAG.getStore(Chain, DL, StackPtr, Addr, MachinePointerInfo(SV));
1277
1278 uint64_t NextOffset = FrameOffset;
1279 SDValue NextPtr =
1280 DAG.getObjectPtrOffset(DL, Addr, TypeSize::getFixed(NextOffset));
1281
1282 // Store pointer to arguments given on registers (va_reg)
1283 SDValue StoreRegPtr = DAG.getStore(StoreStackPtr, DL, FrameIndex, NextPtr,
1284 MachinePointerInfo(SV, NextOffset));
1285 NextOffset += FrameOffset;
1286 NextPtr = DAG.getObjectPtrOffset(DL, Addr, TypeSize::getFixed(NextOffset));
1287
1288 // Store third word : position in bytes of the first VA argument (va_ndx)
1289 return DAG.getStore(StoreRegPtr, DL, VAIndex, NextPtr,
1290 MachinePointerInfo(SV, NextOffset));
1291}
1292
1293SDValue XtensaTargetLowering::LowerVACOPY(SDValue Op, SelectionDAG &DAG) const {
1294 // Size of the va_list_tag structure
1295 constexpr unsigned VAListSize = 3 * 4;
1296 SDValue Chain = Op.getOperand(0);
1297 SDValue DstPtr = Op.getOperand(1);
1298 SDValue SrcPtr = Op.getOperand(2);
1299 const Value *DstSV = cast<SrcValueSDNode>(Op.getOperand(3))->getValue();
1300 const Value *SrcSV = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
1301 SDLoc DL(Op);
1302
1303 return DAG.getMemcpy(Chain, DL, DstPtr, SrcPtr,
1304 DAG.getConstant(VAListSize, SDLoc(Op), MVT::i32),
1305 Align(4), Align(4), /*isVolatile*/ false,
1306 /*AlwaysInline*/ true,
1307 /*CI=*/nullptr, std::nullopt, MachinePointerInfo(DstSV),
1308 MachinePointerInfo(SrcSV));
1309}
1310
1311SDValue XtensaTargetLowering::LowerVAARG(SDValue Op, SelectionDAG &DAG) const {
1312 SDNode *Node = Op.getNode();
1313 EVT VT = Node->getValueType(0);
1314 Type *Ty = VT.getTypeForEVT(*DAG.getContext());
1315 EVT PtrVT = Op.getValueType();
1316 SDValue InChain = Node->getOperand(0);
1317 SDValue VAListPtr = Node->getOperand(1);
1318 const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
1319 SDLoc DL(Node);
1320 auto &TD = DAG.getDataLayout();
1321 Align ArgAlignment = TD.getABITypeAlign(Ty);
1322 unsigned ArgAlignInBytes = ArgAlignment.value();
1323 unsigned ArgSizeInBytes = TD.getTypeAllocSize(Ty);
1324 unsigned VASizeInBytes = llvm::alignTo(ArgSizeInBytes, 4);
1325
1326 // va_stk
1327 SDValue VAStack =
1328 DAG.getLoad(MVT::i32, DL, InChain, VAListPtr, MachinePointerInfo());
1329 InChain = VAStack.getValue(1);
1330
1331 // va_reg
1332 SDValue VARegPtr =
1333 DAG.getObjectPtrOffset(DL, VAListPtr, TypeSize::getFixed(4));
1334 SDValue VAReg =
1335 DAG.getLoad(MVT::i32, DL, InChain, VARegPtr, MachinePointerInfo());
1336 InChain = VAReg.getValue(1);
1337
1338 // va_ndx
1339 SDValue VarArgIndexPtr =
1340 DAG.getObjectPtrOffset(DL, VARegPtr, TypeSize::getFixed(4));
1341 SDValue VAIndex =
1342 DAG.getLoad(MVT::i32, DL, InChain, VarArgIndexPtr, MachinePointerInfo());
1343 InChain = VAIndex.getValue(1);
1344
1345 SDValue OrigIndex = VAIndex;
1346
1347 if (ArgAlignInBytes > 4) {
1348 OrigIndex = DAG.getNode(ISD::ADD, DL, PtrVT, OrigIndex,
1349 DAG.getConstant(ArgAlignInBytes - 1, DL, MVT::i32));
1350 OrigIndex =
1351 DAG.getNode(ISD::AND, DL, PtrVT, OrigIndex,
1352 DAG.getSignedConstant(-ArgAlignInBytes, DL, MVT::i32));
1353 }
1354
1355 VAIndex = DAG.getNode(ISD::ADD, DL, PtrVT, OrigIndex,
1356 DAG.getConstant(VASizeInBytes, DL, MVT::i32));
1357
1358 SDValue CC = DAG.getSetCC(DL, MVT::i32, OrigIndex,
1359 DAG.getConstant(6 * 4, DL, MVT::i32), ISD::SETLE);
1360
1361 SDValue StkIndex =
1362 DAG.getNode(ISD::ADD, DL, PtrVT, VAIndex,
1363 DAG.getConstant(32 + VASizeInBytes, DL, MVT::i32));
1364
1365 CC = DAG.getSetCC(DL, MVT::i32, VAIndex, DAG.getConstant(6 * 4, DL, MVT::i32),
1366 ISD::SETLE);
1367
1368 SDValue Array = DAG.getNode(ISD::SELECT, DL, MVT::i32, CC, VAReg, VAStack);
1369
1370 VAIndex = DAG.getNode(ISD::SELECT, DL, MVT::i32, CC, VAIndex, StkIndex);
1371
1372 CC = DAG.getSetCC(DL, MVT::i32, VAIndex, DAG.getConstant(6 * 4, DL, MVT::i32),
1373 ISD::SETLE);
1374
1375 SDValue VAIndexStore = DAG.getStore(InChain, DL, VAIndex, VarArgIndexPtr,
1376 MachinePointerInfo(SV));
1377 InChain = VAIndexStore;
1378
1379 SDValue Addr = DAG.getNode(ISD::SUB, DL, PtrVT, VAIndex,
1380 DAG.getConstant(VASizeInBytes, DL, MVT::i32));
1381
1382 Addr = DAG.getNode(ISD::ADD, DL, PtrVT, Array, Addr);
1383
1384 return DAG.getLoad(VT, DL, InChain, Addr, MachinePointerInfo());
1385}
1386
1387SDValue XtensaTargetLowering::LowerShiftLeftParts(SDValue Op,
1388 SelectionDAG &DAG) const {
1389 SDLoc DL(Op);
1390 MVT VT = MVT::i32;
1391 SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1);
1392 SDValue Shamt = Op.getOperand(2);
1393
1394 // if Shamt - register size < 0: // Shamt < register size
1395 // Lo = Lo << Shamt
1396 // Hi = (Hi << Shamt) | (Lo >>u (register size - Shamt))
1397 // else:
1398 // Lo = 0
1399 // Hi = Lo << (Shamt - register size)
1400
1401 SDValue MinusRegisterSize = DAG.getSignedConstant(-32, DL, VT);
1402 SDValue ShamtMinusRegisterSize =
1403 DAG.getNode(ISD::ADD, DL, VT, Shamt, MinusRegisterSize);
1404
1405 SDValue LoTrue = DAG.getNode(ISD::SHL, DL, VT, Lo, Shamt);
1406 SDValue HiTrue = DAG.getNode(XtensaISD::SRCL, DL, VT, Hi, Lo, Shamt);
1407 SDValue Zero = DAG.getConstant(0, DL, VT);
1408 SDValue HiFalse = DAG.getNode(ISD::SHL, DL, VT, Lo, ShamtMinusRegisterSize);
1409
1410 SDValue Cond = DAG.getSetCC(DL, VT, ShamtMinusRegisterSize, Zero, ISD::SETLT);
1411 Lo = DAG.getNode(ISD::SELECT, DL, VT, Cond, LoTrue, Zero);
1412 Hi = DAG.getNode(ISD::SELECT, DL, VT, Cond, HiTrue, HiFalse);
1413
1414 return DAG.getMergeValues({Lo, Hi}, DL);
1415}
1416
1417SDValue XtensaTargetLowering::LowerShiftRightParts(SDValue Op,
1418 SelectionDAG &DAG,
1419 bool IsSRA) const {
1420 SDLoc DL(Op);
1421 SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1);
1422 SDValue Shamt = Op.getOperand(2);
1423 MVT VT = MVT::i32;
1424
1425 // SRA expansion:
1426 // if Shamt - register size < 0: // Shamt < register size
1427 // Lo = (Lo >>u Shamt) | (Hi << u (register size - Shamt))
1428 // Hi = Hi >>s Shamt
1429 // else:
1430 // Lo = Hi >>s (Shamt - register size);
1431 // Hi = Hi >>s (register size - 1)
1432 //
1433 // SRL expansion:
1434 // if Shamt - register size < 0: // Shamt < register size
1435 // Lo = (Lo >>u Shamt) | (Hi << u (register size - Shamt))
1436 // Hi = Hi >>u Shamt
1437 // else:
1438 // Lo = Hi >>u (Shamt - register size);
1439 // Hi = 0;
1440
1441 unsigned ShiftRightOp = IsSRA ? ISD::SRA : ISD::SRL;
1442 SDValue MinusRegisterSize = DAG.getSignedConstant(-32, DL, VT);
1443 SDValue RegisterSizeMinus1 = DAG.getConstant(32 - 1, DL, VT);
1444 SDValue ShamtMinusRegisterSize =
1445 DAG.getNode(ISD::ADD, DL, VT, Shamt, MinusRegisterSize);
1446
1447 SDValue LoTrue = DAG.getNode(XtensaISD::SRCR, DL, VT, Hi, Lo, Shamt);
1448 SDValue HiTrue = DAG.getNode(ShiftRightOp, DL, VT, Hi, Shamt);
1449 SDValue Zero = DAG.getConstant(0, DL, VT);
1450 SDValue LoFalse =
1451 DAG.getNode(ShiftRightOp, DL, VT, Hi, ShamtMinusRegisterSize);
1452 SDValue HiFalse;
1453
1454 if (IsSRA) {
1455 HiFalse = DAG.getNode(ShiftRightOp, DL, VT, Hi, RegisterSizeMinus1);
1456 } else {
1457 HiFalse = Zero;
1458 }
1459
1460 SDValue Cond = DAG.getSetCC(DL, VT, ShamtMinusRegisterSize, Zero, ISD::SETLT);
1461 Lo = DAG.getNode(ISD::SELECT, DL, VT, Cond, LoTrue, LoFalse);
1462 Hi = DAG.getNode(ISD::SELECT, DL, VT, Cond, HiTrue, HiFalse);
1463
1464 return DAG.getMergeValues({Lo, Hi}, DL);
1465}
1466
1467SDValue XtensaTargetLowering::LowerCTPOP(SDValue Op, SelectionDAG &DAG) const {
1468 auto &TLI = DAG.getTargetLoweringInfo();
1469 return TLI.expandCTPOP(Op.getNode(), DAG);
1470}
1471
1473 SDValue C) const {
1474 APInt Imm;
1475 unsigned EltSizeInBits;
1476
1477 if (ISD::isConstantSplatVector(C.getNode(), Imm)) {
1478 EltSizeInBits = VT.getScalarSizeInBits();
1479 } else if (VT.isScalarInteger()) {
1480 EltSizeInBits = VT.getSizeInBits();
1481 if (auto *ConstNode = dyn_cast<ConstantSDNode>(C.getNode()))
1482 Imm = ConstNode->getAPIntValue();
1483 else
1484 return false;
1485 } else {
1486 return false;
1487 }
1488
1489 // Omit if data size exceeds.
1490 if (EltSizeInBits > 32)
1491 return false;
1492
1493 // Convert MULT to LSL.
1494 if (Imm.isPowerOf2() && Imm.isIntN(5))
1495 return true;
1496
1497 return false;
1498}
1499
1501 SelectionDAG &DAG) const {
1502 switch (Op.getOpcode()) {
1503 case ISD::BR_JT:
1504 return LowerBR_JT(Op, DAG);
1505 case ISD::Constant:
1506 return LowerImmediate(Op, DAG);
1507 case ISD::RETURNADDR:
1508 return LowerRETURNADDR(Op, DAG);
1509 case ISD::GlobalAddress:
1510 return LowerGlobalAddress(Op, DAG);
1512 return LowerGlobalTLSAddress(Op, DAG);
1513 case ISD::BlockAddress:
1514 return LowerBlockAddress(Op, DAG);
1515 case ISD::JumpTable:
1516 return LowerJumpTable(Op, DAG);
1517 case ISD::CTPOP:
1518 return LowerCTPOP(Op, DAG);
1519 case ISD::ConstantPool:
1520 return LowerConstantPool(Op, DAG);
1521 case ISD::SELECT_CC:
1522 return LowerSELECT_CC(Op, DAG);
1523 case ISD::STACKSAVE:
1524 return LowerSTACKSAVE(Op, DAG);
1525 case ISD::STACKRESTORE:
1526 return LowerSTACKRESTORE(Op, DAG);
1527 case ISD::FRAMEADDR:
1528 return LowerFRAMEADDR(Op, DAG);
1530 return LowerDYNAMIC_STACKALLOC(Op, DAG);
1531 case ISD::VASTART:
1532 return LowerVASTART(Op, DAG);
1533 case ISD::VAARG:
1534 return LowerVAARG(Op, DAG);
1535 case ISD::VACOPY:
1536 return LowerVACOPY(Op, DAG);
1537 case ISD::SHL_PARTS:
1538 return LowerShiftLeftParts(Op, DAG);
1539 case ISD::SRA_PARTS:
1540 return LowerShiftRightParts(Op, DAG, true);
1541 case ISD::SRL_PARTS:
1542 return LowerShiftRightParts(Op, DAG, false);
1543 default:
1544 report_fatal_error("Unexpected node to lower");
1545 }
1546}
1547
1552
1553//===----------------------------------------------------------------------===//
1554// Custom insertion
1555//===----------------------------------------------------------------------===//
1556
1558XtensaTargetLowering::emitSelectCC(MachineInstr &MI,
1559 MachineBasicBlock *MBB) const {
1560 const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
1561 DebugLoc DL = MI.getDebugLoc();
1562
1563 MachineOperand &LHS = MI.getOperand(1);
1564 MachineOperand &RHS = MI.getOperand(2);
1565 MachineOperand &TrueValue = MI.getOperand(3);
1566 MachineOperand &FalseValue = MI.getOperand(4);
1567
1568 // To "insert" a SELECT_CC instruction, we actually have to insert
1569 // CopyMBB and SinkMBB blocks and add branch to MBB. We build phi
1570 // operation in SinkMBB like phi (TrueVakue,FalseValue), where TrueValue
1571 // is passed from MMB and FalseValue is passed from CopyMBB.
1572 // MBB
1573 // | \
1574 // | CopyMBB
1575 // | /
1576 // SinkMBB
1577 // The incoming instruction knows the
1578 // destination vreg to set, the condition code register to branch on, the
1579 // true/false values to select between, and a branch opcode to use.
1580 const BasicBlock *LLVM_BB = MBB->getBasicBlock();
1581 MachineFunction::iterator It = ++MBB->getIterator();
1582
1583 MachineFunction *F = MBB->getParent();
1584 MachineBasicBlock *CopyMBB = F->CreateMachineBasicBlock(LLVM_BB);
1585 MachineBasicBlock *SinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
1586
1587 F->insert(It, CopyMBB);
1588 F->insert(It, SinkMBB);
1589
1590 // Transfer the remainder of MBB and its successor edges to SinkMBB.
1591 SinkMBB->splice(SinkMBB->begin(), MBB,
1592 std::next(MachineBasicBlock::iterator(MI)), MBB->end());
1594
1595 MBB->addSuccessor(CopyMBB);
1596 MBB->addSuccessor(SinkMBB);
1597
1598 if (MI.getOpcode() == Xtensa::SELECT_CC_FP_FP ||
1599 MI.getOpcode() == Xtensa::SELECT_CC_FP_INT) {
1600 unsigned CmpKind = MI.getOperand(5).getImm();
1601 unsigned BrKind = MI.getOperand(6).getImm();
1602 MCPhysReg BReg = Xtensa::B0;
1603
1604 BuildMI(MBB, DL, TII.get(CmpKind), BReg)
1605 .addReg(LHS.getReg())
1606 .addReg(RHS.getReg());
1607 BuildMI(MBB, DL, TII.get(BrKind))
1608 .addReg(BReg, RegState::Kill)
1609 .addMBB(SinkMBB);
1610 } else {
1611 unsigned BrKind = MI.getOperand(5).getImm();
1612 BuildMI(MBB, DL, TII.get(BrKind))
1613 .addReg(LHS.getReg())
1614 .addReg(RHS.getReg())
1615 .addMBB(SinkMBB);
1616 }
1617
1618 CopyMBB->addSuccessor(SinkMBB);
1619
1620 // SinkMBB:
1621 // %Result = phi [ %FalseValue, CopyMBB ], [ %TrueValue, MBB ]
1622 // ...
1623
1624 BuildMI(*SinkMBB, SinkMBB->begin(), DL, TII.get(Xtensa::PHI),
1625 MI.getOperand(0).getReg())
1626 .addReg(FalseValue.getReg())
1627 .addMBB(CopyMBB)
1628 .addReg(TrueValue.getReg())
1629 .addMBB(MBB);
1630
1631 MI.eraseFromParent(); // The pseudo instruction is gone now.
1632 return SinkMBB;
1633}
1634
1637 DebugLoc DL = MI.getDebugLoc();
1638 const XtensaInstrInfo &TII = *Subtarget.getInstrInfo();
1639
1640 switch (MI.getOpcode()) {
1641 case Xtensa::BRCC_FP: {
1642 MachineOperand &Cond = MI.getOperand(0);
1643 MachineOperand &LHS = MI.getOperand(1);
1644 MachineOperand &RHS = MI.getOperand(2);
1645 MachineBasicBlock *TargetBB = MI.getOperand(3).getMBB();
1646 unsigned BrKind = 0;
1647 unsigned CmpKind = 0;
1648 ISD::CondCode CondCode = (ISD::CondCode)Cond.getImm();
1649 MCPhysReg BReg = Xtensa::B0;
1650
1651 std::tie(BrKind, CmpKind) = getFPBranchKind(CondCode);
1652 BuildMI(*MBB, MI, DL, TII.get(CmpKind), BReg)
1653 .addReg(LHS.getReg())
1654 .addReg(RHS.getReg());
1655 BuildMI(*MBB, MI, DL, TII.get(BrKind))
1656 .addReg(BReg, RegState::Kill)
1657 .addMBB(TargetBB);
1658
1659 MI.eraseFromParent();
1660 return MBB;
1661 }
1662 case Xtensa::SELECT_CC_FP_FP:
1663 case Xtensa::SELECT_CC_FP_INT:
1664 case Xtensa::SELECT_CC_INT_FP:
1665 case Xtensa::SELECT:
1666 return emitSelectCC(MI, MBB);
1667 case Xtensa::S8I:
1668 case Xtensa::S16I:
1669 case Xtensa::S32I:
1670 case Xtensa::S32I_N:
1671 case Xtensa::SSI:
1672 case Xtensa::SSIP:
1673 case Xtensa::SSX:
1674 case Xtensa::SSXP:
1675 case Xtensa::L8UI:
1676 case Xtensa::L16SI:
1677 case Xtensa::L16UI:
1678 case Xtensa::L32I:
1679 case Xtensa::L32I_N:
1680 case Xtensa::LSI:
1681 case Xtensa::LSIP:
1682 case Xtensa::LSX:
1683 case Xtensa::LSXP: {
1684 // Insert memory wait instruction "memw" before volatile load/store as it is
1685 // implemented in gcc. If memoperands is empty then assume that it aslo
1686 // maybe volatile load/store and insert "memw".
1687 if (MI.memoperands_empty() || (*MI.memoperands_begin())->isVolatile()) {
1688 BuildMI(*MBB, MI, DL, TII.get(Xtensa::MEMW));
1689 }
1690 return MBB;
1691 }
1692 case Xtensa::MOVSP_P: {
1693 MachineOperand &NewSP = MI.getOperand(0);
1694
1695 BuildMI(*MBB, MI, DL, TII.get(Xtensa::MOVSP), Xtensa::SP)
1696 .addReg(NewSP.getReg());
1697 MI.eraseFromParent();
1698
1699 return MBB;
1700 }
1701 case Xtensa::ATOMIC_CMP_SWAP_32_P: {
1702 MachineOperand &R = MI.getOperand(0);
1703 MachineOperand &Addr = MI.getOperand(1);
1704 MachineOperand &Cmp = MI.getOperand(2);
1705 MachineOperand &Swap = MI.getOperand(3);
1706
1707 BuildMI(*MBB, MI, DL, TII.get(Xtensa::WSR), Xtensa::SCOMPARE1)
1708 .addReg(Cmp.getReg());
1709
1710 BuildMI(*MBB, MI, DL, TII.get(Xtensa::S32C1I), R.getReg())
1711 .addReg(Swap.getReg())
1712 .addReg(Addr.getReg())
1713 .addImm(0);
1714
1715 MI.eraseFromParent();
1716 return MBB;
1717 }
1718 default:
1719 llvm_unreachable("Unexpected instr type to insert");
1720 }
1721}
return SDValue()
unsigned RegSize
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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:1587
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:43
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:68
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)
LLVM_ABI 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 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 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 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.
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 ...
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...
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:343
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:309
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:319
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.
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.
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
XtensaTargetLowering(const TargetMachine &TM, const XtensaSubtarget &STI)
Register getExceptionPointerRegister(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...
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
#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
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h:829
@ 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:275
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:789
@ 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:264
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
Definition ISDOpcodes.h:520
@ GlobalAddress
Definition ISDOpcodes.h:88
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition ISDOpcodes.h:890
@ FADD
Simple binary floating point operators.
Definition ISDOpcodes.h:417
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition ISDOpcodes.h:280
@ 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:89
@ CTLZ_ZERO_POISON
Definition ISDOpcodes.h:798
@ 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:806
@ 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:706
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:771
@ 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:821
@ 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:898
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition ISDOpcodes.h:729
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition ISDOpcodes.h:110
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition ISDOpcodes.h:936
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:741
@ TRAP
TRAP - Trapping instruction.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition ISDOpcodes.h:53
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
Definition ISDOpcodes.h:797
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:866
@ 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:843
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition ISDOpcodes.h:62
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
Definition ISDOpcodes.h:536
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,...
NodeAddr< NodeBase * > Node
Definition RDFGraph.h:381
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:578
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:332
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:144
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
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:77
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