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