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