LLVM 24.0.0git
MSP430ISelLowering.cpp
Go to the documentation of this file.
1//===-- MSP430ISelLowering.cpp - MSP430 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 implements the MSP430TargetLowering class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "MSP430ISelLowering.h"
14#include "MSP430.h"
17#include "MSP430Subtarget.h"
18#include "MSP430TargetMachine.h"
26#include "llvm/IR/CallingConv.h"
28#include "llvm/IR/Function.h"
29#include "llvm/IR/Intrinsics.h"
30#include "llvm/Support/Debug.h"
33using namespace llvm;
34
35#define DEBUG_TYPE "msp430-lower"
36
38 const MSP430Subtarget &STI)
39 : TargetLowering(TM, STI), CLOpts(STI.getCLOpts()) {
40
41 // Set up the register classes.
42 addRegisterClass(MVT::i8, &MSP430::GR8RegClass);
43 addRegisterClass(MVT::i16, &MSP430::GR16RegClass);
44
45 // Compute derived properties from the register classes
47
48 // Provide all sorts of operation actions
51 setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?
52
53 // We have post-incremented loads / stores.
56
57 for (MVT VT : MVT::integer_valuetypes()) {
63 }
64
65 // We don't have any truncstores
66 setTruncStoreAction(MVT::i16, MVT::i8, Expand);
67
96
103
110
112
113 // FIXME: Implement efficiently multiplication by a constant
124
137
138 // varargs support
144
148}
149
151 SelectionDAG &DAG) const {
152 switch (Op.getOpcode()) {
153 case ISD::SHL: // FALLTHROUGH
154 case ISD::SRL:
155 case ISD::SRA: return LowerShifts(Op, DAG);
156 case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
157 case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
158 case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG);
159 case ISD::SETCC: return LowerSETCC(Op, DAG);
160 case ISD::BR_CC: return LowerBR_CC(Op, DAG);
161 case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
162 case ISD::SIGN_EXTEND: return LowerSIGN_EXTEND(Op, DAG);
163 case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
164 case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
165 case ISD::VASTART: return LowerVASTART(Op, DAG);
166 case ISD::JumpTable: return LowerJumpTable(Op, DAG);
167 default:
168 llvm_unreachable("unimplemented operand");
169 }
170}
171
172// Define non profitable transforms into shifts
174 unsigned Amount) const {
175 return !(Amount == 8 || Amount == 9 || Amount<=2);
176}
177
178// Implemented to verify test case assertions in
179// tests/codegen/msp430/shift-amount-threshold-b.ll
181 if (CLOpts.no_legal_immediate)
182 return Immed >= -32 && Immed < 32;
184}
185
186//===----------------------------------------------------------------------===//
187// MSP430 Inline Assembly Support
188//===----------------------------------------------------------------------===//
189
190/// getConstraintType - Given a constraint letter, return the type of
191/// constraint it is for this target.
194 if (Constraint.size() == 1) {
195 switch (Constraint[0]) {
196 case 'r':
197 return C_RegisterClass;
198 default:
199 break;
200 }
201 }
202 return TargetLowering::getConstraintType(Constraint);
203}
204
205std::pair<unsigned, const TargetRegisterClass *>
207 const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
208 if (Constraint.size() == 1) {
209 // GCC Constraint Letters
210 switch (Constraint[0]) {
211 default: break;
212 case 'r': // GENERAL_REGS
213 if (VT == MVT::i8)
214 return std::make_pair(0U, &MSP430::GR8RegClass);
215
216 return std::make_pair(0U, &MSP430::GR16RegClass);
217 }
218 }
219
221}
222
223//===----------------------------------------------------------------------===//
224// Calling Convention Implementation
225//===----------------------------------------------------------------------===//
226
227#define GET_CALLING_CONV_IMPL
228#include "MSP430GenCallingConv.inc"
229
230/// For each argument in a function store the number of pieces it is composed
231/// of.
232template<typename ArgT>
235 unsigned CurrentArgIndex;
236
237 if (Args.empty())
238 return;
239
240 CurrentArgIndex = Args[0].OrigArgIndex;
241 Out.push_back(0);
242
243 for (auto &Arg : Args) {
244 if (CurrentArgIndex == Arg.OrigArgIndex) {
245 Out.back() += 1;
246 } else {
247 Out.push_back(1);
248 CurrentArgIndex = Arg.OrigArgIndex;
249 }
250 }
251}
252
253static void AnalyzeVarArgs(CCState &State,
255 State.AnalyzeCallOperands(Outs, CC_MSP430_AssignStack);
256}
257
258static void AnalyzeVarArgs(CCState &State,
260 State.AnalyzeFormalArguments(Ins, CC_MSP430_AssignStack);
261}
262
263/// Analyze incoming and outgoing function arguments. We need custom C++ code
264/// to handle special constraints in the ABI like reversing the order of the
265/// pieces of splitted arguments. In addition, all pieces of a certain argument
266/// have to be passed either using registers or the stack but never mixing both.
267template<typename ArgT>
268static void AnalyzeArguments(CCState &State,
270 const SmallVectorImpl<ArgT> &Args) {
271 static const MCPhysReg CRegList[] = {
272 MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15
273 };
274 static const unsigned CNbRegs = std::size(CRegList);
275 static const MCPhysReg BuiltinRegList[] = {
276 MSP430::R8, MSP430::R9, MSP430::R10, MSP430::R11,
277 MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15
278 };
279 static const unsigned BuiltinNbRegs = std::size(BuiltinRegList);
280
281 ArrayRef<MCPhysReg> RegList;
282 unsigned NbRegs;
283
284 bool Builtin = (State.getCallingConv() == CallingConv::MSP430_BUILTIN);
285 if (Builtin) {
286 RegList = BuiltinRegList;
287 NbRegs = BuiltinNbRegs;
288 } else {
289 RegList = CRegList;
290 NbRegs = CNbRegs;
291 }
292
293 if (State.isVarArg()) {
294 AnalyzeVarArgs(State, Args);
295 return;
296 }
297
298 SmallVector<unsigned, 4> ArgsParts;
299 ParseFunctionArgs(Args, ArgsParts);
300
301 if (Builtin) {
302 assert(ArgsParts.size() == 2 &&
303 "Builtin calling convention requires two arguments");
304 }
305
306 unsigned RegsLeft = NbRegs;
307 bool UsedStack = false;
308 unsigned ValNo = 0;
309
310 for (unsigned i = 0, e = ArgsParts.size(); i != e; i++) {
311 MVT ArgVT = Args[ValNo].VT;
312 ISD::ArgFlagsTy ArgFlags = Args[ValNo].Flags;
313 Type *OrigTy = Args[ValNo].OrigTy;
314 MVT LocVT = ArgVT;
316
317 // Promote i8 to i16
318 if (LocVT == MVT::i8) {
319 LocVT = MVT::i16;
320 if (ArgFlags.isSExt())
321 LocInfo = CCValAssign::SExt;
322 else if (ArgFlags.isZExt())
323 LocInfo = CCValAssign::ZExt;
324 else
325 LocInfo = CCValAssign::AExt;
326 }
327
328 // Handle byval arguments
329 if (ArgFlags.isByVal()) {
330 State.HandleByVal(ValNo++, ArgVT, LocVT, LocInfo, 2, Align(2), ArgFlags);
331 continue;
332 }
333
334 unsigned Parts = ArgsParts[i];
335
336 if (Builtin) {
337 assert(Parts == 4 &&
338 "Builtin calling convention requires 64-bit arguments");
339 }
340
341 if (!UsedStack && Parts == 2 && RegsLeft == 1) {
342 // Special case for 32-bit register split, see EABI section 3.3.3
343 MCRegister Reg = State.AllocateReg(RegList);
344 State.addLoc(CCValAssign::getReg(ValNo++, ArgVT, Reg, LocVT, LocInfo));
345 RegsLeft -= 1;
346
347 UsedStack = true;
348 CC_MSP430_AssignStack(ValNo++, ArgVT, LocVT, LocInfo, ArgFlags, OrigTy,
349 State);
350 } else if (Parts <= RegsLeft) {
351 for (unsigned j = 0; j < Parts; j++) {
352 MCRegister Reg = State.AllocateReg(RegList);
353 State.addLoc(CCValAssign::getReg(ValNo++, ArgVT, Reg, LocVT, LocInfo));
354 RegsLeft--;
355 }
356 } else {
357 UsedStack = true;
358 for (unsigned j = 0; j < Parts; j++)
359 CC_MSP430_AssignStack(ValNo++, ArgVT, LocVT, LocInfo, ArgFlags, OrigTy,
360 State);
361 }
362 }
363}
364
365static void AnalyzeRetResult(CCState &State,
367 State.AnalyzeCallResult(Ins, RetCC_MSP430);
368}
369
370static void AnalyzeRetResult(CCState &State,
372 State.AnalyzeReturn(Outs, RetCC_MSP430);
373}
374
375template<typename ArgT>
376static void AnalyzeReturnValues(CCState &State,
378 const SmallVectorImpl<ArgT> &Args) {
379 AnalyzeRetResult(State, Args);
380}
381
382SDValue MSP430TargetLowering::LowerFormalArguments(
383 SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
384 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
385 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
386
387 switch (CallConv) {
388 default:
389 report_fatal_error("Unsupported calling convention");
390 case CallingConv::C:
392 return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals);
394 if (Ins.empty())
395 return Chain;
396 report_fatal_error("ISRs cannot have arguments");
397 }
398}
399
401MSP430TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
402 SmallVectorImpl<SDValue> &InVals) const {
403 SelectionDAG &DAG = CLI.DAG;
404 SDLoc &dl = CLI.DL;
405 SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
406 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
407 SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
408 SDValue Chain = CLI.Chain;
409 SDValue Callee = CLI.Callee;
410 bool &isTailCall = CLI.IsTailCall;
411 CallingConv::ID CallConv = CLI.CallConv;
412 bool isVarArg = CLI.IsVarArg;
413
414 // MSP430 target does not yet support tail call optimization.
415 isTailCall = false;
416
417 switch (CallConv) {
418 default:
419 report_fatal_error("Unsupported calling convention");
422 case CallingConv::C:
423 return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
424 Outs, OutVals, Ins, dl, DAG, InVals);
426 report_fatal_error("ISRs cannot be called directly");
427 }
428}
429
430/// LowerCCCArguments - transform physical registers into virtual registers and
431/// generate load operations for arguments places on the stack.
432// FIXME: struct return stuff
433SDValue MSP430TargetLowering::LowerCCCArguments(
434 SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
435 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
436 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
438 MachineFrameInfo &MFI = MF.getFrameInfo();
439 MachineRegisterInfo &RegInfo = MF.getRegInfo();
440 MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
441
442 // Assign locations to all of the incoming arguments.
444 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
445 *DAG.getContext());
446 AnalyzeArguments(CCInfo, ArgLocs, Ins);
447
448 // Create frame index for the start of the first vararg value
449 if (isVarArg) {
450 unsigned Offset = CCInfo.getStackSize();
451 FuncInfo->setVarArgsFrameIndex(MFI.CreateFixedObject(1, Offset, true));
452 }
453
454 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
455 CCValAssign &VA = ArgLocs[i];
456 if (VA.isRegLoc()) {
457 // Arguments passed in registers
458 EVT RegVT = VA.getLocVT();
459 switch (RegVT.getSimpleVT().SimpleTy) {
460 default:
461 {
462#ifndef NDEBUG
463 errs() << "LowerFormalArguments Unhandled argument type: "
464 << RegVT << "\n";
465#endif
466 llvm_unreachable(nullptr);
467 }
468 case MVT::i16:
469 Register VReg = RegInfo.createVirtualRegister(&MSP430::GR16RegClass);
470 RegInfo.addLiveIn(VA.getLocReg(), VReg);
471 SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, RegVT);
472
473 // If this is an 8-bit value, it is really passed promoted to 16
474 // bits. Insert an assert[sz]ext to capture this, then truncate to the
475 // right size.
476 if (VA.getLocInfo() == CCValAssign::SExt)
477 ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue,
478 DAG.getValueType(VA.getValVT()));
479 else if (VA.getLocInfo() == CCValAssign::ZExt)
480 ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue,
481 DAG.getValueType(VA.getValVT()));
482
483 if (VA.getLocInfo() != CCValAssign::Full)
484 ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
485
486 InVals.push_back(ArgValue);
487 }
488 } else {
489 // Only arguments passed on the stack should make it here.
490 assert(VA.isMemLoc());
491
492 SDValue InVal;
493 ISD::ArgFlagsTy Flags = Ins[i].Flags;
494
495 if (Flags.isByVal()) {
496 MVT PtrVT = VA.getLocVT();
497 int FI = MFI.CreateFixedObject(Flags.getByValSize(),
498 VA.getLocMemOffset(), true);
499 InVal = DAG.getFrameIndex(FI, PtrVT);
500 } else {
501 // Load the argument to a virtual register
502 unsigned ObjSize = VA.getLocVT().getSizeInBits()/8;
503 if (ObjSize > 2) {
504 errs() << "LowerFormalArguments Unhandled argument type: "
505 << VA.getLocVT() << "\n";
506 }
507 // Create the frame index object for this incoming parameter...
508 int FI = MFI.CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);
509
510 // Create the SelectionDAG nodes corresponding to a load
511 //from this parameter
512 SDValue FIN = DAG.getFrameIndex(FI, MVT::i16);
513 InVal = DAG.getLoad(
514 VA.getLocVT(), dl, Chain, FIN,
516 }
517
518 InVals.push_back(InVal);
519 }
520 }
521
522 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
523 if (Ins[i].Flags.isSRet()) {
524 Register Reg = FuncInfo->getSRetReturnReg();
525 if (!Reg) {
527 getRegClassFor(MVT::i16));
528 FuncInfo->setSRetReturnReg(Reg);
529 }
530 SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, InVals[i]);
531 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain);
532 }
533 }
534
535 return Chain;
536}
537
538bool
539MSP430TargetLowering::CanLowerReturn(CallingConv::ID CallConv,
540 MachineFunction &MF,
541 bool IsVarArg,
544 const Type *RetTy) const {
546 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
547 return CCInfo.CheckReturn(Outs, RetCC_MSP430);
548}
549
551MSP430TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
552 bool isVarArg,
554 const SmallVectorImpl<SDValue> &OutVals,
555 const SDLoc &dl, SelectionDAG &DAG) const {
556
558
559 // CCValAssign - represent the assignment of the return value to a location
561
562 // ISRs cannot return any value.
563 if (CallConv == CallingConv::MSP430_INTR && !Outs.empty())
564 report_fatal_error("ISRs cannot return any value");
565
566 // CCState - Info about the registers and stack slot.
567 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
568 *DAG.getContext());
569
570 // Analize return values.
571 AnalyzeReturnValues(CCInfo, RVLocs, Outs);
572
573 SDValue Glue;
574 SmallVector<SDValue, 4> RetOps(1, Chain);
575
576 // Copy the result values into the output registers.
577 for (unsigned i = 0; i != RVLocs.size(); ++i) {
578 CCValAssign &VA = RVLocs[i];
579 assert(VA.isRegLoc() && "Can only return in registers!");
580
581 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
582 OutVals[i], Glue);
583
584 // Guarantee that all emitted copies are stuck together,
585 // avoiding something bad.
586 Glue = Chain.getValue(1);
587 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
588 }
589
590 if (MF.getFunction().hasStructRetAttr()) {
591 MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
592 Register Reg = FuncInfo->getSRetReturnReg();
593
594 if (!Reg)
595 llvm_unreachable("sret virtual register not created in entry block");
596
597 MVT PtrVT = getFrameIndexTy(DAG.getDataLayout());
598 SDValue Val =
599 DAG.getCopyFromReg(Chain, dl, Reg, PtrVT);
600 unsigned R12 = MSP430::R12;
601
602 Chain = DAG.getCopyToReg(Chain, dl, R12, Val, Glue);
603 Glue = Chain.getValue(1);
604 RetOps.push_back(DAG.getRegister(R12, PtrVT));
605 }
606
607 unsigned Opc = (CallConv == CallingConv::MSP430_INTR ?
608 MSP430ISD::RETI_GLUE : MSP430ISD::RET_GLUE);
609
610 RetOps[0] = Chain; // Update chain.
611
612 // Add the glue if we have it.
613 if (Glue.getNode())
614 RetOps.push_back(Glue);
615
616 return DAG.getNode(Opc, dl, MVT::Other, RetOps);
617}
618
619/// LowerCCCCallTo - functions arguments are copied from virtual regs to
620/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
621SDValue MSP430TargetLowering::LowerCCCCallTo(
622 SDValue Chain, SDValue Callee, CallingConv::ID CallConv, bool isVarArg,
623 bool isTailCall, const SmallVectorImpl<ISD::OutputArg> &Outs,
624 const SmallVectorImpl<SDValue> &OutVals,
625 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
626 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
627 // Analyze operands of the call, assigning locations to each operand.
629 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
630 *DAG.getContext());
631 AnalyzeArguments(CCInfo, ArgLocs, Outs);
632
633 // Get a count of how many bytes are to be pushed on the stack.
634 unsigned NumBytes = CCInfo.getStackSize();
635 MVT PtrVT = getFrameIndexTy(DAG.getDataLayout());
636
637 Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, dl);
638
640 SmallVector<SDValue, 12> MemOpChains;
641 SDValue StackPtr;
642
643 // Walk the register/memloc assignments, inserting copies/loads.
644 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
645 CCValAssign &VA = ArgLocs[i];
646
647 SDValue Arg = OutVals[i];
648
649 // Promote the value if needed.
650 switch (VA.getLocInfo()) {
651 default: llvm_unreachable("Unknown loc info!");
652 case CCValAssign::Full: break;
654 Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
655 break;
657 Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
658 break;
660 Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
661 break;
662 }
663
664 // Arguments that can be passed on register must be kept at RegsToPass
665 // vector
666 if (VA.isRegLoc()) {
667 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
668 } else {
669 assert(VA.isMemLoc());
670
671 if (!StackPtr.getNode())
672 StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SP, PtrVT);
673
674 SDValue PtrOff =
675 DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr,
676 DAG.getIntPtrConstant(VA.getLocMemOffset(), dl));
677
678 SDValue MemOp;
679 ISD::ArgFlagsTy Flags = Outs[i].Flags;
680
681 if (Flags.isByVal()) {
682 SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), dl, MVT::i16);
683 Align Alignment = Flags.getNonZeroByValAlign();
684 MemOp = DAG.getMemcpy(Chain, dl, PtrOff, Arg, SizeNode, Alignment,
685 Alignment,
686 /*isVolatile*/ false,
687 /*AlwaysInline=*/true,
688 /*CI=*/nullptr, std::nullopt,
689 MachinePointerInfo(), MachinePointerInfo());
690 } else {
691 MemOp = DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
692 }
693
694 MemOpChains.push_back(MemOp);
695 }
696 }
697
698 // Transform all store nodes into one single node because all store nodes are
699 // independent of each other.
700 if (!MemOpChains.empty())
701 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
702
703 // Build a sequence of copy-to-reg nodes chained together with token chain and
704 // flag operands which copy the outgoing args into registers. The InGlue in
705 // necessary since all emitted instructions must be stuck together.
706 SDValue InGlue;
707 for (const auto &[Reg, N] : RegsToPass) {
708 Chain = DAG.getCopyToReg(Chain, dl, Reg, N, InGlue);
709 InGlue = Chain.getValue(1);
710 }
711
712 // If the callee is a GlobalAddress node (quite common, every direct call is)
713 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
714 // Likewise ExternalSymbol -> TargetExternalSymbol.
715 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
716 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i16);
717 else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
718 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i16);
719
720 // Returns a chain & a flag for retval copy to use.
721 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
723 Ops.push_back(Chain);
724 Ops.push_back(Callee);
725
726 // Add argument registers to the end of the list so that they are
727 // known live into the call.
728 for (const auto &[Reg, N] : RegsToPass)
729 Ops.push_back(DAG.getRegister(Reg, N.getValueType()));
730
731 if (InGlue.getNode())
732 Ops.push_back(InGlue);
733
734 Chain = DAG.getNode(MSP430ISD::CALL, dl, NodeTys, Ops);
735 InGlue = Chain.getValue(1);
736
737 // Create the CALLSEQ_END node.
738 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, InGlue, dl);
739 InGlue = Chain.getValue(1);
740
741 // Handle result values, copying them out of physregs into vregs that we
742 // return.
743 return LowerCallResult(Chain, InGlue, CallConv, isVarArg, Ins, dl,
744 DAG, InVals);
745}
746
747/// LowerCallResult - Lower the result values of a call into the
748/// appropriate copies out of appropriate physical registers.
749///
750SDValue MSP430TargetLowering::LowerCallResult(
751 SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool isVarArg,
752 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
753 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
754
755 // Assign locations to each value returned by this call.
757 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
758 *DAG.getContext());
759
760 AnalyzeReturnValues(CCInfo, RVLocs, Ins);
761
762 // Copy all of the result registers out of their specified physreg.
763 for (unsigned i = 0; i != RVLocs.size(); ++i) {
764 Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(),
765 RVLocs[i].getValVT(), InGlue).getValue(1);
766 InGlue = Chain.getValue(2);
767 InVals.push_back(Chain.getValue(0));
768 }
769
770 return Chain;
771}
772
774 SelectionDAG &DAG) const {
775 unsigned Opc = Op.getOpcode();
776 SDNode* N = Op.getNode();
777 EVT VT = Op.getValueType();
778 SDLoc dl(N);
779
780 // Expand non-constant shifts to loops:
781 if (!isa<ConstantSDNode>(N->getOperand(1)))
782 return Op;
783
784 uint64_t ShiftAmount = N->getConstantOperandVal(1);
785
786 // Expand the stuff into sequence of shifts.
787 SDValue Victim = N->getOperand(0);
788
789 if (ShiftAmount >= 8) {
790 assert(VT == MVT::i16 && "Can not shift i8 by 8 and more");
791 switch(Opc) {
792 default:
793 llvm_unreachable("Unknown shift");
794 case ISD::SHL:
795 // foo << (8 + N) => swpb(zext(foo)) << N
796 Victim = DAG.getZeroExtendInReg(Victim, dl, MVT::i8);
797 Victim = DAG.getNode(ISD::BSWAP, dl, VT, Victim);
798 break;
799 case ISD::SRA:
800 case ISD::SRL:
801 // foo >> (8 + N) => sxt(swpb(foo)) >> N
802 Victim = DAG.getNode(ISD::BSWAP, dl, VT, Victim);
803 Victim = (Opc == ISD::SRA)
804 ? DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT, Victim,
805 DAG.getValueType(MVT::i8))
806 : DAG.getZeroExtendInReg(Victim, dl, MVT::i8);
807 break;
808 }
809 ShiftAmount -= 8;
810 }
811
812 if (Opc == ISD::SRL && ShiftAmount) {
813 // Emit a special goodness here:
814 // srl A, 1 => clrc; rrc A
815 Victim = DAG.getNode(MSP430ISD::RRCL, dl, VT, Victim);
816 ShiftAmount -= 1;
817 }
818
819 while (ShiftAmount--)
820 Victim = DAG.getNode((Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA),
821 dl, VT, Victim);
822
823 return Victim;
824}
825
827 SelectionDAG &DAG) const {
828 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
829 int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();
830 EVT PtrVT = Op.getValueType();
831
832 // Create the TargetGlobalAddress node, folding in the constant offset.
833 SDValue Result = DAG.getTargetGlobalAddress(GV, SDLoc(Op), PtrVT, Offset);
834 return DAG.getNode(MSP430ISD::Wrapper, SDLoc(Op), PtrVT, Result);
835}
836
838 SelectionDAG &DAG) const {
839 SDLoc dl(Op);
840 const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol();
841 EVT PtrVT = Op.getValueType();
842 SDValue Result = DAG.getTargetExternalSymbol(Sym, PtrVT);
843
844 return DAG.getNode(MSP430ISD::Wrapper, dl, PtrVT, Result);
845}
846
848 SelectionDAG &DAG) const {
849 SDLoc dl(Op);
850 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
851 EVT PtrVT = Op.getValueType();
852 SDValue Result = DAG.getTargetBlockAddress(BA, PtrVT);
853
854 return DAG.getNode(MSP430ISD::Wrapper, dl, PtrVT, Result);
855}
856
858 ISD::CondCode CC, const SDLoc &dl, SelectionDAG &DAG) {
859 // FIXME: Handle bittests someday
860 assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet");
861
862 // FIXME: Handle jump negative someday
864 switch (CC) {
865 default: llvm_unreachable("Invalid integer condition!");
866 case ISD::SETEQ:
867 TCC = MSP430CC::COND_E; // aka COND_Z
868 // Minor optimization: if LHS is a constant, swap operands, then the
869 // constant can be folded into comparison.
870 if (LHS.getOpcode() == ISD::Constant)
871 std::swap(LHS, RHS);
872 break;
873 case ISD::SETNE:
874 TCC = MSP430CC::COND_NE; // aka COND_NZ
875 // Minor optimization: if LHS is a constant, swap operands, then the
876 // constant can be folded into comparison.
877 if (LHS.getOpcode() == ISD::Constant)
878 std::swap(LHS, RHS);
879 break;
880 case ISD::SETULE:
881 std::swap(LHS, RHS);
882 [[fallthrough]];
883 case ISD::SETUGE:
884 // Turn lhs u>= rhs with lhs constant into rhs u< lhs+1, this allows us to
885 // fold constant into instruction.
887 LHS = RHS;
888 RHS =
889 DAG.getSignedConstant(C->getSExtValue() + 1, dl, C->getValueType(0));
890 TCC = MSP430CC::COND_LO;
891 break;
892 }
893 TCC = MSP430CC::COND_HS; // aka COND_C
894 break;
895 case ISD::SETUGT:
896 std::swap(LHS, RHS);
897 [[fallthrough]];
898 case ISD::SETULT:
899 // Turn lhs u< rhs with lhs constant into rhs u>= lhs+1, this allows us to
900 // fold constant into instruction.
902 LHS = RHS;
903 RHS =
904 DAG.getSignedConstant(C->getSExtValue() + 1, dl, C->getValueType(0));
905 TCC = MSP430CC::COND_HS;
906 break;
907 }
908 TCC = MSP430CC::COND_LO; // aka COND_NC
909 break;
910 case ISD::SETLE:
911 std::swap(LHS, RHS);
912 [[fallthrough]];
913 case ISD::SETGE:
914 // Turn lhs >= rhs with lhs constant into rhs < lhs+1, this allows us to
915 // fold constant into instruction.
917 LHS = RHS;
918 RHS =
919 DAG.getSignedConstant(C->getSExtValue() + 1, dl, C->getValueType(0));
920 TCC = MSP430CC::COND_L;
921 break;
922 }
923 TCC = MSP430CC::COND_GE;
924 break;
925 case ISD::SETGT:
926 std::swap(LHS, RHS);
927 [[fallthrough]];
928 case ISD::SETLT:
929 // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to
930 // fold constant into instruction.
932 LHS = RHS;
933 RHS =
934 DAG.getSignedConstant(C->getSExtValue() + 1, dl, C->getValueType(0));
935 TCC = MSP430CC::COND_GE;
936 break;
937 }
938 TCC = MSP430CC::COND_L;
939 break;
940 }
941
942 TargetCC = DAG.getConstant(TCC, dl, MVT::i8);
943 return DAG.getNode(MSP430ISD::CMP, dl, MVT::Glue, LHS, RHS);
944}
945
946
948 SDValue Chain = Op.getOperand(0);
949 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
950 SDValue LHS = Op.getOperand(2);
951 SDValue RHS = Op.getOperand(3);
952 SDValue Dest = Op.getOperand(4);
953 SDLoc dl (Op);
954
955 SDValue TargetCC;
956 SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
957
958 return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(),
959 Chain, Dest, TargetCC, Flag);
960}
961
963 SDValue LHS = Op.getOperand(0);
964 SDValue RHS = Op.getOperand(1);
965 SDLoc dl (Op);
966
967 // If we are doing an AND and testing against zero, then the CMP
968 // will not be generated. The AND (or BIT) will generate the condition codes,
969 // but they are different from CMP.
970 // FIXME: since we're doing a post-processing, use a pseudoinstr here, so
971 // lowering & isel wouldn't diverge.
972 bool andCC = isNullConstant(RHS) && LHS.hasOneUse() &&
973 (LHS.getOpcode() == ISD::AND ||
974 (LHS.getOpcode() == ISD::TRUNCATE &&
975 LHS.getOperand(0).getOpcode() == ISD::AND));
976 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
977 SDValue TargetCC;
978 SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
979
980 // Get the condition codes directly from the status register, if its easy.
981 // Otherwise a branch will be generated. Note that the AND and BIT
982 // instructions generate different flags than CMP, the carry bit can be used
983 // for NE/EQ.
984 bool Invert = false;
985 bool Shift = false;
986 bool Convert = true;
987 switch (TargetCC->getAsZExtVal()) {
988 default:
989 Convert = false;
990 break;
992 // Res = SR & 1, no processing is required
993 break;
995 // Res = ~(SR & 1)
996 Invert = true;
997 break;
999 if (andCC) {
1000 // C = ~Z, thus Res = SR & 1, no processing is required
1001 } else {
1002 // Res = ~((SR >> 1) & 1)
1003 Shift = true;
1004 Invert = true;
1005 }
1006 break;
1007 case MSP430CC::COND_E:
1008 Shift = true;
1009 // C = ~Z for AND instruction, thus we can put Res = ~(SR & 1), however,
1010 // Res = (SR >> 1) & 1 is 1 word shorter.
1011 break;
1012 }
1013 EVT VT = Op.getValueType();
1014 SDValue One = DAG.getConstant(1, dl, VT);
1015 if (Convert) {
1016 SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SR,
1017 MVT::i16, Flag);
1018 if (Shift)
1019 // FIXME: somewhere this is turned into a SRL, lower it MSP specific?
1020 SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One);
1021 SR = DAG.getNode(ISD::AND, dl, MVT::i16, SR, One);
1022 if (Invert)
1023 SR = DAG.getNode(ISD::XOR, dl, MVT::i16, SR, One);
1024 return SR;
1025 } else {
1026 SDValue Zero = DAG.getConstant(0, dl, VT);
1027 SDValue Ops[] = {One, Zero, TargetCC, Flag};
1028 return DAG.getNode(MSP430ISD::SELECT_CC, dl, Op.getValueType(), Ops);
1029 }
1030}
1031
1033 SelectionDAG &DAG) const {
1034 SDValue LHS = Op.getOperand(0);
1035 SDValue RHS = Op.getOperand(1);
1036 SDValue TrueV = Op.getOperand(2);
1037 SDValue FalseV = Op.getOperand(3);
1038 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
1039 SDLoc dl (Op);
1040
1041 SDValue TargetCC;
1042 SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
1043
1044 SDValue Ops[] = {TrueV, FalseV, TargetCC, Flag};
1045
1046 return DAG.getNode(MSP430ISD::SELECT_CC, dl, Op.getValueType(), Ops);
1047}
1048
1050 SelectionDAG &DAG) const {
1051 SDValue Val = Op.getOperand(0);
1052 EVT VT = Op.getValueType();
1053 SDLoc dl(Op);
1054
1055 assert(VT == MVT::i16 && "Only support i16 for now!");
1056
1057 return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT,
1058 DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val),
1059 DAG.getValueType(Val.getValueType()));
1060}
1061
1062SDValue
1066 int ReturnAddrIndex = FuncInfo->getRAIndex();
1067 MVT PtrVT = getFrameIndexTy(MF.getDataLayout());
1068
1069 if (ReturnAddrIndex == 0) {
1070 // Set up a frame object for the return address.
1071 uint64_t SlotSize = PtrVT.getStoreSize();
1072 ReturnAddrIndex = MF.getFrameInfo().CreateFixedObject(SlotSize, -SlotSize,
1073 true);
1074 FuncInfo->setRAIndex(ReturnAddrIndex);
1075 }
1076
1077 return DAG.getFrameIndex(ReturnAddrIndex, PtrVT);
1078}
1079
1081 SelectionDAG &DAG) const {
1083 MFI.setReturnAddressIsTaken(true);
1084
1085 unsigned Depth = Op.getConstantOperandVal(0);
1086 SDLoc dl(Op);
1087 EVT PtrVT = Op.getValueType();
1088
1089 if (Depth > 0) {
1090 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
1091 SDValue Offset =
1092 DAG.getConstant(PtrVT.getStoreSize(), dl, MVT::i16);
1093 return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(),
1094 DAG.getNode(ISD::ADD, dl, PtrVT, FrameAddr, Offset),
1096 }
1097
1098 // Just load the return address.
1099 SDValue RetAddrFI = getReturnAddressFrameIndex(DAG);
1100 return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), RetAddrFI,
1102}
1103
1105 SelectionDAG &DAG) const {
1107 MFI.setFrameAddressIsTaken(true);
1108
1109 EVT VT = Op.getValueType();
1110 SDLoc dl(Op); // FIXME probably not meaningful
1111 unsigned Depth = Op.getConstantOperandVal(0);
1112 SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl,
1113 MSP430::R4, VT);
1114 while (Depth--)
1115 FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
1117 return FrameAddr;
1118}
1119
1121 SelectionDAG &DAG) const {
1124
1125 SDValue Ptr = Op.getOperand(1);
1126 EVT PtrVT = Ptr.getValueType();
1127
1128 // Frame index of first vararg argument
1129 SDValue FrameIndex =
1130 DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);
1131 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
1132
1133 // Create a store of the frame index to the location operand
1134 return DAG.getStore(Op.getOperand(0), SDLoc(Op), FrameIndex, Ptr,
1135 MachinePointerInfo(SV));
1136}
1137
1139 SelectionDAG &DAG) const {
1141 EVT PtrVT = Op.getValueType();
1142 SDValue Result = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
1143 return DAG.getNode(MSP430ISD::Wrapper, SDLoc(JT), PtrVT, Result);
1144}
1145
1146/// getPostIndexedAddressParts - returns true by value, base pointer and
1147/// offset pointer and addressing mode by reference if this node can be
1148/// combined with a load / store to form a post-indexed load / store.
1149bool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
1150 SDValue &Base,
1151 SDValue &Offset,
1153 SelectionDAG &DAG) const {
1154
1156 if (LD->getExtensionType() != ISD::NON_EXTLOAD)
1157 return false;
1158
1159 EVT VT = LD->getMemoryVT();
1160 if (VT != MVT::i8 && VT != MVT::i16)
1161 return false;
1162
1163 if (Op->getOpcode() != ISD::ADD)
1164 return false;
1165
1166 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) {
1167 uint64_t RHSC = RHS->getZExtValue();
1168 if ((VT == MVT::i16 && RHSC != 2) ||
1169 (VT == MVT::i8 && RHSC != 1))
1170 return false;
1171
1172 Base = Op->getOperand(0);
1173 Offset = DAG.getConstant(RHSC, SDLoc(N), VT);
1174 AM = ISD::POST_INC;
1175 return true;
1176 }
1177
1178 return false;
1179}
1180
1182 Type *Ty2) const {
1183 if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
1184 return false;
1185
1186 return (Ty1->getPrimitiveSizeInBits().getFixedValue() >
1188}
1189
1191 if (!VT1.isInteger() || !VT2.isInteger())
1192 return false;
1193
1194 return (VT1.getFixedSizeInBits() > VT2.getFixedSizeInBits());
1195}
1196
1198 // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
1199 return false && Ty1->isIntegerTy(8) && Ty2->isIntegerTy(16);
1200}
1201
1203 // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
1204 return false && VT1 == MVT::i8 && VT2 == MVT::i16;
1205}
1206
1207//===----------------------------------------------------------------------===//
1208// Other Lowering Code
1209//===----------------------------------------------------------------------===//
1210
1213 MachineBasicBlock *BB) const {
1214 MachineFunction *F = BB->getParent();
1215 MachineRegisterInfo &RI = F->getRegInfo();
1216 DebugLoc dl = MI.getDebugLoc();
1217 const TargetInstrInfo &TII = *F->getSubtarget().getInstrInfo();
1218
1219 unsigned Opc;
1220 bool ClearCarry = false;
1221 const TargetRegisterClass * RC;
1222 switch (MI.getOpcode()) {
1223 default: llvm_unreachable("Invalid shift opcode!");
1224 case MSP430::Shl8:
1225 Opc = MSP430::ADD8rr;
1226 RC = &MSP430::GR8RegClass;
1227 break;
1228 case MSP430::Shl16:
1229 Opc = MSP430::ADD16rr;
1230 RC = &MSP430::GR16RegClass;
1231 break;
1232 case MSP430::Sra8:
1233 Opc = MSP430::RRA8r;
1234 RC = &MSP430::GR8RegClass;
1235 break;
1236 case MSP430::Sra16:
1237 Opc = MSP430::RRA16r;
1238 RC = &MSP430::GR16RegClass;
1239 break;
1240 case MSP430::Srl8:
1241 ClearCarry = true;
1242 Opc = MSP430::RRC8r;
1243 RC = &MSP430::GR8RegClass;
1244 break;
1245 case MSP430::Srl16:
1246 ClearCarry = true;
1247 Opc = MSP430::RRC16r;
1248 RC = &MSP430::GR16RegClass;
1249 break;
1250 case MSP430::Rrcl8:
1251 case MSP430::Rrcl16: {
1252 BuildMI(*BB, MI, dl, TII.get(MSP430::BIC16rc), MSP430::SR)
1253 .addReg(MSP430::SR).addImm(1);
1254 Register SrcReg = MI.getOperand(1).getReg();
1255 Register DstReg = MI.getOperand(0).getReg();
1256 unsigned RrcOpc = MI.getOpcode() == MSP430::Rrcl16
1257 ? MSP430::RRC16r : MSP430::RRC8r;
1258 BuildMI(*BB, MI, dl, TII.get(RrcOpc), DstReg)
1259 .addReg(SrcReg);
1260 MI.eraseFromParent(); // The pseudo instruction is gone now.
1261 return BB;
1262 }
1263 }
1264
1265 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1267
1268 // Create loop block
1269 MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB);
1270 MachineBasicBlock *RemBB = F->CreateMachineBasicBlock(LLVM_BB);
1271
1272 F->insert(I, LoopBB);
1273 F->insert(I, RemBB);
1274
1275 // Update machine-CFG edges by transferring all successors of the current
1276 // block to the block containing instructions after shift.
1277 RemBB->splice(RemBB->begin(), BB, std::next(MachineBasicBlock::iterator(MI)),
1278 BB->end());
1280
1281 // Add edges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB
1282 BB->addSuccessor(LoopBB);
1283 BB->addSuccessor(RemBB);
1284 LoopBB->addSuccessor(RemBB);
1285 LoopBB->addSuccessor(LoopBB);
1286
1287 Register ShiftAmtReg = RI.createVirtualRegister(&MSP430::GR8RegClass);
1288 Register ShiftAmtReg2 = RI.createVirtualRegister(&MSP430::GR8RegClass);
1289 Register ShiftReg = RI.createVirtualRegister(RC);
1290 Register ShiftReg2 = RI.createVirtualRegister(RC);
1291 Register ShiftAmtSrcReg = MI.getOperand(2).getReg();
1292 Register SrcReg = MI.getOperand(1).getReg();
1293 Register DstReg = MI.getOperand(0).getReg();
1294
1295 // BB:
1296 // cmp 0, N
1297 // je RemBB
1298 BuildMI(BB, dl, TII.get(MSP430::CMP8ri))
1299 .addReg(ShiftAmtSrcReg).addImm(0);
1300 BuildMI(BB, dl, TII.get(MSP430::JCC))
1301 .addMBB(RemBB)
1303
1304 // LoopBB:
1305 // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB]
1306 // ShiftAmt = phi [%N, BB], [%ShiftAmt2, LoopBB]
1307 // ShiftReg2 = shift ShiftReg
1308 // ShiftAmt2 = ShiftAmt - 1;
1309 BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftReg)
1310 .addReg(SrcReg).addMBB(BB)
1311 .addReg(ShiftReg2).addMBB(LoopBB);
1312 BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg)
1313 .addReg(ShiftAmtSrcReg).addMBB(BB)
1314 .addReg(ShiftAmtReg2).addMBB(LoopBB);
1315 if (ClearCarry)
1316 BuildMI(LoopBB, dl, TII.get(MSP430::BIC16rc), MSP430::SR)
1317 .addReg(MSP430::SR).addImm(1);
1318 if (Opc == MSP430::ADD8rr || Opc == MSP430::ADD16rr)
1319 BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2)
1320 .addReg(ShiftReg)
1321 .addReg(ShiftReg);
1322 else
1323 BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2)
1324 .addReg(ShiftReg);
1325 BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2)
1326 .addReg(ShiftAmtReg).addImm(1);
1327 BuildMI(LoopBB, dl, TII.get(MSP430::JCC))
1328 .addMBB(LoopBB)
1330
1331 // RemBB:
1332 // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB]
1333 BuildMI(*RemBB, RemBB->begin(), dl, TII.get(MSP430::PHI), DstReg)
1334 .addReg(SrcReg).addMBB(BB)
1335 .addReg(ShiftReg2).addMBB(LoopBB);
1336
1337 MI.eraseFromParent(); // The pseudo instruction is gone now.
1338 return RemBB;
1339}
1340
1343 MachineBasicBlock *BB) const {
1344 unsigned Opc = MI.getOpcode();
1345
1346 if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 ||
1347 Opc == MSP430::Sra8 || Opc == MSP430::Sra16 ||
1348 Opc == MSP430::Srl8 || Opc == MSP430::Srl16 ||
1349 Opc == MSP430::Rrcl8 || Opc == MSP430::Rrcl16)
1350 return EmitShiftInstr(MI, BB);
1351
1353 DebugLoc dl = MI.getDebugLoc();
1354
1355 assert((Opc == MSP430::Select16 || Opc == MSP430::Select8) &&
1356 "Unexpected instr type to insert");
1357
1358 // To "insert" a SELECT instruction, we actually have to insert the diamond
1359 // control-flow pattern. The incoming instruction knows the destination vreg
1360 // to set, the condition code register to branch on, the true/false values to
1361 // select between, and a branch opcode to use.
1362 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1364
1365 // thisMBB:
1366 // ...
1367 // TrueVal = ...
1368 // cmpTY ccX, r1, r2
1369 // jCC copy1MBB
1370 // fallthrough --> copy0MBB
1371 MachineBasicBlock *thisMBB = BB;
1372 MachineFunction *F = BB->getParent();
1373 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
1374 MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB);
1375 F->insert(I, copy0MBB);
1376 F->insert(I, copy1MBB);
1377 // Update machine-CFG edges by transferring all successors of the current
1378 // block to the new block which will contain the Phi node for the select.
1379 copy1MBB->splice(copy1MBB->begin(), BB,
1380 std::next(MachineBasicBlock::iterator(MI)), BB->end());
1381 copy1MBB->transferSuccessorsAndUpdatePHIs(BB);
1382 // Next, add the true and fallthrough blocks as its successors.
1383 BB->addSuccessor(copy0MBB);
1384 BB->addSuccessor(copy1MBB);
1385
1386 BuildMI(BB, dl, TII.get(MSP430::JCC))
1387 .addMBB(copy1MBB)
1388 .addImm(MI.getOperand(3).getImm());
1389
1390 // copy0MBB:
1391 // %FalseValue = ...
1392 // # fallthrough to copy1MBB
1393 BB = copy0MBB;
1394
1395 // Update machine-CFG edges
1396 BB->addSuccessor(copy1MBB);
1397
1398 // copy1MBB:
1399 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
1400 // ...
1401 BB = copy1MBB;
1402 BuildMI(*BB, BB->begin(), dl, TII.get(MSP430::PHI), MI.getOperand(0).getReg())
1403 .addReg(MI.getOperand(2).getReg())
1404 .addMBB(copy0MBB)
1405 .addReg(MI.getOperand(1).getReg())
1406 .addMBB(thisMBB);
1407
1408 MI.eraseFromParent(); // The pseudo instruction is gone now.
1409 return BB;
1410}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
static void AnalyzeReturnValues(CCState &State, SmallVectorImpl< CCValAssign > &RVLocs, const SmallVectorImpl< ArgT > &Args)
static void AnalyzeVarArgs(CCState &State, const SmallVectorImpl< ISD::OutputArg > &Outs)
static void AnalyzeRetResult(CCState &State, const SmallVectorImpl< ISD::InputArg > &Ins)
static void ParseFunctionArgs(const SmallVectorImpl< ArgT > &Args, SmallVectorImpl< unsigned > &Out)
For each argument in a function store the number of pieces it is composed of.
static void AnalyzeArguments(CCState &State, SmallVectorImpl< CCValAssign > &ArgLocs, const SmallVectorImpl< ArgT > &Args)
Analyze incoming and outgoing function arguments.
static SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC, ISD::CondCode CC, const SDLoc &dl, SelectionDAG &DAG)
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
Value * RHS
Value * LHS
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
LLVM Basic Block Representation.
Definition BasicBlock.h:62
The address of a basic block.
Definition Constants.h:1088
CCState - This class holds information needed while lowering arguments and return values.
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP, bool IsCustom=false)
int64_t getLocMemOffset() const
A debug info location.
Definition DebugLoc.h:126
bool hasStructRetAttr() const
Determine if the function returns a structure through first or second pointer argument.
Definition Function.h:673
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
This class is used to represent ISD::LOAD nodes.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
MSP430MachineFunctionInfo - This class is derived from MachineFunction and contains private MSP430 ta...
const MSP430RegisterInfo * getRegisterInfo() const override
SDValue getReturnAddressFrameIndex(SelectionDAG &DAG) const
MSP430TargetLowering(const TargetMachine &TM, const MSP430Subtarget &STI)
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
MachineBasicBlock * EmitShiftInstr(MachineInstr &MI, MachineBasicBlock *BB) const
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const
SDValue LowerExternalSymbol(SDValue Op, SelectionDAG &DAG) const
bool isTruncateFree(Type *Ty1, Type *Ty2) const override
isTruncateFree - Return true if it's free to truncate a value of type Ty1 to type Ty2.
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const
SDValue LowerShifts(SDValue Op, SelectionDAG &DAG) const
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const
SDValue LowerSIGN_EXTEND(SDValue Op, SelectionDAG &DAG) const
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *BB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const
SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const
SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const
SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const
bool shouldAvoidTransformToShift(EVT VT, unsigned Amount) const override
Return true if creating a shift of the type by the given amount is not profitable.
bool isZExtFree(Type *Ty1, Type *Ty2) const override
isZExtFree - Return true if any actual instruction that defines a value of type Ty1 implicit zero-ext...
TargetLowering::ConstraintType getConstraintType(StringRef Constraint) const override
getConstraintType - Given a constraint letter, return the type of constraint it is for this target.
bool isLegalICmpImmediate(int64_t) const override
Return true if the specified immediate is legal icmp immediate, that is the target has icmp instructi...
Machine Value Type.
SimpleValueType SimpleTy
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI 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 '...
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
void setFrameAddressIsTaken(bool T)
void setReturnAddressIsTaken(bool s)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI 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:20
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align DstAlign, Align SrcAlign, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
LLVM_ABI SDValue getZeroExtendInReg(SDValue Op, const SDLoc &DL, EVT VT)
Return the expression required to zero extend the Op value assuming it was the smaller SrcTy value.
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
LLVM_ABI SDValue 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 ...
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
MachineFunction & getMachineFunction() const
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
TargetInstrInfo - Interface to description of machine instruction set.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
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 bool isLegalICmpImmediate(int64_t) const
Return true if the specified immediate is legal icmp immediate, that is the target has icmp instructi...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
void setIndexedLoadAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed load does or does not work with the specified type and indicate w...
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
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...
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
TargetLowering(const TargetLowering &)=delete
Primary interface to the complete machine description for the target machine.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition Type.cpp:187
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
LLVM Value Representation.
Definition Value.h:75
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:201
self_iterator getIterator()
Definition ilist_node.h:123
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
CondCodes
Definition MSP430.h:26
@ COND_LO
Definition MSP430.h:30
@ COND_L
Definition MSP430.h:32
@ COND_INVALID
Definition MSP430.h:36
@ COND_E
Definition MSP430.h:27
@ COND_GE
Definition MSP430.h:31
@ COND_NE
Definition MSP430.h:28
@ COND_HS
Definition MSP430.h:29
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ MSP430_BUILTIN
Used for special MSP430 rtlib functions which have an "optimized" convention using additional registe...
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition CallingConv.h:41
@ MSP430_INTR
Used for MSP430 interrupt routines.
@ 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:845
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition ISDOpcodes.h:277
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:805
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:266
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition ISDOpcodes.h:879
@ GlobalAddress
Definition ISDOpcodes.h:90
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition ISDOpcodes.h:282
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:870
@ BR_CC
BR_CC - Conditional branch.
@ BR_JT
BR_JT - Jumptable branch.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:822
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:714
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:787
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:876
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition ISDOpcodes.h:837
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition ISDOpcodes.h:914
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition ISDOpcodes.h:112
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:757
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition ISDOpcodes.h:55
@ ExternalSymbol
Definition ISDOpcodes.h:95
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:882
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
Definition ISDOpcodes.h:859
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition ISDOpcodes.h:64
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define N
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:418
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:339
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
Definition ValueTypes.h:404
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition ValueTypes.h:160
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
SmallVector< ISD::OutputArg, 32 > Outs