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