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