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