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