LLVM 23.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"
31#include "llvm/Support/Debug.h"
34using namespace llvm;
35
36#define DEBUG_TYPE "msp430-lower"
37
39 "msp430-no-legal-immediate", cl::Hidden,
40 cl::desc("Enable non legal immediates (for testing purposes only)"),
41 cl::init(false));
42
44 const MSP430Subtarget &STI)
45 : TargetLowering(TM, STI) {
46
47 // Set up the register classes.
48 addRegisterClass(MVT::i8, &MSP430::GR8RegClass);
49 addRegisterClass(MVT::i16, &MSP430::GR16RegClass);
50
51 // Compute derived properties from the register classes
53
54 // Provide all sorts of operation actions
57 setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?
58
59 // We have post-incremented loads / stores.
62
63 for (MVT VT : MVT::integer_valuetypes()) {
69 }
70
71 // We don't have any truncstores
72 setTruncStoreAction(MVT::i16, MVT::i8, Expand);
73
102
109
116
118
119 // FIXME: Implement efficiently multiplication by a constant
130
143
144 // varargs support
150
154}
155
157 SelectionDAG &DAG) const {
158 switch (Op.getOpcode()) {
159 case ISD::SHL: // FALLTHROUGH
160 case ISD::SRL:
161 case ISD::SRA: return LowerShifts(Op, DAG);
162 case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
163 case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
164 case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG);
165 case ISD::SETCC: return LowerSETCC(Op, DAG);
166 case ISD::BR_CC: return LowerBR_CC(Op, DAG);
167 case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
168 case ISD::SIGN_EXTEND: return LowerSIGN_EXTEND(Op, DAG);
169 case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
170 case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
171 case ISD::VASTART: return LowerVASTART(Op, DAG);
172 case ISD::JumpTable: return LowerJumpTable(Op, DAG);
173 default:
174 llvm_unreachable("unimplemented operand");
175 }
176}
177
178// Define non profitable transforms into shifts
180 unsigned Amount) const {
181 return !(Amount == 8 || Amount == 9 || Amount<=2);
182}
183
184// Implemented to verify test case assertions in
185// tests/codegen/msp430/shift-amount-threshold-b.ll
188 return Immed >= -32 && Immed < 32;
190}
191
192//===----------------------------------------------------------------------===//
193// MSP430 Inline Assembly Support
194//===----------------------------------------------------------------------===//
195
196/// getConstraintType - Given a constraint letter, return the type of
197/// constraint it is for this target.
200 if (Constraint.size() == 1) {
201 switch (Constraint[0]) {
202 case 'r':
203 return C_RegisterClass;
204 default:
205 break;
206 }
207 }
208 return TargetLowering::getConstraintType(Constraint);
209}
210
211std::pair<unsigned, const TargetRegisterClass *>
213 const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
214 if (Constraint.size() == 1) {
215 // GCC Constraint Letters
216 switch (Constraint[0]) {
217 default: break;
218 case 'r': // GENERAL_REGS
219 if (VT == MVT::i8)
220 return std::make_pair(0U, &MSP430::GR8RegClass);
221
222 return std::make_pair(0U, &MSP430::GR16RegClass);
223 }
224 }
225
227}
228
229//===----------------------------------------------------------------------===//
230// Calling Convention Implementation
231//===----------------------------------------------------------------------===//
232
233#include "MSP430GenCallingConv.inc"
234
235/// For each argument in a function store the number of pieces it is composed
236/// of.
237template<typename ArgT>
240 unsigned CurrentArgIndex;
241
242 if (Args.empty())
243 return;
244
245 CurrentArgIndex = Args[0].OrigArgIndex;
246 Out.push_back(0);
247
248 for (auto &Arg : Args) {
249 if (CurrentArgIndex == Arg.OrigArgIndex) {
250 Out.back() += 1;
251 } else {
252 Out.push_back(1);
253 CurrentArgIndex = Arg.OrigArgIndex;
254 }
255 }
256}
257
258static void AnalyzeVarArgs(CCState &State,
260 State.AnalyzeCallOperands(Outs, CC_MSP430_AssignStack);
261}
262
263static void AnalyzeVarArgs(CCState &State,
265 State.AnalyzeFormalArguments(Ins, CC_MSP430_AssignStack);
266}
267
268/// Analyze incoming and outgoing function arguments. We need custom C++ code
269/// to handle special constraints in the ABI like reversing the order of the
270/// pieces of splitted arguments. In addition, all pieces of a certain argument
271/// have to be passed either using registers or the stack but never mixing both.
272template<typename ArgT>
273static void AnalyzeArguments(CCState &State,
275 const SmallVectorImpl<ArgT> &Args) {
276 static const MCPhysReg CRegList[] = {
277 MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15
278 };
279 static const unsigned CNbRegs = std::size(CRegList);
280 static const MCPhysReg BuiltinRegList[] = {
281 MSP430::R8, MSP430::R9, MSP430::R10, MSP430::R11,
282 MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15
283 };
284 static const unsigned BuiltinNbRegs = std::size(BuiltinRegList);
285
286 ArrayRef<MCPhysReg> RegList;
287 unsigned NbRegs;
288
289 bool Builtin = (State.getCallingConv() == CallingConv::MSP430_BUILTIN);
290 if (Builtin) {
291 RegList = BuiltinRegList;
292 NbRegs = BuiltinNbRegs;
293 } else {
294 RegList = CRegList;
295 NbRegs = CNbRegs;
296 }
297
298 if (State.isVarArg()) {
299 AnalyzeVarArgs(State, Args);
300 return;
301 }
302
303 SmallVector<unsigned, 4> ArgsParts;
304 ParseFunctionArgs(Args, ArgsParts);
305
306 if (Builtin) {
307 assert(ArgsParts.size() == 2 &&
308 "Builtin calling convention requires two arguments");
309 }
310
311 unsigned RegsLeft = NbRegs;
312 bool UsedStack = false;
313 unsigned ValNo = 0;
314
315 for (unsigned i = 0, e = ArgsParts.size(); i != e; i++) {
316 MVT ArgVT = Args[ValNo].VT;
317 ISD::ArgFlagsTy ArgFlags = Args[ValNo].Flags;
318 Type *OrigTy = Args[ValNo].OrigTy;
319 MVT LocVT = ArgVT;
321
322 // Promote i8 to i16
323 if (LocVT == MVT::i8) {
324 LocVT = MVT::i16;
325 if (ArgFlags.isSExt())
326 LocInfo = CCValAssign::SExt;
327 else if (ArgFlags.isZExt())
328 LocInfo = CCValAssign::ZExt;
329 else
330 LocInfo = CCValAssign::AExt;
331 }
332
333 // Handle byval arguments
334 if (ArgFlags.isByVal()) {
335 State.HandleByVal(ValNo++, ArgVT, LocVT, LocInfo, 2, Align(2), ArgFlags);
336 continue;
337 }
338
339 unsigned Parts = ArgsParts[i];
340
341 if (Builtin) {
342 assert(Parts == 4 &&
343 "Builtin calling convention requires 64-bit arguments");
344 }
345
346 if (!UsedStack && Parts == 2 && RegsLeft == 1) {
347 // Special case for 32-bit register split, see EABI section 3.3.3
348 MCRegister Reg = State.AllocateReg(RegList);
349 State.addLoc(CCValAssign::getReg(ValNo++, ArgVT, Reg, LocVT, LocInfo));
350 RegsLeft -= 1;
351
352 UsedStack = true;
353 CC_MSP430_AssignStack(ValNo++, ArgVT, LocVT, LocInfo, ArgFlags, OrigTy,
354 State);
355 } else if (Parts <= RegsLeft) {
356 for (unsigned j = 0; j < Parts; j++) {
357 MCRegister Reg = State.AllocateReg(RegList);
358 State.addLoc(CCValAssign::getReg(ValNo++, ArgVT, Reg, LocVT, LocInfo));
359 RegsLeft--;
360 }
361 } else {
362 UsedStack = true;
363 for (unsigned j = 0; j < Parts; j++)
364 CC_MSP430_AssignStack(ValNo++, ArgVT, LocVT, LocInfo, ArgFlags, OrigTy,
365 State);
366 }
367 }
368}
369
370static void AnalyzeRetResult(CCState &State,
372 State.AnalyzeCallResult(Ins, RetCC_MSP430);
373}
374
375static void AnalyzeRetResult(CCState &State,
377 State.AnalyzeReturn(Outs, RetCC_MSP430);
378}
379
380template<typename ArgT>
381static void AnalyzeReturnValues(CCState &State,
383 const SmallVectorImpl<ArgT> &Args) {
384 AnalyzeRetResult(State, Args);
385}
386
387SDValue MSP430TargetLowering::LowerFormalArguments(
388 SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
389 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
390 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
391
392 switch (CallConv) {
393 default:
394 report_fatal_error("Unsupported calling convention");
395 case CallingConv::C:
397 return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals);
399 if (Ins.empty())
400 return Chain;
401 report_fatal_error("ISRs cannot have arguments");
402 }
403}
404
406MSP430TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
407 SmallVectorImpl<SDValue> &InVals) const {
408 SelectionDAG &DAG = CLI.DAG;
409 SDLoc &dl = CLI.DL;
410 SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
411 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
412 SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
413 SDValue Chain = CLI.Chain;
414 SDValue Callee = CLI.Callee;
415 bool &isTailCall = CLI.IsTailCall;
416 CallingConv::ID CallConv = CLI.CallConv;
417 bool isVarArg = CLI.IsVarArg;
418
419 // MSP430 target does not yet support tail call optimization.
420 isTailCall = false;
421
422 switch (CallConv) {
423 default:
424 report_fatal_error("Unsupported calling convention");
427 case CallingConv::C:
428 return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
429 Outs, OutVals, Ins, dl, DAG, InVals);
431 report_fatal_error("ISRs cannot be called directly");
432 }
433}
434
435/// LowerCCCArguments - transform physical registers into virtual registers and
436/// generate load operations for arguments places on the stack.
437// FIXME: struct return stuff
438SDValue MSP430TargetLowering::LowerCCCArguments(
439 SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
440 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
441 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
442 MachineFunction &MF = DAG.getMachineFunction();
443 MachineFrameInfo &MFI = MF.getFrameInfo();
444 MachineRegisterInfo &RegInfo = MF.getRegInfo();
445 MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
446
447 // Assign locations to all of the incoming arguments.
449 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
450 *DAG.getContext());
451 AnalyzeArguments(CCInfo, ArgLocs, Ins);
452
453 // Create frame index for the start of the first vararg value
454 if (isVarArg) {
455 unsigned Offset = CCInfo.getStackSize();
456 FuncInfo->setVarArgsFrameIndex(MFI.CreateFixedObject(1, Offset, true));
457 }
458
459 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
460 CCValAssign &VA = ArgLocs[i];
461 if (VA.isRegLoc()) {
462 // Arguments passed in registers
463 EVT RegVT = VA.getLocVT();
464 switch (RegVT.getSimpleVT().SimpleTy) {
465 default:
466 {
467#ifndef NDEBUG
468 errs() << "LowerFormalArguments Unhandled argument type: "
469 << RegVT << "\n";
470#endif
471 llvm_unreachable(nullptr);
472 }
473 case MVT::i16:
474 Register VReg = RegInfo.createVirtualRegister(&MSP430::GR16RegClass);
475 RegInfo.addLiveIn(VA.getLocReg(), VReg);
476 SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, RegVT);
477
478 // If this is an 8-bit value, it is really passed promoted to 16
479 // bits. Insert an assert[sz]ext to capture this, then truncate to the
480 // right size.
481 if (VA.getLocInfo() == CCValAssign::SExt)
482 ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue,
483 DAG.getValueType(VA.getValVT()));
484 else if (VA.getLocInfo() == CCValAssign::ZExt)
485 ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue,
486 DAG.getValueType(VA.getValVT()));
487
488 if (VA.getLocInfo() != CCValAssign::Full)
489 ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
490
491 InVals.push_back(ArgValue);
492 }
493 } else {
494 // Only arguments passed on the stack should make it here.
495 assert(VA.isMemLoc());
496
497 SDValue InVal;
498 ISD::ArgFlagsTy Flags = Ins[i].Flags;
499
500 if (Flags.isByVal()) {
501 MVT PtrVT = VA.getLocVT();
502 int FI = MFI.CreateFixedObject(Flags.getByValSize(),
503 VA.getLocMemOffset(), true);
504 InVal = DAG.getFrameIndex(FI, PtrVT);
505 } else {
506 // Load the argument to a virtual register
507 unsigned ObjSize = VA.getLocVT().getSizeInBits()/8;
508 if (ObjSize > 2) {
509 errs() << "LowerFormalArguments Unhandled argument type: "
510 << VA.getLocVT() << "\n";
511 }
512 // Create the frame index object for this incoming parameter...
513 int FI = MFI.CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);
514
515 // Create the SelectionDAG nodes corresponding to a load
516 //from this parameter
517 SDValue FIN = DAG.getFrameIndex(FI, MVT::i16);
518 InVal = DAG.getLoad(
519 VA.getLocVT(), dl, Chain, FIN,
521 }
522
523 InVals.push_back(InVal);
524 }
525 }
526
527 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
528 if (Ins[i].Flags.isSRet()) {
529 Register Reg = FuncInfo->getSRetReturnReg();
530 if (!Reg) {
532 getRegClassFor(MVT::i16));
533 FuncInfo->setSRetReturnReg(Reg);
534 }
535 SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, InVals[i]);
536 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain);
537 }
538 }
539
540 return Chain;
541}
542
543bool
544MSP430TargetLowering::CanLowerReturn(CallingConv::ID CallConv,
545 MachineFunction &MF,
546 bool IsVarArg,
549 const Type *RetTy) const {
551 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
552 return CCInfo.CheckReturn(Outs, RetCC_MSP430);
553}
554
556MSP430TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
557 bool isVarArg,
559 const SmallVectorImpl<SDValue> &OutVals,
560 const SDLoc &dl, SelectionDAG &DAG) const {
561
562 MachineFunction &MF = DAG.getMachineFunction();
563
564 // CCValAssign - represent the assignment of the return value to a location
566
567 // ISRs cannot return any value.
568 if (CallConv == CallingConv::MSP430_INTR && !Outs.empty())
569 report_fatal_error("ISRs cannot return any value");
570
571 // CCState - Info about the registers and stack slot.
572 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
573 *DAG.getContext());
574
575 // Analize return values.
576 AnalyzeReturnValues(CCInfo, RVLocs, Outs);
577
578 SDValue Glue;
579 SmallVector<SDValue, 4> RetOps(1, Chain);
580
581 // Copy the result values into the output registers.
582 for (unsigned i = 0; i != RVLocs.size(); ++i) {
583 CCValAssign &VA = RVLocs[i];
584 assert(VA.isRegLoc() && "Can only return in registers!");
585
586 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
587 OutVals[i], Glue);
588
589 // Guarantee that all emitted copies are stuck together,
590 // avoiding something bad.
591 Glue = Chain.getValue(1);
592 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
593 }
594
595 if (MF.getFunction().hasStructRetAttr()) {
596 MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
597 Register Reg = FuncInfo->getSRetReturnReg();
598
599 if (!Reg)
600 llvm_unreachable("sret virtual register not created in entry block");
601
602 MVT PtrVT = getFrameIndexTy(DAG.getDataLayout());
603 SDValue Val =
604 DAG.getCopyFromReg(Chain, dl, Reg, PtrVT);
605 unsigned R12 = MSP430::R12;
606
607 Chain = DAG.getCopyToReg(Chain, dl, R12, Val, Glue);
608 Glue = Chain.getValue(1);
609 RetOps.push_back(DAG.getRegister(R12, PtrVT));
610 }
611
612 unsigned Opc = (CallConv == CallingConv::MSP430_INTR ?
613 MSP430ISD::RETI_GLUE : MSP430ISD::RET_GLUE);
614
615 RetOps[0] = Chain; // Update chain.
616
617 // Add the glue if we have it.
618 if (Glue.getNode())
619 RetOps.push_back(Glue);
620
621 return DAG.getNode(Opc, dl, MVT::Other, RetOps);
622}
623
624/// LowerCCCCallTo - functions arguments are copied from virtual regs to
625/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
626SDValue MSP430TargetLowering::LowerCCCCallTo(
627 SDValue Chain, SDValue Callee, CallingConv::ID CallConv, bool isVarArg,
628 bool isTailCall, const SmallVectorImpl<ISD::OutputArg> &Outs,
629 const SmallVectorImpl<SDValue> &OutVals,
630 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
631 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
632 // Analyze operands of the call, assigning locations to each operand.
634 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
635 *DAG.getContext());
636 AnalyzeArguments(CCInfo, ArgLocs, Outs);
637
638 // Get a count of how many bytes are to be pushed on the stack.
639 unsigned NumBytes = CCInfo.getStackSize();
640 MVT PtrVT = getFrameIndexTy(DAG.getDataLayout());
641
642 Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, dl);
643
645 SmallVector<SDValue, 12> MemOpChains;
647
648 // Walk the register/memloc assignments, inserting copies/loads.
649 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
650 CCValAssign &VA = ArgLocs[i];
651
652 SDValue Arg = OutVals[i];
653
654 // Promote the value if needed.
655 switch (VA.getLocInfo()) {
656 default: llvm_unreachable("Unknown loc info!");
657 case CCValAssign::Full: break;
659 Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
660 break;
662 Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
663 break;
665 Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
666 break;
667 }
668
669 // Arguments that can be passed on register must be kept at RegsToPass
670 // vector
671 if (VA.isRegLoc()) {
672 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
673 } else {
674 assert(VA.isMemLoc());
675
676 if (!StackPtr.getNode())
677 StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SP, PtrVT);
678
679 SDValue PtrOff =
680 DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr,
681 DAG.getIntPtrConstant(VA.getLocMemOffset(), dl));
682
683 SDValue MemOp;
684 ISD::ArgFlagsTy Flags = Outs[i].Flags;
685
686 if (Flags.isByVal()) {
687 SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), dl, MVT::i16);
688 MemOp = DAG.getMemcpy(Chain, dl, PtrOff, Arg, SizeNode,
689 Flags.getNonZeroByValAlign(),
690 /*isVolatile*/ false,
691 /*AlwaysInline=*/true,
692 /*CI=*/nullptr, std::nullopt,
693 MachinePointerInfo(), MachinePointerInfo());
694 } else {
695 MemOp = DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
696 }
697
698 MemOpChains.push_back(MemOp);
699 }
700 }
701
702 // Transform all store nodes into one single node because all store nodes are
703 // independent of each other.
704 if (!MemOpChains.empty())
705 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
706
707 // Build a sequence of copy-to-reg nodes chained together with token chain and
708 // flag operands which copy the outgoing args into registers. The InGlue in
709 // necessary since all emitted instructions must be stuck together.
710 SDValue InGlue;
711 for (const auto &[Reg, N] : RegsToPass) {
712 Chain = DAG.getCopyToReg(Chain, dl, Reg, N, InGlue);
713 InGlue = Chain.getValue(1);
714 }
715
716 // If the callee is a GlobalAddress node (quite common, every direct call is)
717 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
718 // Likewise ExternalSymbol -> TargetExternalSymbol.
719 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
720 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i16);
721 else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
722 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i16);
723
724 // Returns a chain & a flag for retval copy to use.
725 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
727 Ops.push_back(Chain);
728 Ops.push_back(Callee);
729
730 // Add argument registers to the end of the list so that they are
731 // known live into the call.
732 for (const auto &[Reg, N] : RegsToPass)
733 Ops.push_back(DAG.getRegister(Reg, N.getValueType()));
734
735 if (InGlue.getNode())
736 Ops.push_back(InGlue);
737
738 Chain = DAG.getNode(MSP430ISD::CALL, dl, NodeTys, Ops);
739 InGlue = Chain.getValue(1);
740
741 // Create the CALLSEQ_END node.
742 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, InGlue, dl);
743 InGlue = Chain.getValue(1);
744
745 // Handle result values, copying them out of physregs into vregs that we
746 // return.
747 return LowerCallResult(Chain, InGlue, CallConv, isVarArg, Ins, dl,
748 DAG, InVals);
749}
750
751/// LowerCallResult - Lower the result values of a call into the
752/// appropriate copies out of appropriate physical registers.
753///
754SDValue MSP430TargetLowering::LowerCallResult(
755 SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool isVarArg,
756 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
757 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
758
759 // Assign locations to each value returned by this call.
761 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
762 *DAG.getContext());
763
764 AnalyzeReturnValues(CCInfo, RVLocs, Ins);
765
766 // Copy all of the result registers out of their specified physreg.
767 for (unsigned i = 0; i != RVLocs.size(); ++i) {
768 Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(),
769 RVLocs[i].getValVT(), InGlue).getValue(1);
770 InGlue = Chain.getValue(2);
771 InVals.push_back(Chain.getValue(0));
772 }
773
774 return Chain;
775}
776
778 SelectionDAG &DAG) const {
779 unsigned Opc = Op.getOpcode();
780 SDNode* N = Op.getNode();
781 EVT VT = Op.getValueType();
782 SDLoc dl(N);
783
784 // Expand non-constant shifts to loops:
785 if (!isa<ConstantSDNode>(N->getOperand(1)))
786 return Op;
787
788 uint64_t ShiftAmount = N->getConstantOperandVal(1);
789
790 // Expand the stuff into sequence of shifts.
791 SDValue Victim = N->getOperand(0);
792
793 if (ShiftAmount >= 8) {
794 assert(VT == MVT::i16 && "Can not shift i8 by 8 and more");
795 switch(Opc) {
796 default:
797 llvm_unreachable("Unknown shift");
798 case ISD::SHL:
799 // foo << (8 + N) => swpb(zext(foo)) << N
800 Victim = DAG.getZeroExtendInReg(Victim, dl, MVT::i8);
801 Victim = DAG.getNode(ISD::BSWAP, dl, VT, Victim);
802 break;
803 case ISD::SRA:
804 case ISD::SRL:
805 // foo >> (8 + N) => sxt(swpb(foo)) >> N
806 Victim = DAG.getNode(ISD::BSWAP, dl, VT, Victim);
807 Victim = (Opc == ISD::SRA)
808 ? DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT, Victim,
809 DAG.getValueType(MVT::i8))
810 : DAG.getZeroExtendInReg(Victim, dl, MVT::i8);
811 break;
812 }
813 ShiftAmount -= 8;
814 }
815
816 if (Opc == ISD::SRL && ShiftAmount) {
817 // Emit a special goodness here:
818 // srl A, 1 => clrc; rrc A
819 Victim = DAG.getNode(MSP430ISD::RRCL, dl, VT, Victim);
820 ShiftAmount -= 1;
821 }
822
823 while (ShiftAmount--)
824 Victim = DAG.getNode((Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA),
825 dl, VT, Victim);
826
827 return Victim;
828}
829
831 SelectionDAG &DAG) const {
832 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
833 int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();
834 EVT PtrVT = Op.getValueType();
835
836 // Create the TargetGlobalAddress node, folding in the constant offset.
837 SDValue Result = DAG.getTargetGlobalAddress(GV, SDLoc(Op), PtrVT, Offset);
838 return DAG.getNode(MSP430ISD::Wrapper, SDLoc(Op), PtrVT, Result);
839}
840
842 SelectionDAG &DAG) const {
843 SDLoc dl(Op);
844 const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol();
845 EVT PtrVT = Op.getValueType();
846 SDValue Result = DAG.getTargetExternalSymbol(Sym, PtrVT);
847
848 return DAG.getNode(MSP430ISD::Wrapper, dl, PtrVT, Result);
849}
850
852 SelectionDAG &DAG) const {
853 SDLoc dl(Op);
854 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
855 EVT PtrVT = Op.getValueType();
856 SDValue Result = DAG.getTargetBlockAddress(BA, PtrVT);
857
858 return DAG.getNode(MSP430ISD::Wrapper, dl, PtrVT, Result);
859}
860
862 ISD::CondCode CC, const SDLoc &dl, SelectionDAG &DAG) {
863 // FIXME: Handle bittests someday
864 assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet");
865
866 // FIXME: Handle jump negative someday
868 switch (CC) {
869 default: llvm_unreachable("Invalid integer condition!");
870 case ISD::SETEQ:
871 TCC = MSP430CC::COND_E; // aka COND_Z
872 // Minor optimization: if LHS is a constant, swap operands, then the
873 // constant can be folded into comparison.
874 if (LHS.getOpcode() == ISD::Constant)
875 std::swap(LHS, RHS);
876 break;
877 case ISD::SETNE:
878 TCC = MSP430CC::COND_NE; // aka COND_NZ
879 // Minor optimization: if LHS is a constant, swap operands, then the
880 // constant can be folded into comparison.
881 if (LHS.getOpcode() == ISD::Constant)
882 std::swap(LHS, RHS);
883 break;
884 case ISD::SETULE:
885 std::swap(LHS, RHS);
886 [[fallthrough]];
887 case ISD::SETUGE:
888 // Turn lhs u>= rhs with lhs constant into rhs u< lhs+1, this allows us to
889 // fold constant into instruction.
891 LHS = RHS;
892 RHS =
893 DAG.getSignedConstant(C->getSExtValue() + 1, dl, C->getValueType(0));
894 TCC = MSP430CC::COND_LO;
895 break;
896 }
897 TCC = MSP430CC::COND_HS; // aka COND_C
898 break;
899 case ISD::SETUGT:
900 std::swap(LHS, RHS);
901 [[fallthrough]];
902 case ISD::SETULT:
903 // Turn lhs u< rhs with lhs constant into rhs u>= lhs+1, this allows us to
904 // fold constant into instruction.
906 LHS = RHS;
907 RHS =
908 DAG.getSignedConstant(C->getSExtValue() + 1, dl, C->getValueType(0));
909 TCC = MSP430CC::COND_HS;
910 break;
911 }
912 TCC = MSP430CC::COND_LO; // aka COND_NC
913 break;
914 case ISD::SETLE:
915 std::swap(LHS, RHS);
916 [[fallthrough]];
917 case ISD::SETGE:
918 // Turn lhs >= rhs with lhs constant into rhs < lhs+1, this allows us to
919 // fold constant into instruction.
921 LHS = RHS;
922 RHS =
923 DAG.getSignedConstant(C->getSExtValue() + 1, dl, C->getValueType(0));
924 TCC = MSP430CC::COND_L;
925 break;
926 }
927 TCC = MSP430CC::COND_GE;
928 break;
929 case ISD::SETGT:
930 std::swap(LHS, RHS);
931 [[fallthrough]];
932 case ISD::SETLT:
933 // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to
934 // fold constant into instruction.
936 LHS = RHS;
937 RHS =
938 DAG.getSignedConstant(C->getSExtValue() + 1, dl, C->getValueType(0));
939 TCC = MSP430CC::COND_GE;
940 break;
941 }
942 TCC = MSP430CC::COND_L;
943 break;
944 }
945
946 TargetCC = DAG.getConstant(TCC, dl, MVT::i8);
947 return DAG.getNode(MSP430ISD::CMP, dl, MVT::Glue, LHS, RHS);
948}
949
950
952 SDValue Chain = Op.getOperand(0);
953 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
954 SDValue LHS = Op.getOperand(2);
955 SDValue RHS = Op.getOperand(3);
956 SDValue Dest = Op.getOperand(4);
957 SDLoc dl (Op);
958
959 SDValue TargetCC;
960 SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
961
962 return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(),
963 Chain, Dest, TargetCC, Flag);
964}
965
967 SDValue LHS = Op.getOperand(0);
968 SDValue RHS = Op.getOperand(1);
969 SDLoc dl (Op);
970
971 // If we are doing an AND and testing against zero, then the CMP
972 // will not be generated. The AND (or BIT) will generate the condition codes,
973 // but they are different from CMP.
974 // FIXME: since we're doing a post-processing, use a pseudoinstr here, so
975 // lowering & isel wouldn't diverge.
976 bool andCC = isNullConstant(RHS) && LHS.hasOneUse() &&
977 (LHS.getOpcode() == ISD::AND ||
978 (LHS.getOpcode() == ISD::TRUNCATE &&
979 LHS.getOperand(0).getOpcode() == ISD::AND));
980 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
981 SDValue TargetCC;
982 SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
983
984 // Get the condition codes directly from the status register, if its easy.
985 // Otherwise a branch will be generated. Note that the AND and BIT
986 // instructions generate different flags than CMP, the carry bit can be used
987 // for NE/EQ.
988 bool Invert = false;
989 bool Shift = false;
990 bool Convert = true;
991 switch (TargetCC->getAsZExtVal()) {
992 default:
993 Convert = false;
994 break;
996 // Res = SR & 1, no processing is required
997 break;
999 // Res = ~(SR & 1)
1000 Invert = true;
1001 break;
1002 case MSP430CC::COND_NE:
1003 if (andCC) {
1004 // C = ~Z, thus Res = SR & 1, no processing is required
1005 } else {
1006 // Res = ~((SR >> 1) & 1)
1007 Shift = true;
1008 Invert = true;
1009 }
1010 break;
1011 case MSP430CC::COND_E:
1012 Shift = true;
1013 // C = ~Z for AND instruction, thus we can put Res = ~(SR & 1), however,
1014 // Res = (SR >> 1) & 1 is 1 word shorter.
1015 break;
1016 }
1017 EVT VT = Op.getValueType();
1018 SDValue One = DAG.getConstant(1, dl, VT);
1019 if (Convert) {
1020 SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SR,
1021 MVT::i16, Flag);
1022 if (Shift)
1023 // FIXME: somewhere this is turned into a SRL, lower it MSP specific?
1024 SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One);
1025 SR = DAG.getNode(ISD::AND, dl, MVT::i16, SR, One);
1026 if (Invert)
1027 SR = DAG.getNode(ISD::XOR, dl, MVT::i16, SR, One);
1028 return SR;
1029 } else {
1030 SDValue Zero = DAG.getConstant(0, dl, VT);
1031 SDValue Ops[] = {One, Zero, TargetCC, Flag};
1032 return DAG.getNode(MSP430ISD::SELECT_CC, dl, Op.getValueType(), Ops);
1033 }
1034}
1035
1037 SelectionDAG &DAG) const {
1038 SDValue LHS = Op.getOperand(0);
1039 SDValue RHS = Op.getOperand(1);
1040 SDValue TrueV = Op.getOperand(2);
1041 SDValue FalseV = Op.getOperand(3);
1042 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
1043 SDLoc dl (Op);
1044
1045 SDValue TargetCC;
1046 SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
1047
1048 SDValue Ops[] = {TrueV, FalseV, TargetCC, Flag};
1049
1050 return DAG.getNode(MSP430ISD::SELECT_CC, dl, Op.getValueType(), Ops);
1051}
1052
1054 SelectionDAG &DAG) const {
1055 SDValue Val = Op.getOperand(0);
1056 EVT VT = Op.getValueType();
1057 SDLoc dl(Op);
1058
1059 assert(VT == MVT::i16 && "Only support i16 for now!");
1060
1061 return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT,
1062 DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val),
1063 DAG.getValueType(Val.getValueType()));
1064}
1065
1066SDValue
1070 int ReturnAddrIndex = FuncInfo->getRAIndex();
1071 MVT PtrVT = getFrameIndexTy(MF.getDataLayout());
1072
1073 if (ReturnAddrIndex == 0) {
1074 // Set up a frame object for the return address.
1075 uint64_t SlotSize = PtrVT.getStoreSize();
1076 ReturnAddrIndex = MF.getFrameInfo().CreateFixedObject(SlotSize, -SlotSize,
1077 true);
1078 FuncInfo->setRAIndex(ReturnAddrIndex);
1079 }
1080
1081 return DAG.getFrameIndex(ReturnAddrIndex, PtrVT);
1082}
1083
1085 SelectionDAG &DAG) const {
1087 MFI.setReturnAddressIsTaken(true);
1088
1089 unsigned Depth = Op.getConstantOperandVal(0);
1090 SDLoc dl(Op);
1091 EVT PtrVT = Op.getValueType();
1092
1093 if (Depth > 0) {
1094 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
1095 SDValue Offset =
1096 DAG.getConstant(PtrVT.getStoreSize(), dl, MVT::i16);
1097 return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(),
1098 DAG.getNode(ISD::ADD, dl, PtrVT, FrameAddr, Offset),
1100 }
1101
1102 // Just load the return address.
1103 SDValue RetAddrFI = getReturnAddressFrameIndex(DAG);
1104 return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), RetAddrFI,
1106}
1107
1109 SelectionDAG &DAG) const {
1111 MFI.setFrameAddressIsTaken(true);
1112
1113 EVT VT = Op.getValueType();
1114 SDLoc dl(Op); // FIXME probably not meaningful
1115 unsigned Depth = Op.getConstantOperandVal(0);
1116 SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl,
1117 MSP430::R4, VT);
1118 while (Depth--)
1119 FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
1121 return FrameAddr;
1122}
1123
1125 SelectionDAG &DAG) const {
1128
1129 SDValue Ptr = Op.getOperand(1);
1130 EVT PtrVT = Ptr.getValueType();
1131
1132 // Frame index of first vararg argument
1133 SDValue FrameIndex =
1134 DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);
1135 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
1136
1137 // Create a store of the frame index to the location operand
1138 return DAG.getStore(Op.getOperand(0), SDLoc(Op), FrameIndex, Ptr,
1139 MachinePointerInfo(SV));
1140}
1141
1143 SelectionDAG &DAG) const {
1145 EVT PtrVT = Op.getValueType();
1146 SDValue Result = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
1147 return DAG.getNode(MSP430ISD::Wrapper, SDLoc(JT), PtrVT, Result);
1148}
1149
1150/// getPostIndexedAddressParts - returns true by value, base pointer and
1151/// offset pointer and addressing mode by reference if this node can be
1152/// combined with a load / store to form a post-indexed load / store.
1153bool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
1154 SDValue &Base,
1155 SDValue &Offset,
1157 SelectionDAG &DAG) const {
1158
1160 if (LD->getExtensionType() != ISD::NON_EXTLOAD)
1161 return false;
1162
1163 EVT VT = LD->getMemoryVT();
1164 if (VT != MVT::i8 && VT != MVT::i16)
1165 return false;
1166
1167 if (Op->getOpcode() != ISD::ADD)
1168 return false;
1169
1170 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) {
1171 uint64_t RHSC = RHS->getZExtValue();
1172 if ((VT == MVT::i16 && RHSC != 2) ||
1173 (VT == MVT::i8 && RHSC != 1))
1174 return false;
1175
1176 Base = Op->getOperand(0);
1177 Offset = DAG.getConstant(RHSC, SDLoc(N), VT);
1178 AM = ISD::POST_INC;
1179 return true;
1180 }
1181
1182 return false;
1183}
1184
1186 Type *Ty2) const {
1187 if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
1188 return false;
1189
1190 return (Ty1->getPrimitiveSizeInBits().getFixedValue() >
1192}
1193
1195 if (!VT1.isInteger() || !VT2.isInteger())
1196 return false;
1197
1198 return (VT1.getFixedSizeInBits() > VT2.getFixedSizeInBits());
1199}
1200
1202 // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
1203 return false && Ty1->isIntegerTy(8) && Ty2->isIntegerTy(16);
1204}
1205
1207 // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
1208 return false && VT1 == MVT::i8 && VT2 == MVT::i16;
1209}
1210
1211//===----------------------------------------------------------------------===//
1212// Other Lowering Code
1213//===----------------------------------------------------------------------===//
1214
1217 MachineBasicBlock *BB) const {
1218 MachineFunction *F = BB->getParent();
1219 MachineRegisterInfo &RI = F->getRegInfo();
1220 DebugLoc dl = MI.getDebugLoc();
1221 const TargetInstrInfo &TII = *F->getSubtarget().getInstrInfo();
1222
1223 unsigned Opc;
1224 bool ClearCarry = false;
1225 const TargetRegisterClass * RC;
1226 switch (MI.getOpcode()) {
1227 default: llvm_unreachable("Invalid shift opcode!");
1228 case MSP430::Shl8:
1229 Opc = MSP430::ADD8rr;
1230 RC = &MSP430::GR8RegClass;
1231 break;
1232 case MSP430::Shl16:
1233 Opc = MSP430::ADD16rr;
1234 RC = &MSP430::GR16RegClass;
1235 break;
1236 case MSP430::Sra8:
1237 Opc = MSP430::RRA8r;
1238 RC = &MSP430::GR8RegClass;
1239 break;
1240 case MSP430::Sra16:
1241 Opc = MSP430::RRA16r;
1242 RC = &MSP430::GR16RegClass;
1243 break;
1244 case MSP430::Srl8:
1245 ClearCarry = true;
1246 Opc = MSP430::RRC8r;
1247 RC = &MSP430::GR8RegClass;
1248 break;
1249 case MSP430::Srl16:
1250 ClearCarry = true;
1251 Opc = MSP430::RRC16r;
1252 RC = &MSP430::GR16RegClass;
1253 break;
1254 case MSP430::Rrcl8:
1255 case MSP430::Rrcl16: {
1256 BuildMI(*BB, MI, dl, TII.get(MSP430::BIC16rc), MSP430::SR)
1257 .addReg(MSP430::SR).addImm(1);
1258 Register SrcReg = MI.getOperand(1).getReg();
1259 Register DstReg = MI.getOperand(0).getReg();
1260 unsigned RrcOpc = MI.getOpcode() == MSP430::Rrcl16
1261 ? MSP430::RRC16r : MSP430::RRC8r;
1262 BuildMI(*BB, MI, dl, TII.get(RrcOpc), DstReg)
1263 .addReg(SrcReg);
1264 MI.eraseFromParent(); // The pseudo instruction is gone now.
1265 return BB;
1266 }
1267 }
1268
1269 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1271
1272 // Create loop block
1273 MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB);
1274 MachineBasicBlock *RemBB = F->CreateMachineBasicBlock(LLVM_BB);
1275
1276 F->insert(I, LoopBB);
1277 F->insert(I, RemBB);
1278
1279 // Update machine-CFG edges by transferring all successors of the current
1280 // block to the block containing instructions after shift.
1281 RemBB->splice(RemBB->begin(), BB, std::next(MachineBasicBlock::iterator(MI)),
1282 BB->end());
1284
1285 // Add edges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB
1286 BB->addSuccessor(LoopBB);
1287 BB->addSuccessor(RemBB);
1288 LoopBB->addSuccessor(RemBB);
1289 LoopBB->addSuccessor(LoopBB);
1290
1291 Register ShiftAmtReg = RI.createVirtualRegister(&MSP430::GR8RegClass);
1292 Register ShiftAmtReg2 = RI.createVirtualRegister(&MSP430::GR8RegClass);
1293 Register ShiftReg = RI.createVirtualRegister(RC);
1294 Register ShiftReg2 = RI.createVirtualRegister(RC);
1295 Register ShiftAmtSrcReg = MI.getOperand(2).getReg();
1296 Register SrcReg = MI.getOperand(1).getReg();
1297 Register DstReg = MI.getOperand(0).getReg();
1298
1299 // BB:
1300 // cmp 0, N
1301 // je RemBB
1302 BuildMI(BB, dl, TII.get(MSP430::CMP8ri))
1303 .addReg(ShiftAmtSrcReg).addImm(0);
1304 BuildMI(BB, dl, TII.get(MSP430::JCC))
1305 .addMBB(RemBB)
1307
1308 // LoopBB:
1309 // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB]
1310 // ShiftAmt = phi [%N, BB], [%ShiftAmt2, LoopBB]
1311 // ShiftReg2 = shift ShiftReg
1312 // ShiftAmt2 = ShiftAmt - 1;
1313 BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftReg)
1314 .addReg(SrcReg).addMBB(BB)
1315 .addReg(ShiftReg2).addMBB(LoopBB);
1316 BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg)
1317 .addReg(ShiftAmtSrcReg).addMBB(BB)
1318 .addReg(ShiftAmtReg2).addMBB(LoopBB);
1319 if (ClearCarry)
1320 BuildMI(LoopBB, dl, TII.get(MSP430::BIC16rc), MSP430::SR)
1321 .addReg(MSP430::SR).addImm(1);
1322 if (Opc == MSP430::ADD8rr || Opc == MSP430::ADD16rr)
1323 BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2)
1324 .addReg(ShiftReg)
1325 .addReg(ShiftReg);
1326 else
1327 BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2)
1328 .addReg(ShiftReg);
1329 BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2)
1330 .addReg(ShiftAmtReg).addImm(1);
1331 BuildMI(LoopBB, dl, TII.get(MSP430::JCC))
1332 .addMBB(LoopBB)
1334
1335 // RemBB:
1336 // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB]
1337 BuildMI(*RemBB, RemBB->begin(), dl, TII.get(MSP430::PHI), DstReg)
1338 .addReg(SrcReg).addMBB(BB)
1339 .addReg(ShiftReg2).addMBB(LoopBB);
1340
1341 MI.eraseFromParent(); // The pseudo instruction is gone now.
1342 return RemBB;
1343}
1344
1347 MachineBasicBlock *BB) const {
1348 unsigned Opc = MI.getOpcode();
1349
1350 if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 ||
1351 Opc == MSP430::Sra8 || Opc == MSP430::Sra16 ||
1352 Opc == MSP430::Srl8 || Opc == MSP430::Srl16 ||
1353 Opc == MSP430::Rrcl8 || Opc == MSP430::Rrcl16)
1354 return EmitShiftInstr(MI, BB);
1355
1357 DebugLoc dl = MI.getDebugLoc();
1358
1359 assert((Opc == MSP430::Select16 || Opc == MSP430::Select8) &&
1360 "Unexpected instr type to insert");
1361
1362 // To "insert" a SELECT instruction, we actually have to insert the diamond
1363 // control-flow pattern. The incoming instruction knows the destination vreg
1364 // to set, the condition code register to branch on, the true/false values to
1365 // select between, and a branch opcode to use.
1366 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1368
1369 // thisMBB:
1370 // ...
1371 // TrueVal = ...
1372 // cmpTY ccX, r1, r2
1373 // jCC copy1MBB
1374 // fallthrough --> copy0MBB
1375 MachineBasicBlock *thisMBB = BB;
1376 MachineFunction *F = BB->getParent();
1377 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
1378 MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB);
1379 F->insert(I, copy0MBB);
1380 F->insert(I, copy1MBB);
1381 // Update machine-CFG edges by transferring all successors of the current
1382 // block to the new block which will contain the Phi node for the select.
1383 copy1MBB->splice(copy1MBB->begin(), BB,
1384 std::next(MachineBasicBlock::iterator(MI)), BB->end());
1385 copy1MBB->transferSuccessorsAndUpdatePHIs(BB);
1386 // Next, add the true and fallthrough blocks as its successors.
1387 BB->addSuccessor(copy0MBB);
1388 BB->addSuccessor(copy1MBB);
1389
1390 BuildMI(BB, dl, TII.get(MSP430::JCC))
1391 .addMBB(copy1MBB)
1392 .addImm(MI.getOperand(3).getImm());
1393
1394 // copy0MBB:
1395 // %FalseValue = ...
1396 // # fallthrough to copy1MBB
1397 BB = copy0MBB;
1398
1399 // Update machine-CFG edges
1400 BB->addSuccessor(copy1MBB);
1401
1402 // copy1MBB:
1403 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
1404 // ...
1405 BB = copy1MBB;
1406 BuildMI(*BB, BB->begin(), dl, TII.get(MSP430::PHI), MI.getOperand(0).getReg())
1407 .addReg(MI.getOperand(2).getReg())
1408 .addMBB(copy0MBB)
1409 .addReg(MI.getOperand(1).getReg())
1410 .addMBB(thisMBB);
1411
1412 MI.eraseFromParent(); // The pseudo instruction is gone now.
1413 return BB;
1414}
return SDValue()
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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 cl::opt< bool > MSP430NoLegalImmediate("msp430-no-legal-immediate", cl::Hidden, cl::desc("Enable non legal immediates (for testing purposes only)"), cl::init(false))
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:1071
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:123
bool hasStructRetAttr() const
Determine if the function returns a structure through first or second pointer argument.
Definition Function.h:695
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
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 getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
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 getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
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:201
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
LLVM Value Representation.
Definition Value.h:75
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
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:22
@ COND_LO
Definition MSP430.h:26
@ COND_L
Definition MSP430.h:28
@ COND_INVALID
Definition MSP430.h:32
@ COND_E
Definition MSP430.h:23
@ COND_GE
Definition MSP430.h:27
@ COND_NE
Definition MSP430.h:24
@ COND_HS
Definition MSP430.h:25
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:819
@ 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:275
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:779
@ 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:264
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition ISDOpcodes.h:853
@ GlobalAddress
Definition ISDOpcodes.h:88
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition ISDOpcodes.h:280
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:844
@ BR_CC
BR_CC - Conditional branch.
@ BR_JT
BR_JT - Jumptable branch.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:796
@ 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:704
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:765
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:850
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition ISDOpcodes.h:811
@ 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:888
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition ISDOpcodes.h:110
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:739
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition ISDOpcodes.h:53
@ ExternalSymbol
Definition ISDOpcodes.h:93
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:856
@ 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:833
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition ISDOpcodes.h:62
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,...
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:557
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
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:876
#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:403
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:324
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
Definition ValueTypes.h:389
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