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) const {
626 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
627 return CCInfo.CheckReturn(Outs, RetCC_Xtensa);
628}
629
632 bool IsVarArg,
634 const SmallVectorImpl<SDValue> &OutVals,
635 const SDLoc &DL, SelectionDAG &DAG) const {
637
638 // Assign locations to each returned value.
640 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, *DAG.getContext());
641 RetCCInfo.AnalyzeReturn(Outs, RetCC_Xtensa);
642
643 SDValue Glue;
644 // Quick exit for void returns
645 if (RetLocs.empty())
646 return DAG.getNode(XtensaISD::RET, DL, MVT::Other, Chain);
647
648 // Copy the result values into the output registers.
650 RetOps.push_back(Chain);
651 for (unsigned I = 0, E = RetLocs.size(); I != E; ++I) {
652 CCValAssign &VA = RetLocs[I];
653 SDValue RetValue = OutVals[I];
654
655 // Make the return register live on exit.
656 assert(VA.isRegLoc() && "Can only return in registers!");
657
658 // Chain and glue the copies together.
659 unsigned Register = VA.getLocReg();
660 Chain = DAG.getCopyToReg(Chain, DL, Register, RetValue, Glue);
661 Glue = Chain.getValue(1);
662 RetOps.push_back(DAG.getRegister(Register, VA.getLocVT()));
663 }
664
665 // Update chain and glue.
666 RetOps[0] = Chain;
667 if (Glue.getNode())
668 RetOps.push_back(Glue);
669
670 return DAG.getNode(XtensaISD::RET, DL, MVT::Other, RetOps);
671}
672
674 switch (Cond) {
675 case ISD::SETEQ:
676 return Xtensa::BEQ;
677 case ISD::SETNE:
678 return Xtensa::BNE;
679 case ISD::SETLT:
680 return Xtensa::BLT;
681 case ISD::SETLE:
682 return Xtensa::BGE;
683 case ISD::SETGT:
684 return Xtensa::BLT;
685 case ISD::SETGE:
686 return Xtensa::BGE;
687 case ISD::SETULT:
688 return Xtensa::BLTU;
689 case ISD::SETULE:
690 return Xtensa::BGEU;
691 case ISD::SETUGT:
692 return Xtensa::BLTU;
693 case ISD::SETUGE:
694 return Xtensa::BGEU;
695 default:
696 llvm_unreachable("Unknown branch kind");
697 }
698}
699
700SDValue XtensaTargetLowering::LowerSELECT_CC(SDValue Op,
701 SelectionDAG &DAG) const {
702 SDLoc DL(Op);
703 EVT Ty = Op.getOperand(0).getValueType();
704 SDValue LHS = Op.getOperand(0);
705 SDValue RHS = Op.getOperand(1);
706 SDValue TrueValue = Op.getOperand(2);
707 SDValue FalseValue = Op.getOperand(3);
708 ISD::CondCode CC = cast<CondCodeSDNode>(Op->getOperand(4))->get();
709
710 unsigned BrOpcode = getBranchOpcode(CC);
711 SDValue TargetCC = DAG.getConstant(BrOpcode, DL, MVT::i32);
712
713 return DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, LHS, RHS, TrueValue,
714 FalseValue, TargetCC);
715}
716
717SDValue XtensaTargetLowering::LowerRETURNADDR(SDValue Op,
718 SelectionDAG &DAG) const {
719 // This nodes represent llvm.returnaddress on the DAG.
720 // It takes one operand, the index of the return address to return.
721 // An index of zero corresponds to the current function's return address.
722 // An index of one to the parent's return address, and so on.
723 // Depths > 0 not supported yet!
724 if (Op.getConstantOperandVal(0) != 0)
725 return SDValue();
726
728 MachineFrameInfo &MFI = MF.getFrameInfo();
729 EVT VT = Op.getValueType();
730 MFI.setReturnAddressIsTaken(true);
731
732 // Return RA, which contains the return address. Mark it an implicit
733 // live-in.
734 Register RA = MF.addLiveIn(Xtensa::A0, getRegClassFor(MVT::i32));
735 return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), RA, VT);
736}
737
738SDValue XtensaTargetLowering::LowerImmediate(SDValue Op,
739 SelectionDAG &DAG) const {
740 const ConstantSDNode *CN = cast<ConstantSDNode>(Op);
741 SDLoc DL(CN);
742 APInt APVal = CN->getAPIntValue();
743 int64_t Value = APVal.getSExtValue();
744 if (Op.getValueType() == MVT::i32) {
745 // Check if use node maybe lowered to the MOVI instruction
746 if (Value > -2048 && Value <= 2047)
747 return Op;
748 // Check if use node maybe lowered to the ADDMI instruction
749 SDNode &OpNode = *Op.getNode();
750 if ((OpNode.hasOneUse() && OpNode.user_begin()->getOpcode() == ISD::ADD) &&
751 isShiftedInt<16, 8>(Value))
752 return Op;
753 Type *Ty = Type::getInt32Ty(*DAG.getContext());
754 Constant *CV = ConstantInt::get(Ty, Value);
755 SDValue CP = DAG.getConstantPool(CV, MVT::i32);
756 return CP;
757 }
758 return Op;
759}
760
761SDValue XtensaTargetLowering::LowerGlobalAddress(SDValue Op,
762 SelectionDAG &DAG) const {
763 const GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(Op);
764 SDLoc DL(Op);
765 auto PtrVT = Op.getValueType();
766 const GlobalValue *GV = G->getGlobal();
767
768 SDValue CPAddr = DAG.getTargetConstantPool(GV, PtrVT, Align(4));
769 SDValue CPWrap = getAddrPCRel(CPAddr, DAG);
770
771 return CPWrap;
772}
773
774SDValue XtensaTargetLowering::LowerBlockAddress(SDValue Op,
775 SelectionDAG &DAG) const {
776 BlockAddressSDNode *Node = cast<BlockAddressSDNode>(Op);
777 const BlockAddress *BA = Node->getBlockAddress();
778 EVT PtrVT = Op.getValueType();
779
782 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
783 SDValue CPWrap = getAddrPCRel(CPAddr, DAG);
784
785 return CPWrap;
786}
787
788SDValue XtensaTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) const {
789 SDValue Chain = Op.getOperand(0);
790 SDValue Table = Op.getOperand(1);
791 SDValue Index = Op.getOperand(2);
792 SDLoc DL(Op);
793 JumpTableSDNode *JT = cast<JumpTableSDNode>(Table);
795 const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
796 SDValue TargetJT = DAG.getTargetJumpTable(JT->getIndex(), MVT::i32);
797 const DataLayout &TD = DAG.getDataLayout();
798 EVT PtrVT = Table.getValueType();
799 unsigned EntrySize = MJTI->getEntrySize(TD);
800
801 assert((MJTI->getEntrySize(TD) == 4) && "Unsupported jump-table entry size");
802
803 Index = DAG.getNode(
804 ISD::SHL, DL, Index.getValueType(), Index,
805 DAG.getConstant(Log2_32(EntrySize), DL, Index.getValueType()));
806
807 SDValue Addr = DAG.getNode(ISD::ADD, DL, Index.getValueType(), Index, Table);
808 SDValue LD =
809 DAG.getLoad(PtrVT, DL, Chain, Addr,
811
812 return DAG.getNode(XtensaISD::BR_JT, DL, MVT::Other, LD.getValue(1), LD,
813 TargetJT);
814}
815
816SDValue XtensaTargetLowering::LowerJumpTable(SDValue Op,
817 SelectionDAG &DAG) const {
818 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
819 EVT PtrVT = Op.getValueType();
820
821 // Create a constant pool entry for the callee address
824
825 // Get the address of the callee into a register
826 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
827
828 return getAddrPCRel(CPAddr, DAG);
829}
830
831SDValue XtensaTargetLowering::getAddrPCRel(SDValue Op,
832 SelectionDAG &DAG) const {
833 SDLoc DL(Op);
834 EVT Ty = Op.getValueType();
835 return DAG.getNode(XtensaISD::PCREL_WRAPPER, DL, Ty, Op);
836}
837
838SDValue XtensaTargetLowering::LowerConstantPool(SDValue Op,
839 SelectionDAG &DAG) const {
840 EVT PtrVT = Op.getValueType();
841 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
843
844 if (!CP->isMachineConstantPoolEntry()) {
845 Result = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, CP->getAlign(),
846 CP->getOffset());
847 } else {
848 report_fatal_error("This constantpool type is not supported yet");
849 }
850
851 return getAddrPCRel(Result, DAG);
852}
853
854SDValue XtensaTargetLowering::LowerSTACKSAVE(SDValue Op,
855 SelectionDAG &DAG) const {
856 return DAG.getCopyFromReg(Op.getOperand(0), SDLoc(Op), Xtensa::SP,
857 Op.getValueType());
858}
859
860SDValue XtensaTargetLowering::LowerSTACKRESTORE(SDValue Op,
861 SelectionDAG &DAG) const {
862 return DAG.getCopyToReg(Op.getOperand(0), SDLoc(Op), Xtensa::SP,
863 Op.getOperand(1));
864}
865
866SDValue XtensaTargetLowering::LowerFRAMEADDR(SDValue Op,
867 SelectionDAG &DAG) const {
868 // This nodes represent llvm.frameaddress on the DAG.
869 // It takes one operand, the index of the frame address to return.
870 // An index of zero corresponds to the current function's frame address.
871 // An index of one to the parent's frame address, and so on.
872 // Depths > 0 not supported yet!
873 if (Op.getConstantOperandVal(0) != 0)
874 return SDValue();
875
877 MachineFrameInfo &MFI = MF.getFrameInfo();
878 MFI.setFrameAddressIsTaken(true);
879 EVT VT = Op.getValueType();
880 SDLoc DL(Op);
881
882 Register FrameRegister = Subtarget.getRegisterInfo()->getFrameRegister(MF);
883 SDValue FrameAddr =
884 DAG.getCopyFromReg(DAG.getEntryNode(), DL, FrameRegister, VT);
885 return FrameAddr;
886}
887
888SDValue XtensaTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
889 SelectionDAG &DAG) const {
890 SDValue Chain = Op.getOperand(0); // Legalize the chain.
891 SDValue Size = Op.getOperand(1); // Legalize the size.
892 EVT VT = Size->getValueType(0);
893 SDLoc DL(Op);
894
895 // Round up Size to 32
896 SDValue SizeTmp =
897 DAG.getNode(ISD::ADD, DL, VT, Size, DAG.getConstant(31, DL, MVT::i32));
898 SDValue SizeRoundUp = DAG.getNode(ISD::AND, DL, VT, SizeTmp,
899 DAG.getSignedConstant(~31, DL, MVT::i32));
900
901 unsigned SPReg = Xtensa::SP;
902 SDValue SP = DAG.getCopyFromReg(Chain, DL, SPReg, VT);
903 SDValue NewSP = DAG.getNode(ISD::SUB, DL, VT, SP, SizeRoundUp); // Value
904 Chain = DAG.getCopyToReg(SP.getValue(1), DL, SPReg, NewSP); // Output chain
905
906 SDValue NewVal = DAG.getCopyFromReg(Chain, DL, SPReg, MVT::i32);
907 Chain = NewVal.getValue(1);
908
909 SDValue Ops[2] = {NewVal, Chain};
910 return DAG.getMergeValues(Ops, DL);
911}
912
913SDValue XtensaTargetLowering::LowerVASTART(SDValue Op,
914 SelectionDAG &DAG) const {
917 SDValue Chain = Op.getOperand(0);
918 SDValue Addr = Op.getOperand(1);
919 EVT PtrVT = Addr.getValueType();
920 SDLoc DL(Op);
921
922 // Struct va_list_tag
923 // int32 *va_stk - points to the arguments passed in memory
924 // int32 *va_reg - points to the registers with arguments saved in memory
925 // int32 va_ndx - offset from va_stk or va_reg pointers which points to the
926 // next variable argument
927
928 SDValue VAIndex;
929 SDValue StackOffsetFI =
930 DAG.getFrameIndex(XtensaFI->getVarArgsOnStackFrameIndex(), PtrVT);
931 unsigned ArgWords = XtensaFI->getVarArgsFirstGPR() - 2;
932
933 // If first variable argument passed in registers (maximum words in registers
934 // is 6) then set va_ndx to the position of this argument in registers area
935 // stored in memory (va_reg pointer). Otherwise va_ndx should point to the
936 // position of the first variable argument on stack (va_stk pointer).
937 if (ArgWords < 6) {
938 VAIndex = DAG.getConstant(ArgWords * 4, DL, MVT::i32);
939 } else {
940 VAIndex = DAG.getConstant(32, DL, MVT::i32);
941 }
942
944 DAG.getFrameIndex(XtensaFI->getVarArgsInRegsFrameIndex(), PtrVT);
945 uint64_t FrameOffset = PtrVT.getStoreSize();
946 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
947
948 // Store pointer to arguments given on stack (va_stk)
949 SDValue StackPtr = DAG.getNode(ISD::SUB, DL, PtrVT, StackOffsetFI,
950 DAG.getConstant(32, DL, PtrVT));
951
952 SDValue StoreStackPtr =
953 DAG.getStore(Chain, DL, StackPtr, Addr, MachinePointerInfo(SV));
954
955 uint64_t NextOffset = FrameOffset;
956 SDValue NextPtr =
957 DAG.getObjectPtrOffset(DL, Addr, TypeSize::getFixed(NextOffset));
958
959 // Store pointer to arguments given on registers (va_reg)
960 SDValue StoreRegPtr = DAG.getStore(StoreStackPtr, DL, FrameIndex, NextPtr,
961 MachinePointerInfo(SV, NextOffset));
962 NextOffset += FrameOffset;
963 NextPtr = DAG.getObjectPtrOffset(DL, Addr, TypeSize::getFixed(NextOffset));
964
965 // Store third word : position in bytes of the first VA argument (va_ndx)
966 return DAG.getStore(StoreRegPtr, DL, VAIndex, NextPtr,
967 MachinePointerInfo(SV, NextOffset));
968}
969
970SDValue XtensaTargetLowering::LowerVACOPY(SDValue Op, SelectionDAG &DAG) const {
971 // Size of the va_list_tag structure
972 constexpr unsigned VAListSize = 3 * 4;
973 SDValue Chain = Op.getOperand(0);
974 SDValue DstPtr = Op.getOperand(1);
975 SDValue SrcPtr = Op.getOperand(2);
976 const Value *DstSV = cast<SrcValueSDNode>(Op.getOperand(3))->getValue();
977 const Value *SrcSV = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
978 SDLoc DL(Op);
979
980 return DAG.getMemcpy(Chain, DL, DstPtr, SrcPtr,
981 DAG.getConstant(VAListSize, SDLoc(Op), MVT::i32),
982 Align(4), /*isVolatile*/ false, /*AlwaysInline*/ true,
983 /*CI=*/nullptr, std::nullopt, MachinePointerInfo(DstSV),
984 MachinePointerInfo(SrcSV));
985}
986
987SDValue XtensaTargetLowering::LowerVAARG(SDValue Op, SelectionDAG &DAG) const {
988 SDNode *Node = Op.getNode();
989 EVT VT = Node->getValueType(0);
990 Type *Ty = VT.getTypeForEVT(*DAG.getContext());
991 EVT PtrVT = Op.getValueType();
992 SDValue InChain = Node->getOperand(0);
993 SDValue VAListPtr = Node->getOperand(1);
994 const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();
995 SDLoc DL(Node);
996 auto &TD = DAG.getDataLayout();
997 Align ArgAlignment = TD.getABITypeAlign(Ty);
998 unsigned ArgAlignInBytes = ArgAlignment.value();
999 unsigned ArgSizeInBytes = TD.getTypeAllocSize(Ty);
1000 unsigned VASizeInBytes = llvm::alignTo(ArgSizeInBytes, 4);
1001
1002 // va_stk
1003 SDValue VAStack =
1004 DAG.getLoad(MVT::i32, DL, InChain, VAListPtr, MachinePointerInfo());
1005 InChain = VAStack.getValue(1);
1006
1007 // va_reg
1008 SDValue VARegPtr =
1009 DAG.getObjectPtrOffset(DL, VAListPtr, TypeSize::getFixed(4));
1010 SDValue VAReg =
1011 DAG.getLoad(MVT::i32, DL, InChain, VARegPtr, MachinePointerInfo());
1012 InChain = VAReg.getValue(1);
1013
1014 // va_ndx
1015 SDValue VarArgIndexPtr =
1016 DAG.getObjectPtrOffset(DL, VARegPtr, TypeSize::getFixed(4));
1017 SDValue VAIndex =
1018 DAG.getLoad(MVT::i32, DL, InChain, VarArgIndexPtr, MachinePointerInfo());
1019 InChain = VAIndex.getValue(1);
1020
1021 SDValue OrigIndex = VAIndex;
1022
1023 if (ArgAlignInBytes > 4) {
1024 OrigIndex = DAG.getNode(ISD::ADD, DL, PtrVT, OrigIndex,
1025 DAG.getConstant(ArgAlignInBytes - 1, DL, MVT::i32));
1026 OrigIndex =
1027 DAG.getNode(ISD::AND, DL, PtrVT, OrigIndex,
1028 DAG.getSignedConstant(-ArgAlignInBytes, DL, MVT::i32));
1029 }
1030
1031 VAIndex = DAG.getNode(ISD::ADD, DL, PtrVT, OrigIndex,
1032 DAG.getConstant(VASizeInBytes, DL, MVT::i32));
1033
1034 SDValue CC = DAG.getSetCC(DL, MVT::i32, OrigIndex,
1035 DAG.getConstant(6 * 4, DL, MVT::i32), ISD::SETLE);
1036
1037 SDValue StkIndex =
1038 DAG.getNode(ISD::ADD, DL, PtrVT, VAIndex,
1039 DAG.getConstant(32 + VASizeInBytes, DL, MVT::i32));
1040
1041 CC = DAG.getSetCC(DL, MVT::i32, VAIndex, DAG.getConstant(6 * 4, DL, MVT::i32),
1042 ISD::SETLE);
1043
1044 SDValue Array = DAG.getNode(ISD::SELECT, DL, MVT::i32, CC, VAReg, VAStack);
1045
1046 VAIndex = DAG.getNode(ISD::SELECT, DL, MVT::i32, CC, VAIndex, StkIndex);
1047
1048 CC = DAG.getSetCC(DL, MVT::i32, VAIndex, DAG.getConstant(6 * 4, DL, MVT::i32),
1049 ISD::SETLE);
1050
1051 SDValue VAIndexStore = DAG.getStore(InChain, DL, VAIndex, VarArgIndexPtr,
1052 MachinePointerInfo(SV));
1053 InChain = VAIndexStore;
1054
1055 SDValue Addr = DAG.getNode(ISD::SUB, DL, PtrVT, VAIndex,
1056 DAG.getConstant(VASizeInBytes, DL, MVT::i32));
1057
1058 Addr = DAG.getNode(ISD::ADD, DL, PtrVT, Array, Addr);
1059
1060 return DAG.getLoad(VT, DL, InChain, Addr, MachinePointerInfo());
1061}
1062
1063SDValue XtensaTargetLowering::LowerShiftLeftParts(SDValue Op,
1064 SelectionDAG &DAG) const {
1065 SDLoc DL(Op);
1066 MVT VT = MVT::i32;
1067 SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1);
1068 SDValue Shamt = Op.getOperand(2);
1069
1070 // if Shamt - register size < 0: // Shamt < register size
1071 // Lo = Lo << Shamt
1072 // Hi = (Hi << Shamt) | (Lo >>u (register size - Shamt))
1073 // else:
1074 // Lo = 0
1075 // Hi = Lo << (Shamt - register size)
1076
1077 SDValue MinusRegisterSize = DAG.getSignedConstant(-32, DL, VT);
1078 SDValue ShamtMinusRegisterSize =
1079 DAG.getNode(ISD::ADD, DL, VT, Shamt, MinusRegisterSize);
1080
1081 SDValue LoTrue = DAG.getNode(ISD::SHL, DL, VT, Lo, Shamt);
1082 SDValue HiTrue = DAG.getNode(XtensaISD::SRCL, DL, VT, Hi, Lo, Shamt);
1083 SDValue Zero = DAG.getConstant(0, DL, VT);
1084 SDValue HiFalse = DAG.getNode(ISD::SHL, DL, VT, Lo, ShamtMinusRegisterSize);
1085
1086 SDValue Cond = DAG.getSetCC(DL, VT, ShamtMinusRegisterSize, Zero, ISD::SETLT);
1087 Lo = DAG.getNode(ISD::SELECT, DL, VT, Cond, LoTrue, Zero);
1088 Hi = DAG.getNode(ISD::SELECT, DL, VT, Cond, HiTrue, HiFalse);
1089
1090 return DAG.getMergeValues({Lo, Hi}, DL);
1091}
1092
1093SDValue XtensaTargetLowering::LowerShiftRightParts(SDValue Op,
1094 SelectionDAG &DAG,
1095 bool IsSRA) const {
1096 SDLoc DL(Op);
1097 SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1);
1098 SDValue Shamt = Op.getOperand(2);
1099 MVT VT = MVT::i32;
1100
1101 // SRA expansion:
1102 // if Shamt - register size < 0: // Shamt < register size
1103 // Lo = (Lo >>u Shamt) | (Hi << u (register size - Shamt))
1104 // Hi = Hi >>s Shamt
1105 // else:
1106 // Lo = Hi >>s (Shamt - register size);
1107 // Hi = Hi >>s (register size - 1)
1108 //
1109 // SRL expansion:
1110 // if Shamt - register size < 0: // Shamt < register size
1111 // Lo = (Lo >>u Shamt) | (Hi << u (register size - Shamt))
1112 // Hi = Hi >>u Shamt
1113 // else:
1114 // Lo = Hi >>u (Shamt - register size);
1115 // Hi = 0;
1116
1117 unsigned ShiftRightOp = IsSRA ? ISD::SRA : ISD::SRL;
1118 SDValue MinusRegisterSize = DAG.getSignedConstant(-32, DL, VT);
1119 SDValue RegisterSizeMinus1 = DAG.getConstant(32 - 1, DL, VT);
1120 SDValue ShamtMinusRegisterSize =
1121 DAG.getNode(ISD::ADD, DL, VT, Shamt, MinusRegisterSize);
1122
1123 SDValue LoTrue = DAG.getNode(XtensaISD::SRCR, DL, VT, Hi, Lo, Shamt);
1124 SDValue HiTrue = DAG.getNode(ShiftRightOp, DL, VT, Hi, Shamt);
1125 SDValue Zero = DAG.getConstant(0, DL, VT);
1126 SDValue LoFalse =
1127 DAG.getNode(ShiftRightOp, DL, VT, Hi, ShamtMinusRegisterSize);
1128 SDValue HiFalse;
1129
1130 if (IsSRA) {
1131 HiFalse = DAG.getNode(ShiftRightOp, DL, VT, Hi, RegisterSizeMinus1);
1132 } else {
1133 HiFalse = Zero;
1134 }
1135
1136 SDValue Cond = DAG.getSetCC(DL, VT, ShamtMinusRegisterSize, Zero, ISD::SETLT);
1137 Lo = DAG.getNode(ISD::SELECT, DL, VT, Cond, LoTrue, LoFalse);
1138 Hi = DAG.getNode(ISD::SELECT, DL, VT, Cond, HiTrue, HiFalse);
1139
1140 return DAG.getMergeValues({Lo, Hi}, DL);
1141}
1142
1143SDValue XtensaTargetLowering::LowerCTPOP(SDValue Op, SelectionDAG &DAG) const {
1144 auto &TLI = DAG.getTargetLoweringInfo();
1145 return TLI.expandCTPOP(Op.getNode(), DAG);
1146}
1147
1149 SDValue C) const {
1150 APInt Imm;
1151 unsigned EltSizeInBits;
1152
1153 if (ISD::isConstantSplatVector(C.getNode(), Imm)) {
1154 EltSizeInBits = VT.getScalarSizeInBits();
1155 } else if (VT.isScalarInteger()) {
1156 EltSizeInBits = VT.getSizeInBits();
1157 if (auto *ConstNode = dyn_cast<ConstantSDNode>(C.getNode()))
1158 Imm = ConstNode->getAPIntValue();
1159 else
1160 return false;
1161 } else {
1162 return false;
1163 }
1164
1165 // Omit if data size exceeds.
1166 if (EltSizeInBits > 32)
1167 return false;
1168
1169 // Convert MULT to LSL.
1170 if (Imm.isPowerOf2() && Imm.isIntN(5))
1171 return true;
1172
1173 return false;
1174}
1175
1177 SelectionDAG &DAG) const {
1178 switch (Op.getOpcode()) {
1179 case ISD::BR_JT:
1180 return LowerBR_JT(Op, DAG);
1181 case ISD::Constant:
1182 return LowerImmediate(Op, DAG);
1183 case ISD::RETURNADDR:
1184 return LowerRETURNADDR(Op, DAG);
1185 case ISD::GlobalAddress:
1186 return LowerGlobalAddress(Op, DAG);
1187 case ISD::BlockAddress:
1188 return LowerBlockAddress(Op, DAG);
1189 case ISD::JumpTable:
1190 return LowerJumpTable(Op, DAG);
1191 case ISD::CTPOP:
1192 return LowerCTPOP(Op, DAG);
1193 case ISD::ConstantPool:
1194 return LowerConstantPool(Op, DAG);
1195 case ISD::SELECT_CC:
1196 return LowerSELECT_CC(Op, DAG);
1197 case ISD::STACKSAVE:
1198 return LowerSTACKSAVE(Op, DAG);
1199 case ISD::STACKRESTORE:
1200 return LowerSTACKRESTORE(Op, DAG);
1201 case ISD::FRAMEADDR:
1202 return LowerFRAMEADDR(Op, DAG);
1204 return LowerDYNAMIC_STACKALLOC(Op, DAG);
1205 case ISD::VASTART:
1206 return LowerVASTART(Op, DAG);
1207 case ISD::VAARG:
1208 return LowerVAARG(Op, DAG);
1209 case ISD::VACOPY:
1210 return LowerVACOPY(Op, DAG);
1211 case ISD::SHL_PARTS:
1212 return LowerShiftLeftParts(Op, DAG);
1213 case ISD::SRA_PARTS:
1214 return LowerShiftRightParts(Op, DAG, true);
1215 case ISD::SRL_PARTS:
1216 return LowerShiftRightParts(Op, DAG, false);
1217 default:
1218 report_fatal_error("Unexpected node to lower");
1219 }
1220}
1221
1222const char *XtensaTargetLowering::getTargetNodeName(unsigned Opcode) const {
1223 switch (Opcode) {
1224 case XtensaISD::BR_JT:
1225 return "XtensaISD::BR_JT";
1226 case XtensaISD::CALL:
1227 return "XtensaISD::CALL";
1228 case XtensaISD::EXTUI:
1229 return "XtensaISD::EXTUI";
1231 return "XtensaISD::PCREL_WRAPPER";
1232 case XtensaISD::RET:
1233 return "XtensaISD::RET";
1235 return "XtensaISD::SELECT_CC";
1236 case XtensaISD::SRCL:
1237 return "XtensaISD::SRCL";
1238 case XtensaISD::SRCR:
1239 return "XtensaISD::SRCR";
1240 }
1241 return nullptr;
1242}
1243
1244//===----------------------------------------------------------------------===//
1245// Custom insertion
1246//===----------------------------------------------------------------------===//
1247
1249XtensaTargetLowering::emitSelectCC(MachineInstr &MI,
1250 MachineBasicBlock *MBB) const {
1251 const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
1252 DebugLoc DL = MI.getDebugLoc();
1253
1254 MachineOperand &LHS = MI.getOperand(1);
1255 MachineOperand &RHS = MI.getOperand(2);
1256 MachineOperand &TrueValue = MI.getOperand(3);
1257 MachineOperand &FalseValue = MI.getOperand(4);
1258 unsigned BrKind = MI.getOperand(5).getImm();
1259
1260 // To "insert" a SELECT_CC instruction, we actually have to insert
1261 // CopyMBB and SinkMBB blocks and add branch to MBB. We build phi
1262 // operation in SinkMBB like phi (TrueVakue,FalseValue), where TrueValue
1263 // is passed from MMB and FalseValue is passed from CopyMBB.
1264 // MBB
1265 // | \
1266 // | CopyMBB
1267 // | /
1268 // SinkMBB
1269 // The incoming instruction knows the
1270 // destination vreg to set, the condition code register to branch on, the
1271 // true/false values to select between, and a branch opcode to use.
1272 const BasicBlock *LLVM_BB = MBB->getBasicBlock();
1274
1276 MachineBasicBlock *CopyMBB = F->CreateMachineBasicBlock(LLVM_BB);
1277 MachineBasicBlock *SinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
1278
1279 F->insert(It, CopyMBB);
1280 F->insert(It, SinkMBB);
1281
1282 // Transfer the remainder of MBB and its successor edges to SinkMBB.
1283 SinkMBB->splice(SinkMBB->begin(), MBB,
1284 std::next(MachineBasicBlock::iterator(MI)), MBB->end());
1286
1287 MBB->addSuccessor(CopyMBB);
1288 MBB->addSuccessor(SinkMBB);
1289
1290 BuildMI(MBB, DL, TII.get(BrKind))
1291 .addReg(LHS.getReg())
1292 .addReg(RHS.getReg())
1293 .addMBB(SinkMBB);
1294
1295 CopyMBB->addSuccessor(SinkMBB);
1296
1297 // SinkMBB:
1298 // %Result = phi [ %FalseValue, CopyMBB ], [ %TrueValue, MBB ]
1299 // ...
1300
1301 BuildMI(*SinkMBB, SinkMBB->begin(), DL, TII.get(Xtensa::PHI),
1302 MI.getOperand(0).getReg())
1303 .addReg(FalseValue.getReg())
1304 .addMBB(CopyMBB)
1305 .addReg(TrueValue.getReg())
1306 .addMBB(MBB);
1307
1308 MI.eraseFromParent(); // The pseudo instruction is gone now.
1309 return SinkMBB;
1310}
1311
1314 DebugLoc DL = MI.getDebugLoc();
1315 const XtensaInstrInfo &TII = *Subtarget.getInstrInfo();
1316
1317 switch (MI.getOpcode()) {
1318 case Xtensa::SELECT:
1319 return emitSelectCC(MI, MBB);
1320 case Xtensa::S8I:
1321 case Xtensa::S16I:
1322 case Xtensa::S32I:
1323 case Xtensa::S32I_N:
1324 case Xtensa::L8UI:
1325 case Xtensa::L16SI:
1326 case Xtensa::L16UI:
1327 case Xtensa::L32I:
1328 case Xtensa::L32I_N: {
1329 // Insert memory wait instruction "memw" before volatile load/store as it is
1330 // implemented in gcc. If memoperands is empty then assume that it aslo
1331 // maybe volatile load/store and insert "memw".
1332 if (MI.memoperands_empty() || (*MI.memoperands_begin())->isVolatile()) {
1333 BuildMI(*MBB, MI, DL, TII.get(Xtensa::MEMW));
1334 }
1335 return MBB;
1336 }
1337 default:
1338 llvm_unreachable("Unexpected instr type to insert");
1339 }
1340}
unsigned RegSize
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
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:799
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:501
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
Definition: SelectionDAG.h:758
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:825
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:495
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:490
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:508
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:765
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:578
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
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,...
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, LLVMContext &Context) const override
This hook should be implemented to check whether the return values described by the Outs array can fi...
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:1613
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:340
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