LLVM 20.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
46 const XtensaSubtarget &STI)
47 : TargetLowering(TM), Subtarget(STI) {
48 MVT PtrVT = MVT::i32;
49 // Set up the register classes.
50 addRegisterClass(MVT::i32, &Xtensa::ARRegClass);
51
52 // Set up special registers.
54
56
58
61
63
67
74
75 // No sign extend instructions for i1 and sign extend load i8
76 for (MVT VT : MVT::integer_valuetypes()) {
81 }
82
87
88 // Expand jump table branches as address arithmetic followed by an
89 // indirect jump.
91
95
99
104
110
117
121
130
131 // Implement custom stack allocations
133 // Implement custom stack save and restore
136
137 // VASTART, VAARG and VACOPY need to deal with the Xtensa-specific varargs
138 // structure, but VAEND is a no-op.
143
144 // Compute derived properties from the register classes
146}
147
149 const GlobalAddressSDNode *GA) const {
150 // The Xtensa target isn't yet aware of offsets.
151 return false;
152}
153
154//===----------------------------------------------------------------------===//
155// Inline asm support
156//===----------------------------------------------------------------------===//
159 if (Constraint.size() == 1) {
160 switch (Constraint[0]) {
161 case 'r':
162 return C_RegisterClass;
163 default:
164 break;
165 }
166 }
167 return TargetLowering::getConstraintType(Constraint);
168}
169
172 AsmOperandInfo &Info, const char *Constraint) const {
174 Value *CallOperandVal = Info.CallOperandVal;
175 // If we don't have a value, we can't do a match,
176 // but allow it at the lowest weight.
177 if (!CallOperandVal)
178 return CW_Default;
179
180 Type *Ty = CallOperandVal->getType();
181
182 // Look at the constraint type.
183 switch (*Constraint) {
184 default:
186 break;
187 case 'r':
188 if (Ty->isIntegerTy())
189 Weight = CW_Register;
190 break;
191 }
192 return Weight;
193}
194
195std::pair<unsigned, const TargetRegisterClass *>
197 const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
198 if (Constraint.size() == 1) {
199 // GCC Constraint Letters
200 switch (Constraint[0]) {
201 default:
202 break;
203 case 'r': // General-purpose register
204 return std::make_pair(0U, &Xtensa::ARRegClass);
205 }
206 }
208}
209
211 SDValue Op, StringRef Constraint, std::vector<SDValue> &Ops,
212 SelectionDAG &DAG) const {
213 SDLoc DL(Op);
214
215 // Only support length 1 constraints for now.
216 if (Constraint.size() > 1)
217 return;
218
220}
221
222//===----------------------------------------------------------------------===//
223// Calling conventions
224//===----------------------------------------------------------------------===//
225
226#include "XtensaGenCallingConv.inc"
227
228static const MCPhysReg IntRegs[] = {Xtensa::A2, Xtensa::A3, Xtensa::A4,
229 Xtensa::A5, Xtensa::A6, Xtensa::A7};
230
231static bool CC_Xtensa_Custom(unsigned ValNo, MVT ValVT, MVT LocVT,
232 CCValAssign::LocInfo LocInfo,
233 ISD::ArgFlagsTy ArgFlags, CCState &State) {
234 if (ArgFlags.isByVal()) {
235 Align ByValAlign = ArgFlags.getNonZeroByValAlign();
236 unsigned ByValSize = ArgFlags.getByValSize();
237 if (ByValSize < 4) {
238 ByValSize = 4;
239 }
240 if (ByValAlign < Align(4)) {
241 ByValAlign = Align(4);
242 }
243 unsigned Offset = State.AllocateStack(ByValSize, ByValAlign);
244 State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
245 // Mark all unused registers as allocated to avoid misuse
246 // of such registers.
247 while (State.AllocateReg(IntRegs))
248 ;
249 return false;
250 }
251
252 // Promote i8 and i16
253 if (LocVT == MVT::i8 || LocVT == MVT::i16) {
254 LocVT = MVT::i32;
255 if (ArgFlags.isSExt())
256 LocInfo = CCValAssign::SExt;
257 else if (ArgFlags.isZExt())
258 LocInfo = CCValAssign::ZExt;
259 else
260 LocInfo = CCValAssign::AExt;
261 }
262
263 unsigned Register;
264
265 Align OrigAlign = ArgFlags.getNonZeroOrigAlign();
266 bool needs64BitAlign = (ValVT == MVT::i32 && OrigAlign == Align(8));
267 bool needs128BitAlign = (ValVT == MVT::i32 && OrigAlign == Align(16));
268
269 if (ValVT == MVT::i32) {
271 // If this is the first part of an i64 arg,
272 // the allocated register must be either A2, A4 or A6.
273 if (needs64BitAlign && (Register == Xtensa::A3 || Register == Xtensa::A5 ||
274 Register == Xtensa::A7))
276 // arguments with 16byte alignment must be passed in the first register or
277 // passed via stack
278 if (needs128BitAlign && (Register != Xtensa::A2))
279 while ((Register = State.AllocateReg(IntRegs)))
280 ;
281 LocVT = MVT::i32;
282 } else if (ValVT == MVT::f64) {
283 // Allocate int register and shadow next int register.
285 if (Register == Xtensa::A3 || Register == Xtensa::A5 ||
286 Register == Xtensa::A7)
288 State.AllocateReg(IntRegs);
289 LocVT = MVT::i32;
290 } else {
291 report_fatal_error("Cannot handle this ValVT.");
292 }
293
294 if (!Register) {
295 unsigned Offset = State.AllocateStack(ValVT.getStoreSize(), OrigAlign);
296 State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
297 } else {
298 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Register, LocVT, LocInfo));
299 }
300
301 return false;
302}
303
304CCAssignFn *XtensaTargetLowering::CCAssignFnForCall(CallingConv::ID CC,
305 bool IsVarArg) const {
306 return CC_Xtensa_Custom;
307}
308
310 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
311 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
312 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
314 MachineFrameInfo &MFI = MF.getFrameInfo();
316
317 // Used with vargs to acumulate store chains.
318 std::vector<SDValue> OutChains;
319
320 // Assign locations to all of the incoming arguments.
322 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
323 *DAG.getContext());
324
325 CCInfo.AnalyzeFormalArguments(Ins, CCAssignFnForCall(CallConv, IsVarArg));
326
327 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
328 CCValAssign &VA = ArgLocs[i];
329 // Arguments stored on registers
330 if (VA.isRegLoc()) {
331 EVT RegVT = VA.getLocVT();
332
333 if (RegVT != MVT::i32)
334 report_fatal_error("RegVT not supported by FormalArguments Lowering");
335
336 // Transform the arguments stored on
337 // physical registers into virtual ones
338 Register Reg = MF.addLiveIn(VA.getLocReg(), &Xtensa::ARRegClass);
339 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, RegVT);
340
341 // If this is an 8 or 16-bit value, it has been passed promoted
342 // to 32 bits. Insert an assert[sz]ext to capture this, then
343 // truncate to the right size.
344 if (VA.getLocInfo() != CCValAssign::Full) {
345 unsigned Opcode = 0;
346 if (VA.getLocInfo() == CCValAssign::SExt)
347 Opcode = ISD::AssertSext;
348 else if (VA.getLocInfo() == CCValAssign::ZExt)
349 Opcode = ISD::AssertZext;
350 if (Opcode)
351 ArgValue = DAG.getNode(Opcode, DL, RegVT, ArgValue,
352 DAG.getValueType(VA.getValVT()));
353 ArgValue = DAG.getNode((VA.getValVT() == MVT::f32) ? ISD::BITCAST
355 DL, VA.getValVT(), ArgValue);
356 }
357
358 InVals.push_back(ArgValue);
359
360 } else {
361 assert(VA.isMemLoc());
362
363 EVT ValVT = VA.getValVT();
364
365 // The stack pointer offset is relative to the caller stack frame.
366 int FI = MFI.CreateFixedObject(ValVT.getStoreSize(), VA.getLocMemOffset(),
367 true);
368
369 if (Ins[VA.getValNo()].Flags.isByVal()) {
370 // Assume that in this case load operation is created
371 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
372 InVals.push_back(FIN);
373 } else {
374 // Create load nodes to retrieve arguments from the stack
375 SDValue FIN =
377 InVals.push_back(DAG.getLoad(
378 ValVT, DL, Chain, FIN,
380 }
381 }
382 }
383
384 if (IsVarArg) {
385 unsigned Idx = CCInfo.getFirstUnallocated(IntRegs);
386 unsigned ArgRegsNum = std::size(IntRegs);
387 const TargetRegisterClass *RC = &Xtensa::ARRegClass;
388 MachineFrameInfo &MFI = MF.getFrameInfo();
389 MachineRegisterInfo &RegInfo = MF.getRegInfo();
390 unsigned RegSize = 4;
391 MVT RegTy = MVT::i32;
392 MVT FITy = getFrameIndexTy(DAG.getDataLayout());
393
394 XtensaFI->setVarArgsFirstGPR(Idx + 2); // 2 - number of a2 register
395
397 MFI.CreateFixedObject(4, CCInfo.getStackSize(), true));
398
399 // Offset of the first variable argument from stack pointer, and size of
400 // the vararg save area. For now, the varargs save area is either zero or
401 // large enough to hold a0-a7.
402 int VaArgOffset, VarArgsSaveSize;
403
404 // If all registers are allocated, then all varargs must be passed on the
405 // stack and we don't need to save any argregs.
406 if (ArgRegsNum == Idx) {
407 VaArgOffset = CCInfo.getStackSize();
408 VarArgsSaveSize = 0;
409 } else {
410 VarArgsSaveSize = RegSize * (ArgRegsNum - Idx);
411 VaArgOffset = -VarArgsSaveSize;
412
413 // Record the frame index of the first variable argument
414 // which is a value necessary to VASTART.
415 int FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true);
416 XtensaFI->setVarArgsInRegsFrameIndex(FI);
417
418 // Copy the integer registers that may have been used for passing varargs
419 // to the vararg save area.
420 for (unsigned I = Idx; I < ArgRegsNum; ++I, VaArgOffset += RegSize) {
421 const Register Reg = RegInfo.createVirtualRegister(RC);
422 RegInfo.addLiveIn(IntRegs[I], Reg);
423
424 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, RegTy);
425 FI = MFI.CreateFixedObject(RegSize, VaArgOffset, true);
426 SDValue PtrOff = DAG.getFrameIndex(FI, FITy);
427 SDValue Store = DAG.getStore(Chain, DL, ArgValue, PtrOff,
429 OutChains.push_back(Store);
430 }
431 }
432 }
433
434 // All stores are grouped in one node to allow the matching between
435 // the size of Ins and InVals. This only happens when on varg functions
436 if (!OutChains.empty()) {
437 OutChains.push_back(Chain);
438 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
439 }
440
441 return Chain;
442}
443
446 SmallVectorImpl<SDValue> &InVals) const {
447 SelectionDAG &DAG = CLI.DAG;
448 SDLoc &DL = CLI.DL;
450 SmallVector<SDValue, 32> &OutVals = CLI.OutVals;
452 SDValue Chain = CLI.Chain;
453 SDValue Callee = CLI.Callee;
454 bool &IsTailCall = CLI.IsTailCall;
455 CallingConv::ID CallConv = CLI.CallConv;
456 bool IsVarArg = CLI.IsVarArg;
457
459 EVT PtrVT = getPointerTy(DAG.getDataLayout());
460 const TargetFrameLowering *TFL = Subtarget.getFrameLowering();
461
462 // TODO: Support tail call optimization.
463 IsTailCall = false;
464
465 // Analyze the operands of the call, assigning locations to each operand.
467 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
468
469 CCAssignFn *CC = CCAssignFnForCall(CallConv, IsVarArg);
470
471 CCInfo.AnalyzeCallOperands(Outs, CC);
472
473 // Get a count of how many bytes are to be pushed on the stack.
474 unsigned NumBytes = CCInfo.getStackSize();
475
476 Align StackAlignment = TFL->getStackAlign();
477 unsigned NextStackOffset = alignTo(NumBytes, StackAlignment);
478
479 Chain = DAG.getCALLSEQ_START(Chain, NextStackOffset, 0, DL);
480
481 // Copy argument values to their designated locations.
482 std::deque<std::pair<unsigned, SDValue>> RegsToPass;
483 SmallVector<SDValue, 8> MemOpChains;
484 SDValue StackPtr;
485 for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) {
486 CCValAssign &VA = ArgLocs[I];
487 SDValue ArgValue = OutVals[I];
488 ISD::ArgFlagsTy Flags = Outs[I].Flags;
489
490 if (VA.isRegLoc())
491 // Queue up the argument copies and emit them at the end.
492 RegsToPass.push_back(std::make_pair(VA.getLocReg(), ArgValue));
493 else if (Flags.isByVal()) {
494 assert(VA.isMemLoc());
495 assert(Flags.getByValSize() &&
496 "ByVal args of size 0 should have been ignored by front-end.");
497 assert(!IsTailCall &&
498 "Do not tail-call optimize if there is a byval argument.");
499
500 if (!StackPtr.getNode())
501 StackPtr = DAG.getCopyFromReg(Chain, DL, Xtensa::SP, PtrVT);
502 unsigned Offset = VA.getLocMemOffset();
503 SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,
505 SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), DL, MVT::i32);
506 SDValue Memcpy = DAG.getMemcpy(
507 Chain, DL, Address, ArgValue, SizeNode, Flags.getNonZeroByValAlign(),
508 /*isVolatile=*/false, /*AlwaysInline=*/false,
509 /*CI=*/nullptr, std::nullopt, MachinePointerInfo(),
511 MemOpChains.push_back(Memcpy);
512 } else {
513 assert(VA.isMemLoc() && "Argument not register or memory");
514
515 // Work out the address of the stack slot. Unpromoted ints and
516 // floats are passed as right-justified 8-byte values.
517 if (!StackPtr.getNode())
518 StackPtr = DAG.getCopyFromReg(Chain, DL, Xtensa::SP, PtrVT);
519 unsigned Offset = VA.getLocMemOffset();
520 SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,
522
523 // Emit the store.
524 MemOpChains.push_back(
525 DAG.getStore(Chain, DL, ArgValue, Address, MachinePointerInfo()));
526 }
527 }
528
529 // Join the stores, which are independent of one another.
530 if (!MemOpChains.empty())
531 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains);
532
533 // Build a sequence of copy-to-reg nodes, chained and glued together.
534 SDValue Glue;
535 for (unsigned I = 0, E = RegsToPass.size(); I != E; ++I) {
536 unsigned Reg = RegsToPass[I].first;
537 Chain = DAG.getCopyToReg(Chain, DL, Reg, RegsToPass[I].second, Glue);
538 Glue = Chain.getValue(1);
539 }
540 std::string name;
541 unsigned char TF = 0;
542
543 // Accept direct calls by converting symbolic call addresses to the
544 // associated Target* opcodes.
545 if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
546 name = E->getSymbol();
547 TF = E->getTargetFlags();
548 if (isPositionIndependent()) {
549 report_fatal_error("PIC relocations is not supported");
550 } else
551 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, TF);
552 } else if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
553 const GlobalValue *GV = G->getGlobal();
554 name = GV->getName().str();
555 }
556
557 if ((!name.empty()) && isLongCall(name.c_str())) {
558 // Create a constant pool entry for the callee address
560
562 *DAG.getContext(), name.c_str(), 0 /* XtensaCLabelIndex */, false,
563 Modifier);
564
565 // Get the address of the callee into a register
566 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4), 0, TF);
567 SDValue CPWrap = getAddrPCRel(CPAddr, DAG);
568 Callee = CPWrap;
569 }
570
571 // The first call operand is the chain and the second is the target address.
573 Ops.push_back(Chain);
574 Ops.push_back(Callee);
575
576 // Add a register mask operand representing the call-preserved registers.
577 const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
578 const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv);
579 assert(Mask && "Missing call preserved mask for calling convention");
580 Ops.push_back(DAG.getRegisterMask(Mask));
581
582 // Add argument registers to the end of the list so that they are
583 // known live into the call.
584 for (unsigned I = 0, E = RegsToPass.size(); I != E; ++I) {
585 unsigned Reg = RegsToPass[I].first;
586 Ops.push_back(DAG.getRegister(Reg, RegsToPass[I].second.getValueType()));
587 }
588
589 // Glue the call to the argument copies, if any.
590 if (Glue.getNode())
591 Ops.push_back(Glue);
592
593 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
594 Chain = DAG.getNode(XtensaISD::CALL, DL, NodeTys, Ops);
595 Glue = Chain.getValue(1);
596
597 // Mark the end of the call, which is glued to the call itself.
598 Chain = DAG.getCALLSEQ_END(Chain, DAG.getConstant(NumBytes, DL, PtrVT, true),
599 DAG.getConstant(0, DL, PtrVT, true), Glue, DL);
600 Glue = Chain.getValue(1);
601
602 // Assign locations to each value returned by this call.
604 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, *DAG.getContext());
605 RetCCInfo.AnalyzeCallResult(Ins, RetCC_Xtensa);
606
607 // Copy all of the result registers out of their specified physreg.
608 for (unsigned I = 0, E = RetLocs.size(); I != E; ++I) {
609 CCValAssign &VA = RetLocs[I];
610
611 // Copy the value out, gluing the copy to the end of the call sequence.
612 unsigned Reg = VA.getLocReg();
613 SDValue RetValue = DAG.getCopyFromReg(Chain, DL, Reg, VA.getLocVT(), Glue);
614 Chain = RetValue.getValue(1);
615 Glue = RetValue.getValue(2);
616
617 InVals.push_back(RetValue);
618 }
619 return Chain;
620}
621
623 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
624 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
625 const Type *RetTy) const {
627 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
628 return CCInfo.CheckReturn(Outs, RetCC_Xtensa);
629}
630
633 bool IsVarArg,
635 const SmallVectorImpl<SDValue> &OutVals,
636 const SDLoc &DL, SelectionDAG &DAG) const {
638
639 // Assign locations to each returned value.
641 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, *DAG.getContext());
642 RetCCInfo.AnalyzeReturn(Outs, RetCC_Xtensa);
643
644 SDValue Glue;
645 // Quick exit for void returns
646 if (RetLocs.empty())
647 return DAG.getNode(XtensaISD::RET, DL, MVT::Other, Chain);
648
649 // Copy the result values into the output registers.
651 RetOps.push_back(Chain);
652 for (unsigned I = 0, E = RetLocs.size(); I != E; ++I) {
653 CCValAssign &VA = RetLocs[I];
654 SDValue RetValue = OutVals[I];
655
656 // Make the return register live on exit.
657 assert(VA.isRegLoc() && "Can only return in registers!");
658
659 // Chain and glue the copies together.
660 unsigned Register = VA.getLocReg();
661 Chain = DAG.getCopyToReg(Chain, DL, Register, RetValue, Glue);
662 Glue = Chain.getValue(1);
663 RetOps.push_back(DAG.getRegister(Register, VA.getLocVT()));
664 }
665
666 // Update chain and glue.
667 RetOps[0] = Chain;
668 if (Glue.getNode())
669 RetOps.push_back(Glue);
670
671 return DAG.getNode(XtensaISD::RET, DL, MVT::Other, RetOps);
672}
673
675 switch (Cond) {
676 case ISD::SETEQ:
677 return Xtensa::BEQ;
678 case ISD::SETNE:
679 return Xtensa::BNE;
680 case ISD::SETLT:
681 return Xtensa::BLT;
682 case ISD::SETLE:
683 return Xtensa::BGE;
684 case ISD::SETGT:
685 return Xtensa::BLT;
686 case ISD::SETGE:
687 return Xtensa::BGE;
688 case ISD::SETULT:
689 return Xtensa::BLTU;
690 case ISD::SETULE:
691 return Xtensa::BGEU;
692 case ISD::SETUGT:
693 return Xtensa::BLTU;
694 case ISD::SETUGE:
695 return Xtensa::BGEU;
696 default:
697 llvm_unreachable("Unknown branch kind");
698 }
699}
700
701SDValue XtensaTargetLowering::LowerSELECT_CC(SDValue Op,
702 SelectionDAG &DAG) const {
703 SDLoc DL(Op);
704 EVT Ty = Op.getOperand(0).getValueType();
705 SDValue LHS = Op.getOperand(0);
706 SDValue RHS = Op.getOperand(1);
707 SDValue TrueValue = Op.getOperand(2);
708 SDValue FalseValue = Op.getOperand(3);
709 ISD::CondCode CC = cast<CondCodeSDNode>(Op->getOperand(4))->get();
710
711 unsigned BrOpcode = getBranchOpcode(CC);
712 SDValue TargetCC = DAG.getConstant(BrOpcode, DL, MVT::i32);
713
714 return DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, LHS, RHS, TrueValue,
715 FalseValue, TargetCC);
716}
717
718SDValue XtensaTargetLowering::LowerRETURNADDR(SDValue Op,
719 SelectionDAG &DAG) const {
720 // This nodes represent llvm.returnaddress on the DAG.
721 // It takes one operand, the index of the return address to return.
722 // An index of zero corresponds to the current function's return address.
723 // An index of one to the parent's return address, and so on.
724 // Depths > 0 not supported yet!
725 if (Op.getConstantOperandVal(0) != 0)
726 return SDValue();
727
729 MachineFrameInfo &MFI = MF.getFrameInfo();
730 EVT VT = Op.getValueType();
731 MFI.setReturnAddressIsTaken(true);
732
733 // Return RA, which contains the return address. Mark it an implicit
734 // live-in.
735 Register RA = MF.addLiveIn(Xtensa::A0, getRegClassFor(MVT::i32));
736 return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), RA, VT);
737}
738
739SDValue XtensaTargetLowering::LowerImmediate(SDValue Op,
740 SelectionDAG &DAG) const {
741 const ConstantSDNode *CN = cast<ConstantSDNode>(Op);
742 SDLoc DL(CN);
743 APInt APVal = CN->getAPIntValue();
744 int64_t Value = APVal.getSExtValue();
745 if (Op.getValueType() == MVT::i32) {
746 // Check if use node maybe lowered to the MOVI instruction
747 if (Value > -2048 && Value <= 2047)
748 return Op;
749 // Check if use node maybe lowered to the ADDMI instruction
750 SDNode &OpNode = *Op.getNode();
751 if ((OpNode.hasOneUse() && OpNode.user_begin()->getOpcode() == ISD::ADD) &&
752 isShiftedInt<16, 8>(Value))
753 return Op;
754 Type *Ty = Type::getInt32Ty(*DAG.getContext());
755 Constant *CV = ConstantInt::get(Ty, Value);
756 SDValue CP = DAG.getConstantPool(CV, MVT::i32);
757 return CP;
758 }
759 return Op;
760}
761
762SDValue XtensaTargetLowering::LowerGlobalAddress(SDValue Op,
763 SelectionDAG &DAG) const {
764 const GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(Op);
765 SDLoc DL(Op);
766 auto PtrVT = Op.getValueType();
767 const GlobalValue *GV = G->getGlobal();
768
769 SDValue CPAddr = DAG.getTargetConstantPool(GV, PtrVT, Align(4));
770 SDValue CPWrap = getAddrPCRel(CPAddr, DAG);
771
772 return CPWrap;
773}
774
775SDValue XtensaTargetLowering::LowerBlockAddress(SDValue Op,
776 SelectionDAG &DAG) const {
777 BlockAddressSDNode *Node = cast<BlockAddressSDNode>(Op);
778 const BlockAddress *BA = Node->getBlockAddress();
779 EVT PtrVT = Op.getValueType();
780
783 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
784 SDValue CPWrap = getAddrPCRel(CPAddr, DAG);
785
786 return CPWrap;
787}
788
789SDValue XtensaTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) const {
790 SDValue Chain = Op.getOperand(0);
791 SDValue Table = Op.getOperand(1);
792 SDValue Index = Op.getOperand(2);
793 SDLoc DL(Op);
794 JumpTableSDNode *JT = cast<JumpTableSDNode>(Table);
796 const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
797 SDValue TargetJT = DAG.getTargetJumpTable(JT->getIndex(), MVT::i32);
798 const DataLayout &TD = DAG.getDataLayout();
799 EVT PtrVT = Table.getValueType();
800 unsigned EntrySize = MJTI->getEntrySize(TD);
801
802 assert((MJTI->getEntrySize(TD) == 4) && "Unsupported jump-table entry size");
803
804 Index = DAG.getNode(
805 ISD::SHL, DL, Index.getValueType(), Index,
806 DAG.getConstant(Log2_32(EntrySize), DL, Index.getValueType()));
807
808 SDValue Addr = DAG.getNode(ISD::ADD, DL, Index.getValueType(), Index, Table);
809 SDValue LD =
810 DAG.getLoad(PtrVT, DL, Chain, Addr,
812
813 return DAG.getNode(XtensaISD::BR_JT, DL, MVT::Other, LD.getValue(1), LD,
814 TargetJT);
815}
816
817SDValue XtensaTargetLowering::LowerJumpTable(SDValue Op,
818 SelectionDAG &DAG) const {
819 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
820 EVT PtrVT = Op.getValueType();
821
822 // Create a constant pool entry for the callee address
825
826 // Get the address of the callee into a register
827 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
828
829 return getAddrPCRel(CPAddr, DAG);
830}
831
832SDValue XtensaTargetLowering::getAddrPCRel(SDValue Op,
833 SelectionDAG &DAG) const {
834 SDLoc DL(Op);
835 EVT Ty = Op.getValueType();
836 return DAG.getNode(XtensaISD::PCREL_WRAPPER, DL, Ty, Op);
837}
838
839SDValue XtensaTargetLowering::LowerConstantPool(SDValue Op,
840 SelectionDAG &DAG) const {
841 EVT PtrVT = Op.getValueType();
842 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
844
845 if (!CP->isMachineConstantPoolEntry()) {
846 Result = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, CP->getAlign(),
847 CP->getOffset());
848 } else {
849 report_fatal_error("This constantpool type is not supported yet");
850 }
851
852 return getAddrPCRel(Result, DAG);
853}
854
855SDValue XtensaTargetLowering::LowerSTACKSAVE(SDValue Op,
856 SelectionDAG &DAG) const {
857 return DAG.getCopyFromReg(Op.getOperand(0), SDLoc(Op), Xtensa::SP,
858 Op.getValueType());
859}
860
861SDValue XtensaTargetLowering::LowerSTACKRESTORE(SDValue Op,
862 SelectionDAG &DAG) const {
863 return DAG.getCopyToReg(Op.getOperand(0), SDLoc(Op), Xtensa::SP,
864 Op.getOperand(1));
865}
866
867SDValue XtensaTargetLowering::LowerFRAMEADDR(SDValue Op,
868 SelectionDAG &DAG) const {
869 // This nodes represent llvm.frameaddress on the DAG.
870 // It takes one operand, the index of the frame address to return.
871 // An index of zero corresponds to the current function's frame address.
872 // An index of one to the parent's frame address, and so on.
873 // Depths > 0 not supported yet!
874 if (Op.getConstantOperandVal(0) != 0)
875 return SDValue();
876
878 MachineFrameInfo &MFI = MF.getFrameInfo();
879 MFI.setFrameAddressIsTaken(true);
880 EVT VT = Op.getValueType();
881 SDLoc DL(Op);
882
883 Register FrameRegister = Subtarget.getRegisterInfo()->getFrameRegister(MF);
884 SDValue FrameAddr =
885 DAG.getCopyFromReg(DAG.getEntryNode(), DL, FrameRegister, VT);
886 return FrameAddr;
887}
888
889SDValue XtensaTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
890 SelectionDAG &DAG) const {
891 SDValue Chain = Op.getOperand(0); // Legalize the chain.
892 SDValue Size = Op.getOperand(1); // Legalize the size.
893 EVT VT = Size->getValueType(0);
894 SDLoc DL(Op);
895
896 // Round up Size to 32
897 SDValue SizeTmp =
898 DAG.getNode(ISD::ADD, DL, VT, Size, DAG.getConstant(31, DL, MVT::i32));
899 SDValue SizeRoundUp = DAG.getNode(ISD::AND, DL, VT, SizeTmp,
900 DAG.getSignedConstant(~31, DL, MVT::i32));
901
902 unsigned SPReg = Xtensa::SP;
903 SDValue SP = DAG.getCopyFromReg(Chain, DL, SPReg, VT);
904 SDValue NewSP = DAG.getNode(ISD::SUB, DL, VT, SP, SizeRoundUp); // Value
905 Chain = DAG.getCopyToReg(SP.getValue(1), DL, SPReg, NewSP); // Output chain
906
907 SDValue NewVal = DAG.getCopyFromReg(Chain, DL, SPReg, MVT::i32);
908 Chain = NewVal.getValue(1);
909
910 SDValue Ops[2] = {NewVal, Chain};
911 return DAG.getMergeValues(Ops, DL);
912}
913
914SDValue XtensaTargetLowering::LowerVASTART(SDValue Op,
915 SelectionDAG &DAG) const {
918 SDValue Chain = Op.getOperand(0);
919 SDValue Addr = Op.getOperand(1);
920 EVT PtrVT = Addr.getValueType();
921 SDLoc DL(Op);
922
923 // Struct va_list_tag
924 // int32 *va_stk - points to the arguments passed in memory
925 // int32 *va_reg - points to the registers with arguments saved in memory
926 // int32 va_ndx - offset from va_stk or va_reg pointers which points to the
927 // next variable argument
928
929 SDValue VAIndex;
930 SDValue StackOffsetFI =
931 DAG.getFrameIndex(XtensaFI->getVarArgsOnStackFrameIndex(), PtrVT);
932 unsigned ArgWords = XtensaFI->getVarArgsFirstGPR() - 2;
933
934 // If first variable argument passed in registers (maximum words in registers
935 // is 6) then set va_ndx to the position of this argument in registers area
936 // stored in memory (va_reg pointer). Otherwise va_ndx should point to the
937 // position of the first variable argument on stack (va_stk pointer).
938 if (ArgWords < 6) {
939 VAIndex = DAG.getConstant(ArgWords * 4, DL, MVT::i32);
940 } else {
941 VAIndex = DAG.getConstant(32, DL, MVT::i32);
942 }
943
945 DAG.getFrameIndex(XtensaFI->getVarArgsInRegsFrameIndex(), PtrVT);
946 uint64_t FrameOffset = PtrVT.getStoreSize();
947 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
948
949 // Store pointer to arguments given on stack (va_stk)
950 SDValue StackPtr = DAG.getNode(ISD::SUB, DL, PtrVT, StackOffsetFI,
951 DAG.getConstant(32, DL, PtrVT));
952
953 SDValue StoreStackPtr =
954 DAG.getStore(Chain, DL, StackPtr, Addr, MachinePointerInfo(SV));
955
956 uint64_t NextOffset = FrameOffset;
957 SDValue NextPtr =
958 DAG.getObjectPtrOffset(DL, Addr, TypeSize::getFixed(NextOffset));
959
960 // Store pointer to arguments given on registers (va_reg)
961 SDValue StoreRegPtr = DAG.getStore(StoreStackPtr, DL, FrameIndex, NextPtr,
962 MachinePointerInfo(SV, NextOffset));
963 NextOffset += FrameOffset;
964 NextPtr = DAG.getObjectPtrOffset(DL, Addr, TypeSize::getFixed(NextOffset));
965
966 // Store third word : position in bytes of the first VA argument (va_ndx)
967 return DAG.getStore(StoreRegPtr, DL, VAIndex, NextPtr,
968 MachinePointerInfo(SV, NextOffset));
969}
970
971SDValue XtensaTargetLowering::LowerVACOPY(SDValue Op, SelectionDAG &DAG) const {
972 // Size of the va_list_tag structure
973 constexpr unsigned VAListSize = 3 * 4;
974 SDValue Chain = Op.getOperand(0);
975 SDValue DstPtr = Op.getOperand(1);
976 SDValue SrcPtr = Op.getOperand(2);
977 const Value *DstSV = cast<SrcValueSDNode>(Op.getOperand(3))->getValue();
978 const Value *SrcSV = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
979 SDLoc DL(Op);
980
981 return DAG.getMemcpy(Chain, DL, DstPtr, SrcPtr,
982 DAG.getConstant(VAListSize, SDLoc(Op), MVT::i32),
983 Align(4), /*isVolatile*/ false, /*AlwaysInline*/ true,
984 /*CI=*/nullptr, std::nullopt, MachinePointerInfo(DstSV),
985 MachinePointerInfo(SrcSV));
986}
987
988SDValue XtensaTargetLowering::LowerVAARG(SDValue Op, SelectionDAG &DAG) const {
989 SDNode *Node = Op.getNode();
990 EVT VT = Node->getValueType(0);
991 Type *Ty = VT.getTypeForEVT(*DAG.getContext());
992 EVT PtrVT = Op.getValueType();
993 SDValue InChain = Node->getOperand(0);
994 SDValue VAListPtr = Node->getOperand(1);
995 const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
996 SDLoc DL(Node);
997 auto &TD = DAG.getDataLayout();
998 Align ArgAlignment = TD.getABITypeAlign(Ty);
999 unsigned ArgAlignInBytes = ArgAlignment.value();
1000 unsigned ArgSizeInBytes = TD.getTypeAllocSize(Ty);
1001 unsigned VASizeInBytes = llvm::alignTo(ArgSizeInBytes, 4);
1002
1003 // va_stk
1004 SDValue VAStack =
1005 DAG.getLoad(MVT::i32, DL, InChain, VAListPtr, MachinePointerInfo());
1006 InChain = VAStack.getValue(1);
1007
1008 // va_reg
1009 SDValue VARegPtr =
1010 DAG.getObjectPtrOffset(DL, VAListPtr, TypeSize::getFixed(4));
1011 SDValue VAReg =
1012 DAG.getLoad(MVT::i32, DL, InChain, VARegPtr, MachinePointerInfo());
1013 InChain = VAReg.getValue(1);
1014
1015 // va_ndx
1016 SDValue VarArgIndexPtr =
1017 DAG.getObjectPtrOffset(DL, VARegPtr, TypeSize::getFixed(4));
1018 SDValue VAIndex =
1019 DAG.getLoad(MVT::i32, DL, InChain, VarArgIndexPtr, MachinePointerInfo());
1020 InChain = VAIndex.getValue(1);
1021
1022 SDValue OrigIndex = VAIndex;
1023
1024 if (ArgAlignInBytes > 4) {
1025 OrigIndex = DAG.getNode(ISD::ADD, DL, PtrVT, OrigIndex,
1026 DAG.getConstant(ArgAlignInBytes - 1, DL, MVT::i32));
1027 OrigIndex =
1028 DAG.getNode(ISD::AND, DL, PtrVT, OrigIndex,
1029 DAG.getSignedConstant(-ArgAlignInBytes, DL, MVT::i32));
1030 }
1031
1032 VAIndex = DAG.getNode(ISD::ADD, DL, PtrVT, OrigIndex,
1033 DAG.getConstant(VASizeInBytes, DL, MVT::i32));
1034
1035 SDValue CC = DAG.getSetCC(DL, MVT::i32, OrigIndex,
1036 DAG.getConstant(6 * 4, DL, MVT::i32), ISD::SETLE);
1037
1038 SDValue StkIndex =
1039 DAG.getNode(ISD::ADD, DL, PtrVT, VAIndex,
1040 DAG.getConstant(32 + VASizeInBytes, DL, MVT::i32));
1041
1042 CC = DAG.getSetCC(DL, MVT::i32, VAIndex, DAG.getConstant(6 * 4, DL, MVT::i32),
1043 ISD::SETLE);
1044
1045 SDValue Array = DAG.getNode(ISD::SELECT, DL, MVT::i32, CC, VAReg, VAStack);
1046
1047 VAIndex = DAG.getNode(ISD::SELECT, DL, MVT::i32, CC, VAIndex, StkIndex);
1048
1049 CC = DAG.getSetCC(DL, MVT::i32, VAIndex, DAG.getConstant(6 * 4, DL, MVT::i32),
1050 ISD::SETLE);
1051
1052 SDValue VAIndexStore = DAG.getStore(InChain, DL, VAIndex, VarArgIndexPtr,
1053 MachinePointerInfo(SV));
1054 InChain = VAIndexStore;
1055
1056 SDValue Addr = DAG.getNode(ISD::SUB, DL, PtrVT, VAIndex,
1057 DAG.getConstant(VASizeInBytes, DL, MVT::i32));
1058
1059 Addr = DAG.getNode(ISD::ADD, DL, PtrVT, Array, Addr);
1060
1061 return DAG.getLoad(VT, DL, InChain, Addr, MachinePointerInfo());
1062}
1063
1064SDValue XtensaTargetLowering::LowerShiftLeftParts(SDValue Op,
1065 SelectionDAG &DAG) const {
1066 SDLoc DL(Op);
1067 MVT VT = MVT::i32;
1068 SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1);
1069 SDValue Shamt = Op.getOperand(2);
1070
1071 // if Shamt - register size < 0: // Shamt < register size
1072 // Lo = Lo << Shamt
1073 // Hi = (Hi << Shamt) | (Lo >>u (register size - Shamt))
1074 // else:
1075 // Lo = 0
1076 // Hi = Lo << (Shamt - register size)
1077
1078 SDValue MinusRegisterSize = DAG.getSignedConstant(-32, DL, VT);
1079 SDValue ShamtMinusRegisterSize =
1080 DAG.getNode(ISD::ADD, DL, VT, Shamt, MinusRegisterSize);
1081
1082 SDValue LoTrue = DAG.getNode(ISD::SHL, DL, VT, Lo, Shamt);
1083 SDValue HiTrue = DAG.getNode(XtensaISD::SRCL, DL, VT, Hi, Lo, Shamt);
1084 SDValue Zero = DAG.getConstant(0, DL, VT);
1085 SDValue HiFalse = DAG.getNode(ISD::SHL, DL, VT, Lo, ShamtMinusRegisterSize);
1086
1087 SDValue Cond = DAG.getSetCC(DL, VT, ShamtMinusRegisterSize, Zero, ISD::SETLT);
1088 Lo = DAG.getNode(ISD::SELECT, DL, VT, Cond, LoTrue, Zero);
1089 Hi = DAG.getNode(ISD::SELECT, DL, VT, Cond, HiTrue, HiFalse);
1090
1091 return DAG.getMergeValues({Lo, Hi}, DL);
1092}
1093
1094SDValue XtensaTargetLowering::LowerShiftRightParts(SDValue Op,
1095 SelectionDAG &DAG,
1096 bool IsSRA) const {
1097 SDLoc DL(Op);
1098 SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1);
1099 SDValue Shamt = Op.getOperand(2);
1100 MVT VT = MVT::i32;
1101
1102 // SRA expansion:
1103 // if Shamt - register size < 0: // Shamt < register size
1104 // Lo = (Lo >>u Shamt) | (Hi << u (register size - Shamt))
1105 // Hi = Hi >>s Shamt
1106 // else:
1107 // Lo = Hi >>s (Shamt - register size);
1108 // Hi = Hi >>s (register size - 1)
1109 //
1110 // SRL expansion:
1111 // if Shamt - register size < 0: // Shamt < register size
1112 // Lo = (Lo >>u Shamt) | (Hi << u (register size - Shamt))
1113 // Hi = Hi >>u Shamt
1114 // else:
1115 // Lo = Hi >>u (Shamt - register size);
1116 // Hi = 0;
1117
1118 unsigned ShiftRightOp = IsSRA ? ISD::SRA : ISD::SRL;
1119 SDValue MinusRegisterSize = DAG.getSignedConstant(-32, DL, VT);
1120 SDValue RegisterSizeMinus1 = DAG.getConstant(32 - 1, DL, VT);
1121 SDValue ShamtMinusRegisterSize =
1122 DAG.getNode(ISD::ADD, DL, VT, Shamt, MinusRegisterSize);
1123
1124 SDValue LoTrue = DAG.getNode(XtensaISD::SRCR, DL, VT, Hi, Lo, Shamt);
1125 SDValue HiTrue = DAG.getNode(ShiftRightOp, DL, VT, Hi, Shamt);
1126 SDValue Zero = DAG.getConstant(0, DL, VT);
1127 SDValue LoFalse =
1128 DAG.getNode(ShiftRightOp, DL, VT, Hi, ShamtMinusRegisterSize);
1129 SDValue HiFalse;
1130
1131 if (IsSRA) {
1132 HiFalse = DAG.getNode(ShiftRightOp, DL, VT, Hi, RegisterSizeMinus1);
1133 } else {
1134 HiFalse = Zero;
1135 }
1136
1137 SDValue Cond = DAG.getSetCC(DL, VT, ShamtMinusRegisterSize, Zero, ISD::SETLT);
1138 Lo = DAG.getNode(ISD::SELECT, DL, VT, Cond, LoTrue, LoFalse);
1139 Hi = DAG.getNode(ISD::SELECT, DL, VT, Cond, HiTrue, HiFalse);
1140
1141 return DAG.getMergeValues({Lo, Hi}, DL);
1142}
1143
1144SDValue XtensaTargetLowering::LowerCTPOP(SDValue Op, SelectionDAG &DAG) const {
1145 auto &TLI = DAG.getTargetLoweringInfo();
1146 return TLI.expandCTPOP(Op.getNode(), DAG);
1147}
1148
1150 SDValue C) const {
1151 APInt Imm;
1152 unsigned EltSizeInBits;
1153
1154 if (ISD::isConstantSplatVector(C.getNode(), Imm)) {
1155 EltSizeInBits = VT.getScalarSizeInBits();
1156 } else if (VT.isScalarInteger()) {
1157 EltSizeInBits = VT.getSizeInBits();
1158 if (auto *ConstNode = dyn_cast<ConstantSDNode>(C.getNode()))
1159 Imm = ConstNode->getAPIntValue();
1160 else
1161 return false;
1162 } else {
1163 return false;
1164 }
1165
1166 // Omit if data size exceeds.
1167 if (EltSizeInBits > 32)
1168 return false;
1169
1170 // Convert MULT to LSL.
1171 if (Imm.isPowerOf2() && Imm.isIntN(5))
1172 return true;
1173
1174 return false;
1175}
1176
1178 SelectionDAG &DAG) const {
1179 switch (Op.getOpcode()) {
1180 case ISD::BR_JT:
1181 return LowerBR_JT(Op, DAG);
1182 case ISD::Constant:
1183 return LowerImmediate(Op, DAG);
1184 case ISD::RETURNADDR:
1185 return LowerRETURNADDR(Op, DAG);
1186 case ISD::GlobalAddress:
1187 return LowerGlobalAddress(Op, DAG);
1188 case ISD::BlockAddress:
1189 return LowerBlockAddress(Op, DAG);
1190 case ISD::JumpTable:
1191 return LowerJumpTable(Op, DAG);
1192 case ISD::CTPOP:
1193 return LowerCTPOP(Op, DAG);
1194 case ISD::ConstantPool:
1195 return LowerConstantPool(Op, DAG);
1196 case ISD::SELECT_CC:
1197 return LowerSELECT_CC(Op, DAG);
1198 case ISD::STACKSAVE:
1199 return LowerSTACKSAVE(Op, DAG);
1200 case ISD::STACKRESTORE:
1201 return LowerSTACKRESTORE(Op, DAG);
1202 case ISD::FRAMEADDR:
1203 return LowerFRAMEADDR(Op, DAG);
1205 return LowerDYNAMIC_STACKALLOC(Op, DAG);
1206 case ISD::VASTART:
1207 return LowerVASTART(Op, DAG);
1208 case ISD::VAARG:
1209 return LowerVAARG(Op, DAG);
1210 case ISD::VACOPY:
1211 return LowerVACOPY(Op, DAG);
1212 case ISD::SHL_PARTS:
1213 return LowerShiftLeftParts(Op, DAG);
1214 case ISD::SRA_PARTS:
1215 return LowerShiftRightParts(Op, DAG, true);
1216 case ISD::SRL_PARTS:
1217 return LowerShiftRightParts(Op, DAG, false);
1218 default:
1219 report_fatal_error("Unexpected node to lower");
1220 }
1221}
1222
1223const char *XtensaTargetLowering::getTargetNodeName(unsigned Opcode) const {
1224 switch (Opcode) {
1225 case XtensaISD::BR_JT:
1226 return "XtensaISD::BR_JT";
1227 case XtensaISD::CALL:
1228 return "XtensaISD::CALL";
1229 case XtensaISD::EXTUI:
1230 return "XtensaISD::EXTUI";
1232 return "XtensaISD::PCREL_WRAPPER";
1233 case XtensaISD::RET:
1234 return "XtensaISD::RET";
1236 return "XtensaISD::SELECT_CC";
1237 case XtensaISD::SRCL:
1238 return "XtensaISD::SRCL";
1239 case XtensaISD::SRCR:
1240 return "XtensaISD::SRCR";
1241 }
1242 return nullptr;
1243}
1244
1245//===----------------------------------------------------------------------===//
1246// Custom insertion
1247//===----------------------------------------------------------------------===//
1248
1250XtensaTargetLowering::emitSelectCC(MachineInstr &MI,
1251 MachineBasicBlock *MBB) const {
1252 const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
1253 DebugLoc DL = MI.getDebugLoc();
1254
1255 MachineOperand &LHS = MI.getOperand(1);
1256 MachineOperand &RHS = MI.getOperand(2);
1257 MachineOperand &TrueValue = MI.getOperand(3);
1258 MachineOperand &FalseValue = MI.getOperand(4);
1259 unsigned BrKind = MI.getOperand(5).getImm();
1260
1261 // To "insert" a SELECT_CC instruction, we actually have to insert
1262 // CopyMBB and SinkMBB blocks and add branch to MBB. We build phi
1263 // operation in SinkMBB like phi (TrueVakue,FalseValue), where TrueValue
1264 // is passed from MMB and FalseValue is passed from CopyMBB.
1265 // MBB
1266 // | \
1267 // | CopyMBB
1268 // | /
1269 // SinkMBB
1270 // The incoming instruction knows the
1271 // destination vreg to set, the condition code register to branch on, the
1272 // true/false values to select between, and a branch opcode to use.
1273 const BasicBlock *LLVM_BB = MBB->getBasicBlock();
1275
1277 MachineBasicBlock *CopyMBB = F->CreateMachineBasicBlock(LLVM_BB);
1278 MachineBasicBlock *SinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
1279
1280 F->insert(It, CopyMBB);
1281 F->insert(It, SinkMBB);
1282
1283 // Transfer the remainder of MBB and its successor edges to SinkMBB.
1284 SinkMBB->splice(SinkMBB->begin(), MBB,
1285 std::next(MachineBasicBlock::iterator(MI)), MBB->end());
1287
1288 MBB->addSuccessor(CopyMBB);
1289 MBB->addSuccessor(SinkMBB);
1290
1291 BuildMI(MBB, DL, TII.get(BrKind))
1292 .addReg(LHS.getReg())
1293 .addReg(RHS.getReg())
1294 .addMBB(SinkMBB);
1295
1296 CopyMBB->addSuccessor(SinkMBB);
1297
1298 // SinkMBB:
1299 // %Result = phi [ %FalseValue, CopyMBB ], [ %TrueValue, MBB ]
1300 // ...
1301
1302 BuildMI(*SinkMBB, SinkMBB->begin(), DL, TII.get(Xtensa::PHI),
1303 MI.getOperand(0).getReg())
1304 .addReg(FalseValue.getReg())
1305 .addMBB(CopyMBB)
1306 .addReg(TrueValue.getReg())
1307 .addMBB(MBB);
1308
1309 MI.eraseFromParent(); // The pseudo instruction is gone now.
1310 return SinkMBB;
1311}
1312
1315 DebugLoc DL = MI.getDebugLoc();
1316 const XtensaInstrInfo &TII = *Subtarget.getInstrInfo();
1317
1318 switch (MI.getOpcode()) {
1319 case Xtensa::SELECT:
1320 return emitSelectCC(MI, MBB);
1321 case Xtensa::S8I:
1322 case Xtensa::S16I:
1323 case Xtensa::S32I:
1324 case Xtensa::S32I_N:
1325 case Xtensa::L8UI:
1326 case Xtensa::L16SI:
1327 case Xtensa::L16UI:
1328 case Xtensa::L32I:
1329 case Xtensa::L32I_N: {
1330 // Insert memory wait instruction "memw" before volatile load/store as it is
1331 // implemented in gcc. If memoperands is empty then assume that it aslo
1332 // maybe volatile load/store and insert "memw".
1333 if (MI.memoperands_empty() || (*MI.memoperands_begin())->isVolatile()) {
1334 BuildMI(*MBB, MI, DL, TII.get(Xtensa::MEMW));
1335 }
1336 return MBB;
1337 }
1338 default:
1339 llvm_unreachable("Unexpected instr type to insert");
1340 }
1341}
unsigned RegSize
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
return RetTy
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
uint64_t Addr
uint64_t Size
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#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
unsigned const TargetRegisterInfo * TRI
static constexpr Register SPReg
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SI optimize exec mask operations pre RA
static const char * name
Definition: SMEABIPass.cpp:46
static const MCPhysReg IntRegs[32]
Value * RHS
Value * LHS
static bool CC_Xtensa_Custom(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
static bool isLongCall(const char *str)
static unsigned getBranchOpcode(ISD::CondCode Cond)
Class for arbitrary precision integers.
Definition: APInt.h:78
int64_t getSExtValue() const
Get sign extended value.
Definition: APInt.h:1542
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
The address of a basic block.
Definition: Constants.h:893
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,...
void AnalyzeCallResult(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeCallResult - Analyze the return values of a call, incorporating info about the passed values i...
MCRegister AllocateReg(MCPhysReg Reg)
AllocateReg - Attempt to allocate one register.
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 ...
void AnalyzeReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeReturn - Analyze the returned values of a return, incorporating info about the result values i...
int64_t AllocateStack(unsigned Size, Align Alignment)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
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.
void AnalyzeFormalArguments(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeFormalArguments - Analyze an array of argument values, incorporating info about the formals in...
void addLoc(const CCValAssign &V)
CCValAssign - Represent assignment of one arg/retval to a location.
bool isRegLoc() const
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)
bool isMemLoc() const
int64_t getLocMemOffset() const
unsigned getValNo() const
const APInt & getAPIntValue() const
This is an important base class in LLVM.
Definition: Constant.h:42
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:63
Align getABITypeAlign(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
Definition: DataLayout.cpp:843
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
Definition: DataLayout.h:457
A debug info location.
Definition: DebugLoc.h:33
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
Machine Value Type.
static auto integer_valuetypes()
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
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 '...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
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.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
const MachineJumpTableInfo * getJumpTableInfo() const
getJumpTableInfo - Return the jump table info object for the current function.
const MachineInstrBuilder & addReg(Register RegNo, 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.
Definition: MachineInstr.h:69
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,...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
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...
Represents one node in the SelectionDAG.
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...
Definition: SelectionDAG.h:228
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
Definition: SelectionDAG.h:801
SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
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(), AAResults *AA=nullptr)
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...
SDValue getRegister(Register Reg, EVT VT)
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,...
const TargetLowering & getTargetLoweringInfo() const
Definition: SelectionDAG.h:503
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
Definition: SelectionDAG.h:760
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)
Definition: SelectionDAG.h:827
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:497
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
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.
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 ...
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
SDValue getValueType(EVT)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:492
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
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
Definition: SelectionDAG.h:510
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)
Definition: SelectionDAG.h:767
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:580
bool empty() const
Definition: SmallVector.h:81
size_t size() const
Definition: SmallVector.h:78
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:229
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:150
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.
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.
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 setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
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.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
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.
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.
Definition: TargetMachine.h:77
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition: TypeSize.h:345
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
static IntegerType * getInt32Ty(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:237
LLVM Value Representation.
Definition: Value.h:74
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:309
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.
Register getFrameRegister(const MachineFunction &MF) const override
const XtensaInstrInfo * getInstrInfo() const override
const XtensaRegisterInfo * getRegisterInfo() const override
const TargetFrameLowering * getFrameLowering() 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.
XtensaTargetLowering(const TargetMachine &TM, const XtensaSubtarget &STI)
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,...
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...
self_iterator getIterator()
Definition: ilist_node.h:132
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ 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:780
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
Definition: ISDOpcodes.h:1197
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition: ISDOpcodes.h:1193
@ CTLZ_ZERO_UNDEF
Definition: ISDOpcodes.h:753
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition: ISDOpcodes.h:257
@ BSWAP
Byte Swap and Counting operators.
Definition: ISDOpcodes.h:744
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
Definition: ISDOpcodes.h:1226
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:246
@ GlobalAddress
Definition: ISDOpcodes.h:78
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
Definition: ISDOpcodes.h:841
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition: ISDOpcodes.h:262
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
Definition: ISDOpcodes.h:954
@ FrameIndex
Definition: ISDOpcodes.h:80
@ CTTZ_ZERO_UNDEF
Bit counting operators with an undefined result for zero inputs.
Definition: ISDOpcodes.h:752
@ BR_CC
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:1148
@ BR_JT
BR_JT - Jumptable branch.
Definition: ISDOpcodes.h:1127
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition: ISDOpcodes.h:757
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
Definition: ISDOpcodes.h:1222
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition: ISDOpcodes.h:674
@ SHL
Shift and rotation operations.
Definition: ISDOpcodes.h:735
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition: ISDOpcodes.h:772
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
Definition: ISDOpcodes.h:1112
@ ConstantPool
Definition: ISDOpcodes.h:82
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition: ISDOpcodes.h:849
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition: ISDOpcodes.h:100
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition: ISDOpcodes.h:887
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:709
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition: ISDOpcodes.h:52
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition: ISDOpcodes.h:817
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
Definition: ISDOpcodes.h:1217
@ BlockAddress
Definition: ISDOpcodes.h:84
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
Definition: ISDOpcodes.h:794
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition: ISDOpcodes.h:61
@ AssertZext
Definition: ISDOpcodes.h:62
bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
Definition: ISDOpcodes.h:1610
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
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
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
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
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:390
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition: ValueTypes.h:368
uint64_t getScalarSizeInBits() const
Definition: ValueTypes.h:380
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
Definition: ValueTypes.cpp:210
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 MachinePointerInfo getJumpTable(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a jump table entry.
static 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
SmallVector< SDValue, 32 > OutVals