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 "XtensaSubtarget.h"
17#include "XtensaTargetMachine.h"
25#include "llvm/Support/Debug.h"
29#include <deque>
30
31using namespace llvm;
32
33#define DEBUG_TYPE "xtensa-lower"
34
35// Return true if we must use long (in fact, indirect) function call.
36// It's simplified version, production implimentation must
37// resolve a functions in ROM (usually glibc functions)
38static bool isLongCall(const char *str) {
39 // Currently always use long calls
40 return true;
41}
42
44 const XtensaSubtarget &STI)
45 : TargetLowering(TM), Subtarget(STI) {
46 MVT PtrVT = MVT::i32;
47 // Set up the register classes.
48 addRegisterClass(MVT::i32, &Xtensa::ARRegClass);
49
50 // Set up special registers.
52
54
56
59
61
65
72
73 // No sign extend instructions for i1
74 for (MVT VT : MVT::integer_valuetypes()) {
78 }
79
84
85 // Expand jump table branches as address arithmetic followed by an
86 // indirect jump.
88
92
96
101
107
114
118
127
128 // Implement custom stack allocations
130 // Implement custom stack save and restore
133
134 // Compute derived properties from the register classes
136}
137
139 const GlobalAddressSDNode *GA) const {
140 // The Xtensa target isn't yet aware of offsets.
141 return false;
142}
143
144//===----------------------------------------------------------------------===//
145// Calling conventions
146//===----------------------------------------------------------------------===//
147
148#include "XtensaGenCallingConv.inc"
149
150static bool CC_Xtensa_Custom(unsigned ValNo, MVT ValVT, MVT LocVT,
151 CCValAssign::LocInfo LocInfo,
152 ISD::ArgFlagsTy ArgFlags, CCState &State) {
153 static const MCPhysReg IntRegs[] = {Xtensa::A2, Xtensa::A3, Xtensa::A4,
154 Xtensa::A5, Xtensa::A6, Xtensa::A7};
155
156 if (ArgFlags.isByVal()) {
157 Align ByValAlign = ArgFlags.getNonZeroByValAlign();
158 unsigned ByValSize = ArgFlags.getByValSize();
159 if (ByValSize < 4) {
160 ByValSize = 4;
161 }
162 if (ByValAlign < Align(4)) {
163 ByValAlign = Align(4);
164 }
165 unsigned Offset = State.AllocateStack(ByValSize, ByValAlign);
166 State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
167 // Mark all unused registers as allocated to avoid misuse
168 // of such registers.
169 while (State.AllocateReg(IntRegs))
170 ;
171 return false;
172 }
173
174 // Promote i8 and i16
175 if (LocVT == MVT::i8 || LocVT == MVT::i16) {
176 LocVT = MVT::i32;
177 if (ArgFlags.isSExt())
178 LocInfo = CCValAssign::SExt;
179 else if (ArgFlags.isZExt())
180 LocInfo = CCValAssign::ZExt;
181 else
182 LocInfo = CCValAssign::AExt;
183 }
184
185 unsigned Register;
186
187 Align OrigAlign = ArgFlags.getNonZeroOrigAlign();
188 bool needs64BitAlign = (ValVT == MVT::i32 && OrigAlign == Align(8));
189 bool needs128BitAlign = (ValVT == MVT::i32 && OrigAlign == Align(16));
190
191 if (ValVT == MVT::i32) {
193 // If this is the first part of an i64 arg,
194 // the allocated register must be either A2, A4 or A6.
195 if (needs64BitAlign && (Register == Xtensa::A3 || Register == Xtensa::A5 ||
196 Register == Xtensa::A7))
198 // arguments with 16byte alignment must be passed in the first register or
199 // passed via stack
200 if (needs128BitAlign && (Register != Xtensa::A2))
201 while ((Register = State.AllocateReg(IntRegs)))
202 ;
203 LocVT = MVT::i32;
204 } else if (ValVT == MVT::f64) {
205 // Allocate int register and shadow next int register.
207 if (Register == Xtensa::A3 || Register == Xtensa::A5 ||
208 Register == Xtensa::A7)
210 State.AllocateReg(IntRegs);
211 LocVT = MVT::i32;
212 } else {
213 report_fatal_error("Cannot handle this ValVT.");
214 }
215
216 if (!Register) {
217 unsigned Offset = State.AllocateStack(ValVT.getStoreSize(), OrigAlign);
218 State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
219 } else {
220 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Register, LocVT, LocInfo));
221 }
222
223 return false;
224}
225
226CCAssignFn *XtensaTargetLowering::CCAssignFnForCall(CallingConv::ID CC,
227 bool IsVarArg) const {
228 return CC_Xtensa_Custom;
229}
230
232 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
233 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
234 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
236 MachineFrameInfo &MFI = MF.getFrameInfo();
237
238 // Used with vargs to acumulate store chains.
239 std::vector<SDValue> OutChains;
240
241 if (IsVarArg)
242 report_fatal_error("Var arg not supported by FormalArguments Lowering");
243
244 // Assign locations to all of the incoming arguments.
246 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
247 *DAG.getContext());
248
249 CCInfo.AnalyzeFormalArguments(Ins, CCAssignFnForCall(CallConv, IsVarArg));
250
251 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
252 CCValAssign &VA = ArgLocs[i];
253 // Arguments stored on registers
254 if (VA.isRegLoc()) {
255 EVT RegVT = VA.getLocVT();
256 const TargetRegisterClass *RC;
257
258 if (RegVT == MVT::i32)
259 RC = &Xtensa::ARRegClass;
260 else
261 report_fatal_error("RegVT not supported by FormalArguments Lowering");
262
263 // Transform the arguments stored on
264 // physical registers into virtual ones
265 unsigned Register = MF.addLiveIn(VA.getLocReg(), RC);
266 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Register, RegVT);
267
268 // If this is an 8 or 16-bit value, it has been passed promoted
269 // to 32 bits. Insert an assert[sz]ext to capture this, then
270 // truncate to the right size.
271 if (VA.getLocInfo() != CCValAssign::Full) {
272 unsigned Opcode = 0;
273 if (VA.getLocInfo() == CCValAssign::SExt)
274 Opcode = ISD::AssertSext;
275 else if (VA.getLocInfo() == CCValAssign::ZExt)
276 Opcode = ISD::AssertZext;
277 if (Opcode)
278 ArgValue = DAG.getNode(Opcode, DL, RegVT, ArgValue,
279 DAG.getValueType(VA.getValVT()));
280 ArgValue = DAG.getNode((VA.getValVT() == MVT::f32) ? ISD::BITCAST
282 DL, VA.getValVT(), ArgValue);
283 }
284
285 InVals.push_back(ArgValue);
286
287 } else {
288 assert(VA.isMemLoc());
289
290 EVT ValVT = VA.getValVT();
291
292 // The stack pointer offset is relative to the caller stack frame.
293 int FI = MFI.CreateFixedObject(ValVT.getStoreSize(), VA.getLocMemOffset(),
294 true);
295
296 if (Ins[VA.getValNo()].Flags.isByVal()) {
297 // Assume that in this case load operation is created
298 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
299 InVals.push_back(FIN);
300 } else {
301 // Create load nodes to retrieve arguments from the stack
302 SDValue FIN =
304 InVals.push_back(DAG.getLoad(
305 ValVT, DL, Chain, FIN,
307 }
308 }
309 }
310
311 // All stores are grouped in one node to allow the matching between
312 // the size of Ins and InVals. This only happens when on varg functions
313 if (!OutChains.empty()) {
314 OutChains.push_back(Chain);
315 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);
316 }
317
318 return Chain;
319}
320
323 SmallVectorImpl<SDValue> &InVals) const {
324 SelectionDAG &DAG = CLI.DAG;
325 SDLoc &DL = CLI.DL;
327 SmallVector<SDValue, 32> &OutVals = CLI.OutVals;
329 SDValue Chain = CLI.Chain;
330 SDValue Callee = CLI.Callee;
331 bool &IsTailCall = CLI.IsTailCall;
332 CallingConv::ID CallConv = CLI.CallConv;
333 bool IsVarArg = CLI.IsVarArg;
334
336 EVT PtrVT = getPointerTy(DAG.getDataLayout());
337 const TargetFrameLowering *TFL = Subtarget.getFrameLowering();
338
339 // TODO: Support tail call optimization.
340 IsTailCall = false;
341
342 // Analyze the operands of the call, assigning locations to each operand.
344 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
345
346 CCAssignFn *CC = CCAssignFnForCall(CallConv, IsVarArg);
347
348 CCInfo.AnalyzeCallOperands(Outs, CC);
349
350 // Get a count of how many bytes are to be pushed on the stack.
351 unsigned NumBytes = CCInfo.getStackSize();
352
353 Align StackAlignment = TFL->getStackAlign();
354 unsigned NextStackOffset = alignTo(NumBytes, StackAlignment);
355
356 Chain = DAG.getCALLSEQ_START(Chain, NextStackOffset, 0, DL);
357
358 // Copy argument values to their designated locations.
359 std::deque<std::pair<unsigned, SDValue>> RegsToPass;
360 SmallVector<SDValue, 8> MemOpChains;
361 SDValue StackPtr;
362 for (unsigned I = 0, E = ArgLocs.size(); I != E; ++I) {
363 CCValAssign &VA = ArgLocs[I];
364 SDValue ArgValue = OutVals[I];
365 ISD::ArgFlagsTy Flags = Outs[I].Flags;
366
367 if (VA.isRegLoc())
368 // Queue up the argument copies and emit them at the end.
369 RegsToPass.push_back(std::make_pair(VA.getLocReg(), ArgValue));
370 else if (Flags.isByVal()) {
371 assert(VA.isMemLoc());
372 assert(Flags.getByValSize() &&
373 "ByVal args of size 0 should have been ignored by front-end.");
374 assert(!IsTailCall &&
375 "Do not tail-call optimize if there is a byval argument.");
376
377 if (!StackPtr.getNode())
378 StackPtr = DAG.getCopyFromReg(Chain, DL, Xtensa::SP, PtrVT);
379 unsigned Offset = VA.getLocMemOffset();
380 SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,
382 SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), DL, MVT::i32);
383 SDValue Memcpy = DAG.getMemcpy(
384 Chain, DL, Address, ArgValue, SizeNode, Flags.getNonZeroByValAlign(),
385 /*isVolatile=*/false, /*AlwaysInline=*/false,
386 /*CI=*/nullptr, std::nullopt, MachinePointerInfo(), MachinePointerInfo());
387 MemOpChains.push_back(Memcpy);
388 } else {
389 assert(VA.isMemLoc() && "Argument not register or memory");
390
391 // Work out the address of the stack slot. Unpromoted ints and
392 // floats are passed as right-justified 8-byte values.
393 if (!StackPtr.getNode())
394 StackPtr = DAG.getCopyFromReg(Chain, DL, Xtensa::SP, PtrVT);
395 unsigned Offset = VA.getLocMemOffset();
396 SDValue Address = DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,
398
399 // Emit the store.
400 MemOpChains.push_back(
401 DAG.getStore(Chain, DL, ArgValue, Address, MachinePointerInfo()));
402 }
403 }
404
405 // Join the stores, which are independent of one another.
406 if (!MemOpChains.empty())
407 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains);
408
409 // Build a sequence of copy-to-reg nodes, chained and glued together.
410 SDValue Glue;
411 for (unsigned I = 0, E = RegsToPass.size(); I != E; ++I) {
412 unsigned Reg = RegsToPass[I].first;
413 Chain = DAG.getCopyToReg(Chain, DL, Reg, RegsToPass[I].second, Glue);
414 Glue = Chain.getValue(1);
415 }
416 std::string name;
417 unsigned char TF = 0;
418
419 // Accept direct calls by converting symbolic call addresses to the
420 // associated Target* opcodes.
421 if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
422 name = E->getSymbol();
423 TF = E->getTargetFlags();
424 if (isPositionIndependent()) {
425 report_fatal_error("PIC relocations is not supported");
426 } else
427 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), PtrVT, TF);
428 } else if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
429 const GlobalValue *GV = G->getGlobal();
430 name = GV->getName().str();
431 }
432
433 if ((!name.empty()) && isLongCall(name.c_str())) {
434 // Create a constant pool entry for the callee address
436
438 *DAG.getContext(), name.c_str(), 0 /* XtensaCLabelIndex */, false,
439 Modifier);
440
441 // Get the address of the callee into a register
442 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4), 0, TF);
443 SDValue CPWrap = getAddrPCRel(CPAddr, DAG);
444 Callee = CPWrap;
445 }
446
447 // The first call operand is the chain and the second is the target address.
449 Ops.push_back(Chain);
450 Ops.push_back(Callee);
451
452 // Add a register mask operand representing the call-preserved registers.
453 const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
454 const uint32_t *Mask = TRI->getCallPreservedMask(MF, CallConv);
455 assert(Mask && "Missing call preserved mask for calling convention");
456 Ops.push_back(DAG.getRegisterMask(Mask));
457
458 // Add argument registers to the end of the list so that they are
459 // known live into the call.
460 for (unsigned I = 0, E = RegsToPass.size(); I != E; ++I) {
461 unsigned Reg = RegsToPass[I].first;
462 Ops.push_back(DAG.getRegister(Reg, RegsToPass[I].second.getValueType()));
463 }
464
465 // Glue the call to the argument copies, if any.
466 if (Glue.getNode())
467 Ops.push_back(Glue);
468
469 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
470 Chain = DAG.getNode(XtensaISD::CALL, DL, NodeTys, Ops);
471 Glue = Chain.getValue(1);
472
473 // Mark the end of the call, which is glued to the call itself.
474 Chain = DAG.getCALLSEQ_END(Chain, DAG.getConstant(NumBytes, DL, PtrVT, true),
475 DAG.getConstant(0, DL, PtrVT, true), Glue, DL);
476 Glue = Chain.getValue(1);
477
478 // Assign locations to each value returned by this call.
480 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, *DAG.getContext());
481 RetCCInfo.AnalyzeCallResult(Ins, RetCC_Xtensa);
482
483 // Copy all of the result registers out of their specified physreg.
484 for (unsigned I = 0, E = RetLocs.size(); I != E; ++I) {
485 CCValAssign &VA = RetLocs[I];
486
487 // Copy the value out, gluing the copy to the end of the call sequence.
488 unsigned Reg = VA.getLocReg();
489 SDValue RetValue = DAG.getCopyFromReg(Chain, DL, Reg, VA.getLocVT(), Glue);
490 Chain = RetValue.getValue(1);
491 Glue = RetValue.getValue(2);
492
493 InVals.push_back(RetValue);
494 }
495 return Chain;
496}
497
499 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
500 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const {
502 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
503 return CCInfo.CheckReturn(Outs, RetCC_Xtensa);
504}
505
508 bool IsVarArg,
510 const SmallVectorImpl<SDValue> &OutVals,
511 const SDLoc &DL, SelectionDAG &DAG) const {
512 if (IsVarArg)
513 report_fatal_error("VarArg not supported");
514
516
517 // Assign locations to each returned value.
519 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, *DAG.getContext());
520 RetCCInfo.AnalyzeReturn(Outs, RetCC_Xtensa);
521
522 SDValue Glue;
523 // Quick exit for void returns
524 if (RetLocs.empty())
525 return DAG.getNode(XtensaISD::RET, DL, MVT::Other, Chain);
526
527 // Copy the result values into the output registers.
529 RetOps.push_back(Chain);
530 for (unsigned I = 0, E = RetLocs.size(); I != E; ++I) {
531 CCValAssign &VA = RetLocs[I];
532 SDValue RetValue = OutVals[I];
533
534 // Make the return register live on exit.
535 assert(VA.isRegLoc() && "Can only return in registers!");
536
537 // Chain and glue the copies together.
538 unsigned Register = VA.getLocReg();
539 Chain = DAG.getCopyToReg(Chain, DL, Register, RetValue, Glue);
540 Glue = Chain.getValue(1);
541 RetOps.push_back(DAG.getRegister(Register, VA.getLocVT()));
542 }
543
544 // Update chain and glue.
545 RetOps[0] = Chain;
546 if (Glue.getNode())
547 RetOps.push_back(Glue);
548
549 return DAG.getNode(XtensaISD::RET, DL, MVT::Other, RetOps);
550}
551
553 switch (Cond) {
554 case ISD::SETEQ:
555 return Xtensa::BEQ;
556 case ISD::SETNE:
557 return Xtensa::BNE;
558 case ISD::SETLT:
559 return Xtensa::BLT;
560 case ISD::SETLE:
561 return Xtensa::BGE;
562 case ISD::SETGT:
563 return Xtensa::BLT;
564 case ISD::SETGE:
565 return Xtensa::BGE;
566 case ISD::SETULT:
567 return Xtensa::BLTU;
568 case ISD::SETULE:
569 return Xtensa::BGEU;
570 case ISD::SETUGT:
571 return Xtensa::BLTU;
572 case ISD::SETUGE:
573 return Xtensa::BGEU;
574 default:
575 llvm_unreachable("Unknown branch kind");
576 }
577}
578
579SDValue XtensaTargetLowering::LowerSELECT_CC(SDValue Op,
580 SelectionDAG &DAG) const {
581 SDLoc DL(Op);
582 EVT Ty = Op.getOperand(0).getValueType();
583 SDValue LHS = Op.getOperand(0);
584 SDValue RHS = Op.getOperand(1);
585 SDValue TrueValue = Op.getOperand(2);
586 SDValue FalseValue = Op.getOperand(3);
587 ISD::CondCode CC = cast<CondCodeSDNode>(Op->getOperand(4))->get();
588
589 unsigned BrOpcode = getBranchOpcode(CC);
590 SDValue TargetCC = DAG.getConstant(BrOpcode, DL, MVT::i32);
591
592 return DAG.getNode(XtensaISD::SELECT_CC, DL, Ty, LHS, RHS, TrueValue,
593 FalseValue, TargetCC);
594}
595
596SDValue XtensaTargetLowering::LowerImmediate(SDValue Op,
597 SelectionDAG &DAG) const {
598 const ConstantSDNode *CN = cast<ConstantSDNode>(Op);
599 SDLoc DL(CN);
600 APInt APVal = CN->getAPIntValue();
601 int64_t Value = APVal.getSExtValue();
602 if (Op.getValueType() == MVT::i32) {
603 // Check if use node maybe lowered to the MOVI instruction
604 if (Value > -2048 && Value <= 2047)
605 return Op;
606 // Check if use node maybe lowered to the ADDMI instruction
607 SDNode &OpNode = *Op.getNode();
608 if ((OpNode.hasOneUse() && OpNode.use_begin()->getOpcode() == ISD::ADD) &&
609 isShiftedInt<16, 8>(Value))
610 return Op;
611 Type *Ty = Type::getInt32Ty(*DAG.getContext());
612 Constant *CV = ConstantInt::get(Ty, Value);
613 SDValue CP = DAG.getConstantPool(CV, MVT::i32);
614 return CP;
615 }
616 return Op;
617}
618
619SDValue XtensaTargetLowering::LowerGlobalAddress(SDValue Op,
620 SelectionDAG &DAG) const {
621 const GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(Op);
622 SDLoc DL(Op);
623 auto PtrVT = Op.getValueType();
624 const GlobalValue *GV = G->getGlobal();
625
626 SDValue CPAddr = DAG.getTargetConstantPool(GV, PtrVT, Align(4));
627 SDValue CPWrap = getAddrPCRel(CPAddr, DAG);
628
629 return CPWrap;
630}
631
632SDValue XtensaTargetLowering::LowerBlockAddress(SDValue Op,
633 SelectionDAG &DAG) const {
634 BlockAddressSDNode *Node = cast<BlockAddressSDNode>(Op);
635 const BlockAddress *BA = Node->getBlockAddress();
636 EVT PtrVT = Op.getValueType();
637
640 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
641 SDValue CPWrap = getAddrPCRel(CPAddr, DAG);
642
643 return CPWrap;
644}
645
646SDValue XtensaTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) const {
647 SDValue Chain = Op.getOperand(0);
648 SDValue Table = Op.getOperand(1);
649 SDValue Index = Op.getOperand(2);
650 SDLoc DL(Op);
651 JumpTableSDNode *JT = cast<JumpTableSDNode>(Table);
653 const MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
654 SDValue TargetJT = DAG.getTargetJumpTable(JT->getIndex(), MVT::i32);
655 const DataLayout &TD = DAG.getDataLayout();
656 EVT PtrVT = Table.getValueType();
657 unsigned EntrySize = MJTI->getEntrySize(TD);
658
659 assert((MJTI->getEntrySize(TD) == 4) && "Unsupported jump-table entry size");
660
661 Index = DAG.getNode(
662 ISD::SHL, DL, Index.getValueType(), Index,
663 DAG.getConstant(Log2_32(EntrySize), DL, Index.getValueType()));
664
665 SDValue Addr = DAG.getNode(ISD::ADD, DL, Index.getValueType(), Index, Table);
666 SDValue LD =
667 DAG.getLoad(PtrVT, DL, Chain, Addr,
669
670 return DAG.getNode(XtensaISD::BR_JT, DL, MVT::Other, LD.getValue(1), LD,
671 TargetJT);
672}
673
674SDValue XtensaTargetLowering::LowerJumpTable(SDValue Op,
675 SelectionDAG &DAG) const {
676 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
677 EVT PtrVT = Op.getValueType();
678
679 // Create a constant pool entry for the callee address
682
683 // Get the address of the callee into a register
684 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
685
686 return getAddrPCRel(CPAddr, DAG);
687}
688
689SDValue XtensaTargetLowering::getAddrPCRel(SDValue Op,
690 SelectionDAG &DAG) const {
691 SDLoc DL(Op);
692 EVT Ty = Op.getValueType();
693 return DAG.getNode(XtensaISD::PCREL_WRAPPER, DL, Ty, Op);
694}
695
696SDValue XtensaTargetLowering::LowerConstantPool(SDValue Op,
697 SelectionDAG &DAG) const {
698 EVT PtrVT = Op.getValueType();
699 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
701
702 if (!CP->isMachineConstantPoolEntry()) {
703 Result = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, CP->getAlign(),
704 CP->getOffset());
705 } else {
706 report_fatal_error("This constantpool type is not supported yet");
707 }
708
709 return getAddrPCRel(Result, DAG);
710}
711
712SDValue XtensaTargetLowering::LowerSTACKSAVE(SDValue Op,
713 SelectionDAG &DAG) const {
714 return DAG.getCopyFromReg(Op.getOperand(0), SDLoc(Op), Xtensa::SP,
715 Op.getValueType());
716}
717
718SDValue XtensaTargetLowering::LowerSTACKRESTORE(SDValue Op,
719 SelectionDAG &DAG) const {
720 return DAG.getCopyToReg(Op.getOperand(0), SDLoc(Op), Xtensa::SP,
721 Op.getOperand(1));
722}
723
724SDValue XtensaTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
725 SelectionDAG &DAG) const {
726 SDValue Chain = Op.getOperand(0); // Legalize the chain.
727 SDValue Size = Op.getOperand(1); // Legalize the size.
728 EVT VT = Size->getValueType(0);
729 SDLoc DL(Op);
730
731 // Round up Size to 32
732 SDValue SizeTmp =
733 DAG.getNode(ISD::ADD, DL, VT, Size, DAG.getConstant(31, DL, MVT::i32));
734 SDValue SizeRoundUp = DAG.getNode(ISD::AND, DL, VT, SizeTmp,
735 DAG.getConstant(~31, DL, MVT::i32));
736
737 unsigned SPReg = Xtensa::SP;
738 SDValue SP = DAG.getCopyFromReg(Chain, DL, SPReg, VT);
739 SDValue NewSP = DAG.getNode(ISD::SUB, DL, VT, SP, SizeRoundUp); // Value
740 Chain = DAG.getCopyToReg(SP.getValue(1), DL, SPReg, NewSP); // Output chain
741
742 SDValue NewVal = DAG.getCopyFromReg(Chain, DL, SPReg, MVT::i32);
743 Chain = NewVal.getValue(1);
744
745 SDValue Ops[2] = {NewVal, Chain};
746 return DAG.getMergeValues(Ops, DL);
747}
748
749SDValue XtensaTargetLowering::LowerShiftLeftParts(SDValue Op,
750 SelectionDAG &DAG) const {
751 SDLoc DL(Op);
752 MVT VT = MVT::i32;
753 SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1);
754 SDValue Shamt = Op.getOperand(2);
755
756 // if Shamt - register size < 0: // Shamt < register size
757 // Lo = Lo << Shamt
758 // Hi = (Hi << Shamt) | (Lo >>u (register size - Shamt))
759 // else:
760 // Lo = 0
761 // Hi = Lo << (Shamt - register size)
762
763 SDValue MinusRegisterSize = DAG.getConstant(-32, DL, VT);
764 SDValue ShamtMinusRegisterSize =
765 DAG.getNode(ISD::ADD, DL, VT, Shamt, MinusRegisterSize);
766
767 SDValue LoTrue = DAG.getNode(ISD::SHL, DL, VT, Lo, Shamt);
768 SDValue HiTrue = DAG.getNode(XtensaISD::SRCL, DL, VT, Hi, Lo, Shamt);
769 SDValue Zero = DAG.getConstant(0, DL, VT);
770 SDValue HiFalse = DAG.getNode(ISD::SHL, DL, VT, Lo, ShamtMinusRegisterSize);
771
772 SDValue Cond = DAG.getSetCC(DL, VT, ShamtMinusRegisterSize, Zero, ISD::SETLT);
773 Lo = DAG.getNode(ISD::SELECT, DL, VT, Cond, LoTrue, Zero);
774 Hi = DAG.getNode(ISD::SELECT, DL, VT, Cond, HiTrue, HiFalse);
775
776 return DAG.getMergeValues({Lo, Hi}, DL);
777}
778
779SDValue XtensaTargetLowering::LowerShiftRightParts(SDValue Op,
780 SelectionDAG &DAG,
781 bool IsSRA) const {
782 SDLoc DL(Op);
783 SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1);
784 SDValue Shamt = Op.getOperand(2);
785 MVT VT = MVT::i32;
786
787 // SRA expansion:
788 // if Shamt - register size < 0: // Shamt < register size
789 // Lo = (Lo >>u Shamt) | (Hi << u (register size - Shamt))
790 // Hi = Hi >>s Shamt
791 // else:
792 // Lo = Hi >>s (Shamt - register size);
793 // Hi = Hi >>s (register size - 1)
794 //
795 // SRL expansion:
796 // if Shamt - register size < 0: // Shamt < register size
797 // Lo = (Lo >>u Shamt) | (Hi << u (register size - Shamt))
798 // Hi = Hi >>u Shamt
799 // else:
800 // Lo = Hi >>u (Shamt - register size);
801 // Hi = 0;
802
803 unsigned ShiftRightOp = IsSRA ? ISD::SRA : ISD::SRL;
804 SDValue MinusRegisterSize = DAG.getConstant(-32, DL, VT);
805 SDValue RegisterSizeMinus1 = DAG.getConstant(32 - 1, DL, VT);
806 SDValue ShamtMinusRegisterSize =
807 DAG.getNode(ISD::ADD, DL, VT, Shamt, MinusRegisterSize);
808
809 SDValue LoTrue = DAG.getNode(XtensaISD::SRCR, DL, VT, Hi, Lo, Shamt);
810 SDValue HiTrue = DAG.getNode(ShiftRightOp, DL, VT, Hi, Shamt);
811 SDValue Zero = DAG.getConstant(0, DL, VT);
812 SDValue LoFalse =
813 DAG.getNode(ShiftRightOp, DL, VT, Hi, ShamtMinusRegisterSize);
814 SDValue HiFalse;
815
816 if (IsSRA) {
817 HiFalse = DAG.getNode(ShiftRightOp, DL, VT, Hi, RegisterSizeMinus1);
818 } else {
819 HiFalse = Zero;
820 }
821
822 SDValue Cond = DAG.getSetCC(DL, VT, ShamtMinusRegisterSize, Zero, ISD::SETLT);
823 Lo = DAG.getNode(ISD::SELECT, DL, VT, Cond, LoTrue, LoFalse);
824 Hi = DAG.getNode(ISD::SELECT, DL, VT, Cond, HiTrue, HiFalse);
825
826 return DAG.getMergeValues({Lo, Hi}, DL);
827}
828
829SDValue XtensaTargetLowering::LowerCTPOP(SDValue Op, SelectionDAG &DAG) const {
830 auto &TLI = DAG.getTargetLoweringInfo();
831 return TLI.expandCTPOP(Op.getNode(), DAG);
832}
833
835 SDValue C) const {
836 APInt Imm;
837 unsigned EltSizeInBits;
838
839 if (ISD::isConstantSplatVector(C.getNode(), Imm)) {
840 EltSizeInBits = VT.getScalarSizeInBits();
841 } else if (VT.isScalarInteger()) {
842 EltSizeInBits = VT.getSizeInBits();
843 if (auto *ConstNode = dyn_cast<ConstantSDNode>(C.getNode()))
844 Imm = ConstNode->getAPIntValue();
845 else
846 return false;
847 } else {
848 return false;
849 }
850
851 // Omit if data size exceeds.
852 if (EltSizeInBits > 32)
853 return false;
854
855 // Convert MULT to LSL.
856 if (Imm.isPowerOf2() && Imm.isIntN(5))
857 return true;
858
859 return false;
860}
861
863 SelectionDAG &DAG) const {
864 switch (Op.getOpcode()) {
865 case ISD::BR_JT:
866 return LowerBR_JT(Op, DAG);
867 case ISD::Constant:
868 return LowerImmediate(Op, DAG);
870 return LowerGlobalAddress(Op, DAG);
872 return LowerBlockAddress(Op, DAG);
873 case ISD::JumpTable:
874 return LowerJumpTable(Op, DAG);
875 case ISD::CTPOP:
876 return LowerCTPOP(Op, DAG);
878 return LowerConstantPool(Op, DAG);
879 case ISD::SELECT_CC:
880 return LowerSELECT_CC(Op, DAG);
881 case ISD::STACKSAVE:
882 return LowerSTACKSAVE(Op, DAG);
884 return LowerSTACKRESTORE(Op, DAG);
886 return LowerDYNAMIC_STACKALLOC(Op, DAG);
887 case ISD::SHL_PARTS:
888 return LowerShiftLeftParts(Op, DAG);
889 case ISD::SRA_PARTS:
890 return LowerShiftRightParts(Op, DAG, true);
891 case ISD::SRL_PARTS:
892 return LowerShiftRightParts(Op, DAG, false);
893 default:
894 report_fatal_error("Unexpected node to lower");
895 }
896}
897
898const char *XtensaTargetLowering::getTargetNodeName(unsigned Opcode) const {
899 switch (Opcode) {
900 case XtensaISD::BR_JT:
901 return "XtensaISD::BR_JT";
902 case XtensaISD::CALL:
903 return "XtensaISD::CALL";
904 case XtensaISD::EXTUI:
905 return "XtensaISD::EXTUI";
907 return "XtensaISD::PCREL_WRAPPER";
908 case XtensaISD::RET:
909 return "XtensaISD::RET";
911 return "XtensaISD::SELECT_CC";
912 case XtensaISD::SRCL:
913 return "XtensaISD::SRCL";
914 case XtensaISD::SRCR:
915 return "XtensaISD::SRCR";
916 }
917 return nullptr;
918}
919
920//===----------------------------------------------------------------------===//
921// Custom insertion
922//===----------------------------------------------------------------------===//
923
925XtensaTargetLowering::emitSelectCC(MachineInstr &MI,
926 MachineBasicBlock *MBB) const {
927 const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
928 DebugLoc DL = MI.getDebugLoc();
929
930 MachineOperand &LHS = MI.getOperand(1);
931 MachineOperand &RHS = MI.getOperand(2);
932 MachineOperand &TrueValue = MI.getOperand(3);
933 MachineOperand &FalseValue = MI.getOperand(4);
934 unsigned BrKind = MI.getOperand(5).getImm();
935
936 // To "insert" a SELECT_CC instruction, we actually have to insert
937 // CopyMBB and SinkMBB blocks and add branch to MBB. We build phi
938 // operation in SinkMBB like phi (TrueVakue,FalseValue), where TrueValue
939 // is passed from MMB and FalseValue is passed from CopyMBB.
940 // MBB
941 // | \
942 // | CopyMBB
943 // | /
944 // SinkMBB
945 // The incoming instruction knows the
946 // destination vreg to set, the condition code register to branch on, the
947 // true/false values to select between, and a branch opcode to use.
948 const BasicBlock *LLVM_BB = MBB->getBasicBlock();
950
952 MachineBasicBlock *CopyMBB = F->CreateMachineBasicBlock(LLVM_BB);
953 MachineBasicBlock *SinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
954
955 F->insert(It, CopyMBB);
956 F->insert(It, SinkMBB);
957
958 // Transfer the remainder of MBB and its successor edges to SinkMBB.
959 SinkMBB->splice(SinkMBB->begin(), MBB,
960 std::next(MachineBasicBlock::iterator(MI)), MBB->end());
962
963 MBB->addSuccessor(CopyMBB);
964 MBB->addSuccessor(SinkMBB);
965
966 BuildMI(MBB, DL, TII.get(BrKind))
967 .addReg(LHS.getReg())
968 .addReg(RHS.getReg())
969 .addMBB(SinkMBB);
970
971 CopyMBB->addSuccessor(SinkMBB);
972
973 // SinkMBB:
974 // %Result = phi [ %FalseValue, CopyMBB ], [ %TrueValue, MBB ]
975 // ...
976
977 BuildMI(*SinkMBB, SinkMBB->begin(), DL, TII.get(Xtensa::PHI),
978 MI.getOperand(0).getReg())
979 .addReg(FalseValue.getReg())
980 .addMBB(CopyMBB)
981 .addReg(TrueValue.getReg())
982 .addMBB(MBB);
983
984 MI.eraseFromParent(); // The pseudo instruction is gone now.
985 return SinkMBB;
986}
987
990 DebugLoc DL = MI.getDebugLoc();
991
992 switch (MI.getOpcode()) {
993 case Xtensa::SELECT:
994 return emitSelectCC(MI, MBB);
995 default:
996 llvm_unreachable("Unexpected instr type to insert");
997 }
998}
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const char * name
Definition: SMEABIPass.cpp:50
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:77
int64_t getSExtValue() const
Get sign extended value.
Definition: APInt.h:1519
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
The address of a basic block.
Definition: Constants.h:890
CCState - This class holds information needed while lowering arguments and return values.
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 getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getReg(unsigned ValNo, MVT ValVT, unsigned RegNo, 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
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.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
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.
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.
use_iterator use_begin() const
Provide iteration support to walk over all uses 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:226
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 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:493
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
Definition: SelectionDAG.h:746
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).
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:487
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 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 getRegister(unsigned Reg, EVT VT)
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
Definition: SelectionDAG.h:787
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:482
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
Definition: SelectionDAG.h:813
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
SDValue getRegisterMask(const uint32_t *RegMask)
LLVMContext * getContext() const
Definition: SelectionDAG.h:500
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:753
bool empty() const
Definition: SmallVector.h:94
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:215
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...
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...
SDValue expandCTPOP(SDNode *N, SelectionDAG &DAG) const
Expand CTPOP nodes.
bool isPositionIndependent() const
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...
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)
LLVM Value Representation.
Definition: Value.h:74
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.
const XtensaInstrInfo * getInstrInfo() const override
const XtensaRegisterInfo * getRegisterInfo() const override
const TargetFrameLowering * getFrameLowering() const override
const char * getTargetNodeName(unsigned Opcode) const override
This method returns the name of a target specific DAG node.
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)
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:779
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
Definition: ISDOpcodes.h:1194
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition: ISDOpcodes.h:1190
@ CTLZ_ZERO_UNDEF
Definition: ISDOpcodes.h:752
@ 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:743
@ 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:840
@ 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:953
@ CTTZ_ZERO_UNDEF
Bit counting operators with an undefined result for zero inputs.
Definition: ISDOpcodes.h:751
@ BR_CC
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:1145
@ BR_JT
BR_JT - Jumptable branch.
Definition: ISDOpcodes.h:1124
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition: ISDOpcodes.h:756
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition: ISDOpcodes.h:673
@ SHL
Shift and rotation operations.
Definition: ISDOpcodes.h:734
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition: ISDOpcodes.h:771
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
Definition: ISDOpcodes.h:1109
@ 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:848
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
Definition: ISDOpcodes.h:886
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:708
@ 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:816
@ 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:793
@ 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:1603
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
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:381
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition: ValueTypes.h:359
uint64_t getScalarSizeInBits() const
Definition: ValueTypes.h:371
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 structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals