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