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