LLVM 20.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"
16#include "MSP430Subtarget.h"
17#include "MSP430TargetMachine.h"
25#include "llvm/IR/CallingConv.h"
27#include "llvm/IR/Function.h"
28#include "llvm/IR/GlobalAlias.h"
30#include "llvm/IR/Intrinsics.h"
32#include "llvm/Support/Debug.h"
35using namespace llvm;
36
37#define DEBUG_TYPE "msp430-lower"
38
40 "msp430-no-legal-immediate", cl::Hidden,
41 cl::desc("Enable non legal immediates (for testing purposes only)"),
42 cl::init(false));
43
45 const MSP430Subtarget &STI)
46 : TargetLowering(TM) {
47
48 // Set up the register classes.
49 addRegisterClass(MVT::i8, &MSP430::GR8RegClass);
50 addRegisterClass(MVT::i16, &MSP430::GR16RegClass);
51
52 // Compute derived properties from the register classes
54
55 // Provide all sorts of operation actions
58 setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?
59
60 // We have post-incremented loads / stores.
63
64 for (MVT VT : MVT::integer_valuetypes()) {
70 }
71
72 // We don't have any truncstores
73 setTruncStoreAction(MVT::i16, MVT::i8, Expand);
74
103
110
117
119
120 // FIXME: Implement efficiently multiplication by a constant
131
144
145 // varargs support
151
152 // EABI Libcalls - EABI Section 6.2
153 const struct {
154 const RTLIB::Libcall Op;
155 const char * const Name;
156 const ISD::CondCode Cond;
157 } LibraryCalls[] = {
158 // Floating point conversions - EABI Table 6
159 { RTLIB::FPROUND_F64_F32, "__mspabi_cvtdf", ISD::SETCC_INVALID },
160 { RTLIB::FPEXT_F32_F64, "__mspabi_cvtfd", ISD::SETCC_INVALID },
161 // The following is NOT implemented in libgcc
162 //{ RTLIB::FPTOSINT_F64_I16, "__mspabi_fixdi", ISD::SETCC_INVALID },
163 { RTLIB::FPTOSINT_F64_I32, "__mspabi_fixdli", ISD::SETCC_INVALID },
164 { RTLIB::FPTOSINT_F64_I64, "__mspabi_fixdlli", ISD::SETCC_INVALID },
165 // The following is NOT implemented in libgcc
166 //{ RTLIB::FPTOUINT_F64_I16, "__mspabi_fixdu", ISD::SETCC_INVALID },
167 { RTLIB::FPTOUINT_F64_I32, "__mspabi_fixdul", ISD::SETCC_INVALID },
168 { RTLIB::FPTOUINT_F64_I64, "__mspabi_fixdull", ISD::SETCC_INVALID },
169 // The following is NOT implemented in libgcc
170 //{ RTLIB::FPTOSINT_F32_I16, "__mspabi_fixfi", ISD::SETCC_INVALID },
171 { RTLIB::FPTOSINT_F32_I32, "__mspabi_fixfli", ISD::SETCC_INVALID },
172 { RTLIB::FPTOSINT_F32_I64, "__mspabi_fixflli", ISD::SETCC_INVALID },
173 // The following is NOT implemented in libgcc
174 //{ RTLIB::FPTOUINT_F32_I16, "__mspabi_fixfu", ISD::SETCC_INVALID },
175 { RTLIB::FPTOUINT_F32_I32, "__mspabi_fixful", ISD::SETCC_INVALID },
176 { RTLIB::FPTOUINT_F32_I64, "__mspabi_fixfull", ISD::SETCC_INVALID },
177 // TODO The following IS implemented in libgcc
178 //{ RTLIB::SINTTOFP_I16_F64, "__mspabi_fltid", ISD::SETCC_INVALID },
179 { RTLIB::SINTTOFP_I32_F64, "__mspabi_fltlid", ISD::SETCC_INVALID },
180 // TODO The following IS implemented in libgcc but is not in the EABI
181 { RTLIB::SINTTOFP_I64_F64, "__mspabi_fltllid", ISD::SETCC_INVALID },
182 // TODO The following IS implemented in libgcc
183 //{ RTLIB::UINTTOFP_I16_F64, "__mspabi_fltud", ISD::SETCC_INVALID },
184 { RTLIB::UINTTOFP_I32_F64, "__mspabi_fltuld", ISD::SETCC_INVALID },
185 // The following IS implemented in libgcc but is not in the EABI
186 { RTLIB::UINTTOFP_I64_F64, "__mspabi_fltulld", ISD::SETCC_INVALID },
187 // TODO The following IS implemented in libgcc
188 //{ RTLIB::SINTTOFP_I16_F32, "__mspabi_fltif", ISD::SETCC_INVALID },
189 { RTLIB::SINTTOFP_I32_F32, "__mspabi_fltlif", ISD::SETCC_INVALID },
190 // TODO The following IS implemented in libgcc but is not in the EABI
191 { RTLIB::SINTTOFP_I64_F32, "__mspabi_fltllif", ISD::SETCC_INVALID },
192 // TODO The following IS implemented in libgcc
193 //{ RTLIB::UINTTOFP_I16_F32, "__mspabi_fltuf", ISD::SETCC_INVALID },
194 { RTLIB::UINTTOFP_I32_F32, "__mspabi_fltulf", ISD::SETCC_INVALID },
195 // The following IS implemented in libgcc but is not in the EABI
196 { RTLIB::UINTTOFP_I64_F32, "__mspabi_fltullf", ISD::SETCC_INVALID },
197
198 // Floating point comparisons - EABI Table 7
199 { RTLIB::OEQ_F64, "__mspabi_cmpd", ISD::SETEQ },
200 { RTLIB::UNE_F64, "__mspabi_cmpd", ISD::SETNE },
201 { RTLIB::OGE_F64, "__mspabi_cmpd", ISD::SETGE },
202 { RTLIB::OLT_F64, "__mspabi_cmpd", ISD::SETLT },
203 { RTLIB::OLE_F64, "__mspabi_cmpd", ISD::SETLE },
204 { RTLIB::OGT_F64, "__mspabi_cmpd", ISD::SETGT },
205 { RTLIB::OEQ_F32, "__mspabi_cmpf", ISD::SETEQ },
206 { RTLIB::UNE_F32, "__mspabi_cmpf", ISD::SETNE },
207 { RTLIB::OGE_F32, "__mspabi_cmpf", ISD::SETGE },
208 { RTLIB::OLT_F32, "__mspabi_cmpf", ISD::SETLT },
209 { RTLIB::OLE_F32, "__mspabi_cmpf", ISD::SETLE },
210 { RTLIB::OGT_F32, "__mspabi_cmpf", ISD::SETGT },
211
212 // Floating point arithmetic - EABI Table 8
213 { RTLIB::ADD_F64, "__mspabi_addd", ISD::SETCC_INVALID },
214 { RTLIB::ADD_F32, "__mspabi_addf", ISD::SETCC_INVALID },
215 { RTLIB::DIV_F64, "__mspabi_divd", ISD::SETCC_INVALID },
216 { RTLIB::DIV_F32, "__mspabi_divf", ISD::SETCC_INVALID },
217 { RTLIB::MUL_F64, "__mspabi_mpyd", ISD::SETCC_INVALID },
218 { RTLIB::MUL_F32, "__mspabi_mpyf", ISD::SETCC_INVALID },
219 { RTLIB::SUB_F64, "__mspabi_subd", ISD::SETCC_INVALID },
220 { RTLIB::SUB_F32, "__mspabi_subf", ISD::SETCC_INVALID },
221 // The following are NOT implemented in libgcc
222 // { RTLIB::NEG_F64, "__mspabi_negd", ISD::SETCC_INVALID },
223 // { RTLIB::NEG_F32, "__mspabi_negf", ISD::SETCC_INVALID },
224
225 // Universal Integer Operations - EABI Table 9
226 { RTLIB::SDIV_I16, "__mspabi_divi", ISD::SETCC_INVALID },
227 { RTLIB::SDIV_I32, "__mspabi_divli", ISD::SETCC_INVALID },
228 { RTLIB::SDIV_I64, "__mspabi_divlli", ISD::SETCC_INVALID },
229 { RTLIB::UDIV_I16, "__mspabi_divu", ISD::SETCC_INVALID },
230 { RTLIB::UDIV_I32, "__mspabi_divul", ISD::SETCC_INVALID },
231 { RTLIB::UDIV_I64, "__mspabi_divull", ISD::SETCC_INVALID },
232 { RTLIB::SREM_I16, "__mspabi_remi", ISD::SETCC_INVALID },
233 { RTLIB::SREM_I32, "__mspabi_remli", ISD::SETCC_INVALID },
234 { RTLIB::SREM_I64, "__mspabi_remlli", ISD::SETCC_INVALID },
235 { RTLIB::UREM_I16, "__mspabi_remu", ISD::SETCC_INVALID },
236 { RTLIB::UREM_I32, "__mspabi_remul", ISD::SETCC_INVALID },
237 { RTLIB::UREM_I64, "__mspabi_remull", ISD::SETCC_INVALID },
238
239 // Bitwise Operations - EABI Table 10
240 // TODO: __mspabi_[srli/srai/slli] ARE implemented in libgcc
241 { RTLIB::SRL_I32, "__mspabi_srll", ISD::SETCC_INVALID },
242 { RTLIB::SRA_I32, "__mspabi_sral", ISD::SETCC_INVALID },
243 { RTLIB::SHL_I32, "__mspabi_slll", ISD::SETCC_INVALID },
244 // __mspabi_[srlll/srall/sllll/rlli/rlll] are NOT implemented in libgcc
245
246 };
247
248 for (const auto &LC : LibraryCalls) {
249 setLibcallName(LC.Op, LC.Name);
250 if (LC.Cond != ISD::SETCC_INVALID)
251 setCmpLibcallCC(LC.Op, LC.Cond);
252 }
253
254 if (STI.hasHWMult16()) {
255 const struct {
256 const RTLIB::Libcall Op;
257 const char * const Name;
258 } LibraryCalls[] = {
259 // Integer Multiply - EABI Table 9
260 { RTLIB::MUL_I16, "__mspabi_mpyi_hw" },
261 { RTLIB::MUL_I32, "__mspabi_mpyl_hw" },
262 { RTLIB::MUL_I64, "__mspabi_mpyll_hw" },
263 // TODO The __mspabi_mpysl*_hw functions ARE implemented in libgcc
264 // TODO The __mspabi_mpyul*_hw functions ARE implemented in libgcc
265 };
266 for (const auto &LC : LibraryCalls) {
267 setLibcallName(LC.Op, LC.Name);
268 }
269 } else if (STI.hasHWMult32()) {
270 const struct {
271 const RTLIB::Libcall Op;
272 const char * const Name;
273 } LibraryCalls[] = {
274 // Integer Multiply - EABI Table 9
275 { RTLIB::MUL_I16, "__mspabi_mpyi_hw" },
276 { RTLIB::MUL_I32, "__mspabi_mpyl_hw32" },
277 { RTLIB::MUL_I64, "__mspabi_mpyll_hw32" },
278 // TODO The __mspabi_mpysl*_hw32 functions ARE implemented in libgcc
279 // TODO The __mspabi_mpyul*_hw32 functions ARE implemented in libgcc
280 };
281 for (const auto &LC : LibraryCalls) {
282 setLibcallName(LC.Op, LC.Name);
283 }
284 } else if (STI.hasHWMultF5()) {
285 const struct {
286 const RTLIB::Libcall Op;
287 const char * const Name;
288 } LibraryCalls[] = {
289 // Integer Multiply - EABI Table 9
290 { RTLIB::MUL_I16, "__mspabi_mpyi_f5hw" },
291 { RTLIB::MUL_I32, "__mspabi_mpyl_f5hw" },
292 { RTLIB::MUL_I64, "__mspabi_mpyll_f5hw" },
293 // TODO The __mspabi_mpysl*_f5hw functions ARE implemented in libgcc
294 // TODO The __mspabi_mpyul*_f5hw functions ARE implemented in libgcc
295 };
296 for (const auto &LC : LibraryCalls) {
297 setLibcallName(LC.Op, LC.Name);
298 }
299 } else { // NoHWMult
300 const struct {
301 const RTLIB::Libcall Op;
302 const char * const Name;
303 } LibraryCalls[] = {
304 // Integer Multiply - EABI Table 9
305 { RTLIB::MUL_I16, "__mspabi_mpyi" },
306 { RTLIB::MUL_I32, "__mspabi_mpyl" },
307 { RTLIB::MUL_I64, "__mspabi_mpyll" },
308 // The __mspabi_mpysl* functions are NOT implemented in libgcc
309 // The __mspabi_mpyul* functions are NOT implemented in libgcc
310 };
311 for (const auto &LC : LibraryCalls) {
312 setLibcallName(LC.Op, LC.Name);
313 }
315 }
316
317 // Several of the runtime library functions use a special calling conv
332 // TODO: __mspabi_srall, __mspabi_srlll, __mspabi_sllll
333
337}
338
340 SelectionDAG &DAG) const {
341 switch (Op.getOpcode()) {
342 case ISD::SHL: // FALLTHROUGH
343 case ISD::SRL:
344 case ISD::SRA: return LowerShifts(Op, DAG);
345 case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
346 case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
347 case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG);
348 case ISD::SETCC: return LowerSETCC(Op, DAG);
349 case ISD::BR_CC: return LowerBR_CC(Op, DAG);
350 case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
351 case ISD::SIGN_EXTEND: return LowerSIGN_EXTEND(Op, DAG);
352 case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
353 case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
354 case ISD::VASTART: return LowerVASTART(Op, DAG);
355 case ISD::JumpTable: return LowerJumpTable(Op, DAG);
356 default:
357 llvm_unreachable("unimplemented operand");
358 }
359}
360
361// Define non profitable transforms into shifts
363 unsigned Amount) const {
364 return !(Amount == 8 || Amount == 9 || Amount<=2);
365}
366
367// Implemented to verify test case assertions in
368// tests/codegen/msp430/shift-amount-threshold-b.ll
371 return Immed >= -32 && Immed < 32;
373}
374
375//===----------------------------------------------------------------------===//
376// MSP430 Inline Assembly Support
377//===----------------------------------------------------------------------===//
378
379/// getConstraintType - Given a constraint letter, return the type of
380/// constraint it is for this target.
383 if (Constraint.size() == 1) {
384 switch (Constraint[0]) {
385 case 'r':
386 return C_RegisterClass;
387 default:
388 break;
389 }
390 }
391 return TargetLowering::getConstraintType(Constraint);
392}
393
394std::pair<unsigned, const TargetRegisterClass *>
396 const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
397 if (Constraint.size() == 1) {
398 // GCC Constraint Letters
399 switch (Constraint[0]) {
400 default: break;
401 case 'r': // GENERAL_REGS
402 if (VT == MVT::i8)
403 return std::make_pair(0U, &MSP430::GR8RegClass);
404
405 return std::make_pair(0U, &MSP430::GR16RegClass);
406 }
407 }
408
410}
411
412//===----------------------------------------------------------------------===//
413// Calling Convention Implementation
414//===----------------------------------------------------------------------===//
415
416#include "MSP430GenCallingConv.inc"
417
418/// For each argument in a function store the number of pieces it is composed
419/// of.
420template<typename ArgT>
423 unsigned CurrentArgIndex;
424
425 if (Args.empty())
426 return;
427
428 CurrentArgIndex = Args[0].OrigArgIndex;
429 Out.push_back(0);
430
431 for (auto &Arg : Args) {
432 if (CurrentArgIndex == Arg.OrigArgIndex) {
433 Out.back() += 1;
434 } else {
435 Out.push_back(1);
436 CurrentArgIndex = Arg.OrigArgIndex;
437 }
438 }
439}
440
441static void AnalyzeVarArgs(CCState &State,
443 State.AnalyzeCallOperands(Outs, CC_MSP430_AssignStack);
444}
445
446static void AnalyzeVarArgs(CCState &State,
448 State.AnalyzeFormalArguments(Ins, CC_MSP430_AssignStack);
449}
450
451/// Analyze incoming and outgoing function arguments. We need custom C++ code
452/// to handle special constraints in the ABI like reversing the order of the
453/// pieces of splitted arguments. In addition, all pieces of a certain argument
454/// have to be passed either using registers or the stack but never mixing both.
455template<typename ArgT>
456static void AnalyzeArguments(CCState &State,
458 const SmallVectorImpl<ArgT> &Args) {
459 static const MCPhysReg CRegList[] = {
460 MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15
461 };
462 static const unsigned CNbRegs = std::size(CRegList);
463 static const MCPhysReg BuiltinRegList[] = {
464 MSP430::R8, MSP430::R9, MSP430::R10, MSP430::R11,
465 MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15
466 };
467 static const unsigned BuiltinNbRegs = std::size(BuiltinRegList);
468
469 ArrayRef<MCPhysReg> RegList;
470 unsigned NbRegs;
471
472 bool Builtin = (State.getCallingConv() == CallingConv::MSP430_BUILTIN);
473 if (Builtin) {
474 RegList = BuiltinRegList;
475 NbRegs = BuiltinNbRegs;
476 } else {
477 RegList = CRegList;
478 NbRegs = CNbRegs;
479 }
480
481 if (State.isVarArg()) {
482 AnalyzeVarArgs(State, Args);
483 return;
484 }
485
486 SmallVector<unsigned, 4> ArgsParts;
487 ParseFunctionArgs(Args, ArgsParts);
488
489 if (Builtin) {
490 assert(ArgsParts.size() == 2 &&
491 "Builtin calling convention requires two arguments");
492 }
493
494 unsigned RegsLeft = NbRegs;
495 bool UsedStack = false;
496 unsigned ValNo = 0;
497
498 for (unsigned i = 0, e = ArgsParts.size(); i != e; i++) {
499 MVT ArgVT = Args[ValNo].VT;
500 ISD::ArgFlagsTy ArgFlags = Args[ValNo].Flags;
501 MVT LocVT = ArgVT;
503
504 // Promote i8 to i16
505 if (LocVT == MVT::i8) {
506 LocVT = MVT::i16;
507 if (ArgFlags.isSExt())
508 LocInfo = CCValAssign::SExt;
509 else if (ArgFlags.isZExt())
510 LocInfo = CCValAssign::ZExt;
511 else
512 LocInfo = CCValAssign::AExt;
513 }
514
515 // Handle byval arguments
516 if (ArgFlags.isByVal()) {
517 State.HandleByVal(ValNo++, ArgVT, LocVT, LocInfo, 2, Align(2), ArgFlags);
518 continue;
519 }
520
521 unsigned Parts = ArgsParts[i];
522
523 if (Builtin) {
524 assert(Parts == 4 &&
525 "Builtin calling convention requires 64-bit arguments");
526 }
527
528 if (!UsedStack && Parts == 2 && RegsLeft == 1) {
529 // Special case for 32-bit register split, see EABI section 3.3.3
530 unsigned Reg = State.AllocateReg(RegList);
531 State.addLoc(CCValAssign::getReg(ValNo++, ArgVT, Reg, LocVT, LocInfo));
532 RegsLeft -= 1;
533
534 UsedStack = true;
535 CC_MSP430_AssignStack(ValNo++, ArgVT, LocVT, LocInfo, ArgFlags, State);
536 } else if (Parts <= RegsLeft) {
537 for (unsigned j = 0; j < Parts; j++) {
538 unsigned Reg = State.AllocateReg(RegList);
539 State.addLoc(CCValAssign::getReg(ValNo++, ArgVT, Reg, LocVT, LocInfo));
540 RegsLeft--;
541 }
542 } else {
543 UsedStack = true;
544 for (unsigned j = 0; j < Parts; j++)
545 CC_MSP430_AssignStack(ValNo++, ArgVT, LocVT, LocInfo, ArgFlags, State);
546 }
547 }
548}
549
550static void AnalyzeRetResult(CCState &State,
552 State.AnalyzeCallResult(Ins, RetCC_MSP430);
553}
554
555static void AnalyzeRetResult(CCState &State,
557 State.AnalyzeReturn(Outs, RetCC_MSP430);
558}
559
560template<typename ArgT>
561static void AnalyzeReturnValues(CCState &State,
563 const SmallVectorImpl<ArgT> &Args) {
564 AnalyzeRetResult(State, Args);
565}
566
567SDValue MSP430TargetLowering::LowerFormalArguments(
568 SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
569 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
570 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
571
572 switch (CallConv) {
573 default:
574 report_fatal_error("Unsupported calling convention");
575 case CallingConv::C:
577 return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals);
579 if (Ins.empty())
580 return Chain;
581 report_fatal_error("ISRs cannot have arguments");
582 }
583}
584
586MSP430TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
587 SmallVectorImpl<SDValue> &InVals) const {
588 SelectionDAG &DAG = CLI.DAG;
589 SDLoc &dl = CLI.DL;
591 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
593 SDValue Chain = CLI.Chain;
594 SDValue Callee = CLI.Callee;
595 bool &isTailCall = CLI.IsTailCall;
596 CallingConv::ID CallConv = CLI.CallConv;
597 bool isVarArg = CLI.IsVarArg;
598
599 // MSP430 target does not yet support tail call optimization.
600 isTailCall = false;
601
602 switch (CallConv) {
603 default:
604 report_fatal_error("Unsupported calling convention");
607 case CallingConv::C:
608 return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
609 Outs, OutVals, Ins, dl, DAG, InVals);
611 report_fatal_error("ISRs cannot be called directly");
612 }
613}
614
615/// LowerCCCArguments - transform physical registers into virtual registers and
616/// generate load operations for arguments places on the stack.
617// FIXME: struct return stuff
618SDValue MSP430TargetLowering::LowerCCCArguments(
619 SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
620 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
621 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
623 MachineFrameInfo &MFI = MF.getFrameInfo();
626
627 // Assign locations to all of the incoming arguments.
629 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
630 *DAG.getContext());
631 AnalyzeArguments(CCInfo, ArgLocs, Ins);
632
633 // Create frame index for the start of the first vararg value
634 if (isVarArg) {
635 unsigned Offset = CCInfo.getStackSize();
636 FuncInfo->setVarArgsFrameIndex(MFI.CreateFixedObject(1, Offset, true));
637 }
638
639 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
640 CCValAssign &VA = ArgLocs[i];
641 if (VA.isRegLoc()) {
642 // Arguments passed in registers
643 EVT RegVT = VA.getLocVT();
644 switch (RegVT.getSimpleVT().SimpleTy) {
645 default:
646 {
647#ifndef NDEBUG
648 errs() << "LowerFormalArguments Unhandled argument type: "
649 << RegVT << "\n";
650#endif
651 llvm_unreachable(nullptr);
652 }
653 case MVT::i16:
654 Register VReg = RegInfo.createVirtualRegister(&MSP430::GR16RegClass);
655 RegInfo.addLiveIn(VA.getLocReg(), VReg);
656 SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, RegVT);
657
658 // If this is an 8-bit value, it is really passed promoted to 16
659 // bits. Insert an assert[sz]ext to capture this, then truncate to the
660 // right size.
661 if (VA.getLocInfo() == CCValAssign::SExt)
662 ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue,
663 DAG.getValueType(VA.getValVT()));
664 else if (VA.getLocInfo() == CCValAssign::ZExt)
665 ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue,
666 DAG.getValueType(VA.getValVT()));
667
668 if (VA.getLocInfo() != CCValAssign::Full)
669 ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
670
671 InVals.push_back(ArgValue);
672 }
673 } else {
674 // Only arguments passed on the stack should make it here.
675 assert(VA.isMemLoc());
676
677 SDValue InVal;
678 ISD::ArgFlagsTy Flags = Ins[i].Flags;
679
680 if (Flags.isByVal()) {
681 MVT PtrVT = VA.getLocVT();
682 int FI = MFI.CreateFixedObject(Flags.getByValSize(),
683 VA.getLocMemOffset(), true);
684 InVal = DAG.getFrameIndex(FI, PtrVT);
685 } else {
686 // Load the argument to a virtual register
687 unsigned ObjSize = VA.getLocVT().getSizeInBits()/8;
688 if (ObjSize > 2) {
689 errs() << "LowerFormalArguments Unhandled argument type: "
690 << VA.getLocVT() << "\n";
691 }
692 // Create the frame index object for this incoming parameter...
693 int FI = MFI.CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);
694
695 // Create the SelectionDAG nodes corresponding to a load
696 //from this parameter
697 SDValue FIN = DAG.getFrameIndex(FI, MVT::i16);
698 InVal = DAG.getLoad(
699 VA.getLocVT(), dl, Chain, FIN,
701 }
702
703 InVals.push_back(InVal);
704 }
705 }
706
707 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
708 if (Ins[i].Flags.isSRet()) {
709 Register Reg = FuncInfo->getSRetReturnReg();
710 if (!Reg) {
712 getRegClassFor(MVT::i16));
713 FuncInfo->setSRetReturnReg(Reg);
714 }
715 SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, InVals[i]);
716 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain);
717 }
718 }
719
720 return Chain;
721}
722
723bool
724MSP430TargetLowering::CanLowerReturn(CallingConv::ID CallConv,
725 MachineFunction &MF,
726 bool IsVarArg,
728 LLVMContext &Context) const {
730 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
731 return CCInfo.CheckReturn(Outs, RetCC_MSP430);
732}
733
735MSP430TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
736 bool isVarArg,
738 const SmallVectorImpl<SDValue> &OutVals,
739 const SDLoc &dl, SelectionDAG &DAG) const {
740
742
743 // CCValAssign - represent the assignment of the return value to a location
745
746 // ISRs cannot return any value.
747 if (CallConv == CallingConv::MSP430_INTR && !Outs.empty())
748 report_fatal_error("ISRs cannot return any value");
749
750 // CCState - Info about the registers and stack slot.
751 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
752 *DAG.getContext());
753
754 // Analize return values.
755 AnalyzeReturnValues(CCInfo, RVLocs, Outs);
756
757 SDValue Glue;
758 SmallVector<SDValue, 4> RetOps(1, Chain);
759
760 // Copy the result values into the output registers.
761 for (unsigned i = 0; i != RVLocs.size(); ++i) {
762 CCValAssign &VA = RVLocs[i];
763 assert(VA.isRegLoc() && "Can only return in registers!");
764
765 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
766 OutVals[i], Glue);
767
768 // Guarantee that all emitted copies are stuck together,
769 // avoiding something bad.
770 Glue = Chain.getValue(1);
771 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
772 }
773
774 if (MF.getFunction().hasStructRetAttr()) {
776 Register Reg = FuncInfo->getSRetReturnReg();
777
778 if (!Reg)
779 llvm_unreachable("sret virtual register not created in entry block");
780
781 MVT PtrVT = getFrameIndexTy(DAG.getDataLayout());
782 SDValue Val =
783 DAG.getCopyFromReg(Chain, dl, Reg, PtrVT);
784 unsigned R12 = MSP430::R12;
785
786 Chain = DAG.getCopyToReg(Chain, dl, R12, Val, Glue);
787 Glue = Chain.getValue(1);
788 RetOps.push_back(DAG.getRegister(R12, PtrVT));
789 }
790
791 unsigned Opc = (CallConv == CallingConv::MSP430_INTR ?
793
794 RetOps[0] = Chain; // Update chain.
795
796 // Add the glue if we have it.
797 if (Glue.getNode())
798 RetOps.push_back(Glue);
799
800 return DAG.getNode(Opc, dl, MVT::Other, RetOps);
801}
802
803/// LowerCCCCallTo - functions arguments are copied from virtual regs to
804/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
805SDValue MSP430TargetLowering::LowerCCCCallTo(
806 SDValue Chain, SDValue Callee, CallingConv::ID CallConv, bool isVarArg,
807 bool isTailCall, const SmallVectorImpl<ISD::OutputArg> &Outs,
808 const SmallVectorImpl<SDValue> &OutVals,
809 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
810 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
811 // Analyze operands of the call, assigning locations to each operand.
813 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
814 *DAG.getContext());
815 AnalyzeArguments(CCInfo, ArgLocs, Outs);
816
817 // Get a count of how many bytes are to be pushed on the stack.
818 unsigned NumBytes = CCInfo.getStackSize();
819 MVT PtrVT = getFrameIndexTy(DAG.getDataLayout());
820
821 Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, dl);
822
824 SmallVector<SDValue, 12> MemOpChains;
826
827 // Walk the register/memloc assignments, inserting copies/loads.
828 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
829 CCValAssign &VA = ArgLocs[i];
830
831 SDValue Arg = OutVals[i];
832
833 // Promote the value if needed.
834 switch (VA.getLocInfo()) {
835 default: llvm_unreachable("Unknown loc info!");
836 case CCValAssign::Full: break;
838 Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
839 break;
841 Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
842 break;
844 Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
845 break;
846 }
847
848 // Arguments that can be passed on register must be kept at RegsToPass
849 // vector
850 if (VA.isRegLoc()) {
851 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
852 } else {
853 assert(VA.isMemLoc());
854
855 if (!StackPtr.getNode())
856 StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SP, PtrVT);
857
858 SDValue PtrOff =
859 DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr,
860 DAG.getIntPtrConstant(VA.getLocMemOffset(), dl));
861
863 ISD::ArgFlagsTy Flags = Outs[i].Flags;
864
865 if (Flags.isByVal()) {
866 SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), dl, MVT::i16);
867 MemOp = DAG.getMemcpy(Chain, dl, PtrOff, Arg, SizeNode,
868 Flags.getNonZeroByValAlign(),
869 /*isVolatile*/ false,
870 /*AlwaysInline=*/true,
871 /*CI=*/nullptr, std::nullopt,
873 } else {
874 MemOp = DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
875 }
876
877 MemOpChains.push_back(MemOp);
878 }
879 }
880
881 // Transform all store nodes into one single node because all store nodes are
882 // independent of each other.
883 if (!MemOpChains.empty())
884 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
885
886 // Build a sequence of copy-to-reg nodes chained together with token chain and
887 // flag operands which copy the outgoing args into registers. The InGlue in
888 // necessary since all emitted instructions must be stuck together.
889 SDValue InGlue;
890 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
891 Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
892 RegsToPass[i].second, InGlue);
893 InGlue = Chain.getValue(1);
894 }
895
896 // If the callee is a GlobalAddress node (quite common, every direct call is)
897 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
898 // Likewise ExternalSymbol -> TargetExternalSymbol.
899 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
900 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i16);
901 else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
902 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i16);
903
904 // Returns a chain & a flag for retval copy to use.
905 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
907 Ops.push_back(Chain);
908 Ops.push_back(Callee);
909
910 // Add argument registers to the end of the list so that they are
911 // known live into the call.
912 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
913 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
914 RegsToPass[i].second.getValueType()));
915
916 if (InGlue.getNode())
917 Ops.push_back(InGlue);
918
919 Chain = DAG.getNode(MSP430ISD::CALL, dl, NodeTys, Ops);
920 InGlue = Chain.getValue(1);
921
922 // Create the CALLSEQ_END node.
923 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, InGlue, dl);
924 InGlue = Chain.getValue(1);
925
926 // Handle result values, copying them out of physregs into vregs that we
927 // return.
928 return LowerCallResult(Chain, InGlue, CallConv, isVarArg, Ins, dl,
929 DAG, InVals);
930}
931
932/// LowerCallResult - Lower the result values of a call into the
933/// appropriate copies out of appropriate physical registers.
934///
935SDValue MSP430TargetLowering::LowerCallResult(
936 SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool isVarArg,
937 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
938 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
939
940 // Assign locations to each value returned by this call.
942 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
943 *DAG.getContext());
944
945 AnalyzeReturnValues(CCInfo, RVLocs, Ins);
946
947 // Copy all of the result registers out of their specified physreg.
948 for (unsigned i = 0; i != RVLocs.size(); ++i) {
949 Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(),
950 RVLocs[i].getValVT(), InGlue).getValue(1);
951 InGlue = Chain.getValue(2);
952 InVals.push_back(Chain.getValue(0));
953 }
954
955 return Chain;
956}
957
959 SelectionDAG &DAG) const {
960 unsigned Opc = Op.getOpcode();
961 SDNode* N = Op.getNode();
962 EVT VT = Op.getValueType();
963 SDLoc dl(N);
964
965 // Expand non-constant shifts to loops:
966 if (!isa<ConstantSDNode>(N->getOperand(1)))
967 return Op;
968
969 uint64_t ShiftAmount = N->getConstantOperandVal(1);
970
971 // Expand the stuff into sequence of shifts.
972 SDValue Victim = N->getOperand(0);
973
974 if (ShiftAmount >= 8) {
975 assert(VT == MVT::i16 && "Can not shift i8 by 8 and more");
976 switch(Opc) {
977 default:
978 llvm_unreachable("Unknown shift");
979 case ISD::SHL:
980 // foo << (8 + N) => swpb(zext(foo)) << N
981 Victim = DAG.getZeroExtendInReg(Victim, dl, MVT::i8);
982 Victim = DAG.getNode(ISD::BSWAP, dl, VT, Victim);
983 break;
984 case ISD::SRA:
985 case ISD::SRL:
986 // foo >> (8 + N) => sxt(swpb(foo)) >> N
987 Victim = DAG.getNode(ISD::BSWAP, dl, VT, Victim);
988 Victim = (Opc == ISD::SRA)
989 ? DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT, Victim,
990 DAG.getValueType(MVT::i8))
991 : DAG.getZeroExtendInReg(Victim, dl, MVT::i8);
992 break;
993 }
994 ShiftAmount -= 8;
995 }
996
997 if (Opc == ISD::SRL && ShiftAmount) {
998 // Emit a special goodness here:
999 // srl A, 1 => clrc; rrc A
1000 Victim = DAG.getNode(MSP430ISD::RRCL, dl, VT, Victim);
1001 ShiftAmount -= 1;
1002 }
1003
1004 while (ShiftAmount--)
1005 Victim = DAG.getNode((Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA),
1006 dl, VT, Victim);
1007
1008 return Victim;
1009}
1010
1012 SelectionDAG &DAG) const {
1013 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
1014 int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();
1015 EVT PtrVT = Op.getValueType();
1016
1017 // Create the TargetGlobalAddress node, folding in the constant offset.
1018 SDValue Result = DAG.getTargetGlobalAddress(GV, SDLoc(Op), PtrVT, Offset);
1019 return DAG.getNode(MSP430ISD::Wrapper, SDLoc(Op), PtrVT, Result);
1020}
1021
1023 SelectionDAG &DAG) const {
1024 SDLoc dl(Op);
1025 const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol();
1026 EVT PtrVT = Op.getValueType();
1027 SDValue Result = DAG.getTargetExternalSymbol(Sym, PtrVT);
1028
1029 return DAG.getNode(MSP430ISD::Wrapper, dl, PtrVT, Result);
1030}
1031
1033 SelectionDAG &DAG) const {
1034 SDLoc dl(Op);
1035 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
1036 EVT PtrVT = Op.getValueType();
1037 SDValue Result = DAG.getTargetBlockAddress(BA, PtrVT);
1038
1039 return DAG.getNode(MSP430ISD::Wrapper, dl, PtrVT, Result);
1040}
1041
1042static SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC,
1043 ISD::CondCode CC, const SDLoc &dl, SelectionDAG &DAG) {
1044 // FIXME: Handle bittests someday
1045 assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet");
1046
1047 // FIXME: Handle jump negative someday
1049 switch (CC) {
1050 default: llvm_unreachable("Invalid integer condition!");
1051 case ISD::SETEQ:
1052 TCC = MSP430CC::COND_E; // aka COND_Z
1053 // Minor optimization: if LHS is a constant, swap operands, then the
1054 // constant can be folded into comparison.
1055 if (LHS.getOpcode() == ISD::Constant)
1056 std::swap(LHS, RHS);
1057 break;
1058 case ISD::SETNE:
1059 TCC = MSP430CC::COND_NE; // aka COND_NZ
1060 // Minor optimization: if LHS is a constant, swap operands, then the
1061 // constant can be folded into comparison.
1062 if (LHS.getOpcode() == ISD::Constant)
1063 std::swap(LHS, RHS);
1064 break;
1065 case ISD::SETULE:
1066 std::swap(LHS, RHS);
1067 [[fallthrough]];
1068 case ISD::SETUGE:
1069 // Turn lhs u>= rhs with lhs constant into rhs u< lhs+1, this allows us to
1070 // fold constant into instruction.
1071 if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
1072 LHS = RHS;
1073 RHS = DAG.getConstant(C->getSExtValue() + 1, dl, C->getValueType(0));
1074 TCC = MSP430CC::COND_LO;
1075 break;
1076 }
1077 TCC = MSP430CC::COND_HS; // aka COND_C
1078 break;
1079 case ISD::SETUGT:
1080 std::swap(LHS, RHS);
1081 [[fallthrough]];
1082 case ISD::SETULT:
1083 // Turn lhs u< rhs with lhs constant into rhs u>= lhs+1, this allows us to
1084 // fold constant into instruction.
1085 if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
1086 LHS = RHS;
1087 RHS = DAG.getConstant(C->getSExtValue() + 1, dl, C->getValueType(0));
1088 TCC = MSP430CC::COND_HS;
1089 break;
1090 }
1091 TCC = MSP430CC::COND_LO; // aka COND_NC
1092 break;
1093 case ISD::SETLE:
1094 std::swap(LHS, RHS);
1095 [[fallthrough]];
1096 case ISD::SETGE:
1097 // Turn lhs >= rhs with lhs constant into rhs < lhs+1, this allows us to
1098 // fold constant into instruction.
1099 if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
1100 LHS = RHS;
1101 RHS = DAG.getConstant(C->getSExtValue() + 1, dl, C->getValueType(0));
1102 TCC = MSP430CC::COND_L;
1103 break;
1104 }
1105 TCC = MSP430CC::COND_GE;
1106 break;
1107 case ISD::SETGT:
1108 std::swap(LHS, RHS);
1109 [[fallthrough]];
1110 case ISD::SETLT:
1111 // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to
1112 // fold constant into instruction.
1113 if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
1114 LHS = RHS;
1115 RHS = DAG.getConstant(C->getSExtValue() + 1, dl, C->getValueType(0));
1116 TCC = MSP430CC::COND_GE;
1117 break;
1118 }
1119 TCC = MSP430CC::COND_L;
1120 break;
1121 }
1122
1123 TargetCC = DAG.getConstant(TCC, dl, MVT::i8);
1124 return DAG.getNode(MSP430ISD::CMP, dl, MVT::Glue, LHS, RHS);
1125}
1126
1127
1129 SDValue Chain = Op.getOperand(0);
1130 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
1131 SDValue LHS = Op.getOperand(2);
1132 SDValue RHS = Op.getOperand(3);
1133 SDValue Dest = Op.getOperand(4);
1134 SDLoc dl (Op);
1135
1136 SDValue TargetCC;
1137 SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
1138
1139 return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(),
1140 Chain, Dest, TargetCC, Flag);
1141}
1142
1144 SDValue LHS = Op.getOperand(0);
1145 SDValue RHS = Op.getOperand(1);
1146 SDLoc dl (Op);
1147
1148 // If we are doing an AND and testing against zero, then the CMP
1149 // will not be generated. The AND (or BIT) will generate the condition codes,
1150 // but they are different from CMP.
1151 // FIXME: since we're doing a post-processing, use a pseudoinstr here, so
1152 // lowering & isel wouldn't diverge.
1153 bool andCC = isNullConstant(RHS) && LHS.hasOneUse() &&
1154 (LHS.getOpcode() == ISD::AND ||
1155 (LHS.getOpcode() == ISD::TRUNCATE &&
1156 LHS.getOperand(0).getOpcode() == ISD::AND));
1157 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
1158 SDValue TargetCC;
1159 SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
1160
1161 // Get the condition codes directly from the status register, if its easy.
1162 // Otherwise a branch will be generated. Note that the AND and BIT
1163 // instructions generate different flags than CMP, the carry bit can be used
1164 // for NE/EQ.
1165 bool Invert = false;
1166 bool Shift = false;
1167 bool Convert = true;
1168 switch (TargetCC->getAsZExtVal()) {
1169 default:
1170 Convert = false;
1171 break;
1172 case MSP430CC::COND_HS:
1173 // Res = SR & 1, no processing is required
1174 break;
1175 case MSP430CC::COND_LO:
1176 // Res = ~(SR & 1)
1177 Invert = true;
1178 break;
1179 case MSP430CC::COND_NE:
1180 if (andCC) {
1181 // C = ~Z, thus Res = SR & 1, no processing is required
1182 } else {
1183 // Res = ~((SR >> 1) & 1)
1184 Shift = true;
1185 Invert = true;
1186 }
1187 break;
1188 case MSP430CC::COND_E:
1189 Shift = true;
1190 // C = ~Z for AND instruction, thus we can put Res = ~(SR & 1), however,
1191 // Res = (SR >> 1) & 1 is 1 word shorter.
1192 break;
1193 }
1194 EVT VT = Op.getValueType();
1195 SDValue One = DAG.getConstant(1, dl, VT);
1196 if (Convert) {
1197 SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SR,
1198 MVT::i16, Flag);
1199 if (Shift)
1200 // FIXME: somewhere this is turned into a SRL, lower it MSP specific?
1201 SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One);
1202 SR = DAG.getNode(ISD::AND, dl, MVT::i16, SR, One);
1203 if (Invert)
1204 SR = DAG.getNode(ISD::XOR, dl, MVT::i16, SR, One);
1205 return SR;
1206 } else {
1207 SDValue Zero = DAG.getConstant(0, dl, VT);
1208 SDValue Ops[] = {One, Zero, TargetCC, Flag};
1209 return DAG.getNode(MSP430ISD::SELECT_CC, dl, Op.getValueType(), Ops);
1210 }
1211}
1212
1214 SelectionDAG &DAG) const {
1215 SDValue LHS = Op.getOperand(0);
1216 SDValue RHS = Op.getOperand(1);
1217 SDValue TrueV = Op.getOperand(2);
1218 SDValue FalseV = Op.getOperand(3);
1219 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
1220 SDLoc dl (Op);
1221
1222 SDValue TargetCC;
1223 SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
1224
1225 SDValue Ops[] = {TrueV, FalseV, TargetCC, Flag};
1226
1227 return DAG.getNode(MSP430ISD::SELECT_CC, dl, Op.getValueType(), Ops);
1228}
1229
1231 SelectionDAG &DAG) const {
1232 SDValue Val = Op.getOperand(0);
1233 EVT VT = Op.getValueType();
1234 SDLoc dl(Op);
1235
1236 assert(VT == MVT::i16 && "Only support i16 for now!");
1237
1238 return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT,
1239 DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val),
1240 DAG.getValueType(Val.getValueType()));
1241}
1242
1243SDValue
1247 int ReturnAddrIndex = FuncInfo->getRAIndex();
1248 MVT PtrVT = getFrameIndexTy(MF.getDataLayout());
1249
1250 if (ReturnAddrIndex == 0) {
1251 // Set up a frame object for the return address.
1252 uint64_t SlotSize = PtrVT.getStoreSize();
1253 ReturnAddrIndex = MF.getFrameInfo().CreateFixedObject(SlotSize, -SlotSize,
1254 true);
1255 FuncInfo->setRAIndex(ReturnAddrIndex);
1256 }
1257
1258 return DAG.getFrameIndex(ReturnAddrIndex, PtrVT);
1259}
1260
1262 SelectionDAG &DAG) const {
1264 MFI.setReturnAddressIsTaken(true);
1265
1267 return SDValue();
1268
1269 unsigned Depth = Op.getConstantOperandVal(0);
1270 SDLoc dl(Op);
1271 EVT PtrVT = Op.getValueType();
1272
1273 if (Depth > 0) {
1274 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
1275 SDValue Offset =
1276 DAG.getConstant(PtrVT.getStoreSize(), dl, MVT::i16);
1277 return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(),
1278 DAG.getNode(ISD::ADD, dl, PtrVT, FrameAddr, Offset),
1280 }
1281
1282 // Just load the return address.
1283 SDValue RetAddrFI = getReturnAddressFrameIndex(DAG);
1284 return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), RetAddrFI,
1286}
1287
1289 SelectionDAG &DAG) const {
1291 MFI.setFrameAddressIsTaken(true);
1292
1293 EVT VT = Op.getValueType();
1294 SDLoc dl(Op); // FIXME probably not meaningful
1295 unsigned Depth = Op.getConstantOperandVal(0);
1296 SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl,
1297 MSP430::R4, VT);
1298 while (Depth--)
1299 FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
1301 return FrameAddr;
1302}
1303
1305 SelectionDAG &DAG) const {
1308
1309 SDValue Ptr = Op.getOperand(1);
1310 EVT PtrVT = Ptr.getValueType();
1311
1312 // Frame index of first vararg argument
1313 SDValue FrameIndex =
1314 DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);
1315 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
1316
1317 // Create a store of the frame index to the location operand
1318 return DAG.getStore(Op.getOperand(0), SDLoc(Op), FrameIndex, Ptr,
1319 MachinePointerInfo(SV));
1320}
1321
1323 SelectionDAG &DAG) const {
1324 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
1325 EVT PtrVT = Op.getValueType();
1326 SDValue Result = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
1327 return DAG.getNode(MSP430ISD::Wrapper, SDLoc(JT), PtrVT, Result);
1328}
1329
1330/// getPostIndexedAddressParts - returns true by value, base pointer and
1331/// offset pointer and addressing mode by reference if this node can be
1332/// combined with a load / store to form a post-indexed load / store.
1333bool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
1334 SDValue &Base,
1335 SDValue &Offset,
1337 SelectionDAG &DAG) const {
1338
1339 LoadSDNode *LD = cast<LoadSDNode>(N);
1340 if (LD->getExtensionType() != ISD::NON_EXTLOAD)
1341 return false;
1342
1343 EVT VT = LD->getMemoryVT();
1344 if (VT != MVT::i8 && VT != MVT::i16)
1345 return false;
1346
1347 if (Op->getOpcode() != ISD::ADD)
1348 return false;
1349
1350 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) {
1351 uint64_t RHSC = RHS->getZExtValue();
1352 if ((VT == MVT::i16 && RHSC != 2) ||
1353 (VT == MVT::i8 && RHSC != 1))
1354 return false;
1355
1356 Base = Op->getOperand(0);
1357 Offset = DAG.getConstant(RHSC, SDLoc(N), VT);
1358 AM = ISD::POST_INC;
1359 return true;
1360 }
1361
1362 return false;
1363}
1364
1365
1366const char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
1367 switch ((MSP430ISD::NodeType)Opcode) {
1368 case MSP430ISD::FIRST_NUMBER: break;
1369 case MSP430ISD::RET_GLUE: return "MSP430ISD::RET_GLUE";
1370 case MSP430ISD::RETI_GLUE: return "MSP430ISD::RETI_GLUE";
1371 case MSP430ISD::RRA: return "MSP430ISD::RRA";
1372 case MSP430ISD::RLA: return "MSP430ISD::RLA";
1373 case MSP430ISD::RRC: return "MSP430ISD::RRC";
1374 case MSP430ISD::RRCL: return "MSP430ISD::RRCL";
1375 case MSP430ISD::CALL: return "MSP430ISD::CALL";
1376 case MSP430ISD::Wrapper: return "MSP430ISD::Wrapper";
1377 case MSP430ISD::BR_CC: return "MSP430ISD::BR_CC";
1378 case MSP430ISD::CMP: return "MSP430ISD::CMP";
1379 case MSP430ISD::SETCC: return "MSP430ISD::SETCC";
1380 case MSP430ISD::SELECT_CC: return "MSP430ISD::SELECT_CC";
1381 case MSP430ISD::DADD: return "MSP430ISD::DADD";
1382 }
1383 return nullptr;
1384}
1385
1387 Type *Ty2) const {
1388 if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
1389 return false;
1390
1391 return (Ty1->getPrimitiveSizeInBits().getFixedValue() >
1393}
1394
1396 if (!VT1.isInteger() || !VT2.isInteger())
1397 return false;
1398
1399 return (VT1.getFixedSizeInBits() > VT2.getFixedSizeInBits());
1400}
1401
1403 // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
1404 return false && Ty1->isIntegerTy(8) && Ty2->isIntegerTy(16);
1405}
1406
1408 // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
1409 return false && VT1 == MVT::i8 && VT2 == MVT::i16;
1410}
1411
1412//===----------------------------------------------------------------------===//
1413// Other Lowering Code
1414//===----------------------------------------------------------------------===//
1415
1418 MachineBasicBlock *BB) const {
1419 MachineFunction *F = BB->getParent();
1420 MachineRegisterInfo &RI = F->getRegInfo();
1421 DebugLoc dl = MI.getDebugLoc();
1422 const TargetInstrInfo &TII = *F->getSubtarget().getInstrInfo();
1423
1424 unsigned Opc;
1425 bool ClearCarry = false;
1426 const TargetRegisterClass * RC;
1427 switch (MI.getOpcode()) {
1428 default: llvm_unreachable("Invalid shift opcode!");
1429 case MSP430::Shl8:
1430 Opc = MSP430::ADD8rr;
1431 RC = &MSP430::GR8RegClass;
1432 break;
1433 case MSP430::Shl16:
1434 Opc = MSP430::ADD16rr;
1435 RC = &MSP430::GR16RegClass;
1436 break;
1437 case MSP430::Sra8:
1438 Opc = MSP430::RRA8r;
1439 RC = &MSP430::GR8RegClass;
1440 break;
1441 case MSP430::Sra16:
1442 Opc = MSP430::RRA16r;
1443 RC = &MSP430::GR16RegClass;
1444 break;
1445 case MSP430::Srl8:
1446 ClearCarry = true;
1447 Opc = MSP430::RRC8r;
1448 RC = &MSP430::GR8RegClass;
1449 break;
1450 case MSP430::Srl16:
1451 ClearCarry = true;
1452 Opc = MSP430::RRC16r;
1453 RC = &MSP430::GR16RegClass;
1454 break;
1455 case MSP430::Rrcl8:
1456 case MSP430::Rrcl16: {
1457 BuildMI(*BB, MI, dl, TII.get(MSP430::BIC16rc), MSP430::SR)
1458 .addReg(MSP430::SR).addImm(1);
1459 Register SrcReg = MI.getOperand(1).getReg();
1460 Register DstReg = MI.getOperand(0).getReg();
1461 unsigned RrcOpc = MI.getOpcode() == MSP430::Rrcl16
1462 ? MSP430::RRC16r : MSP430::RRC8r;
1463 BuildMI(*BB, MI, dl, TII.get(RrcOpc), DstReg)
1464 .addReg(SrcReg);
1465 MI.eraseFromParent(); // The pseudo instruction is gone now.
1466 return BB;
1467 }
1468 }
1469
1470 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1472
1473 // Create loop block
1474 MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB);
1475 MachineBasicBlock *RemBB = F->CreateMachineBasicBlock(LLVM_BB);
1476
1477 F->insert(I, LoopBB);
1478 F->insert(I, RemBB);
1479
1480 // Update machine-CFG edges by transferring all successors of the current
1481 // block to the block containing instructions after shift.
1482 RemBB->splice(RemBB->begin(), BB, std::next(MachineBasicBlock::iterator(MI)),
1483 BB->end());
1485
1486 // Add edges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB
1487 BB->addSuccessor(LoopBB);
1488 BB->addSuccessor(RemBB);
1489 LoopBB->addSuccessor(RemBB);
1490 LoopBB->addSuccessor(LoopBB);
1491
1492 Register ShiftAmtReg = RI.createVirtualRegister(&MSP430::GR8RegClass);
1493 Register ShiftAmtReg2 = RI.createVirtualRegister(&MSP430::GR8RegClass);
1494 Register ShiftReg = RI.createVirtualRegister(RC);
1495 Register ShiftReg2 = RI.createVirtualRegister(RC);
1496 Register ShiftAmtSrcReg = MI.getOperand(2).getReg();
1497 Register SrcReg = MI.getOperand(1).getReg();
1498 Register DstReg = MI.getOperand(0).getReg();
1499
1500 // BB:
1501 // cmp 0, N
1502 // je RemBB
1503 BuildMI(BB, dl, TII.get(MSP430::CMP8ri))
1504 .addReg(ShiftAmtSrcReg).addImm(0);
1505 BuildMI(BB, dl, TII.get(MSP430::JCC))
1506 .addMBB(RemBB)
1508
1509 // LoopBB:
1510 // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB]
1511 // ShiftAmt = phi [%N, BB], [%ShiftAmt2, LoopBB]
1512 // ShiftReg2 = shift ShiftReg
1513 // ShiftAmt2 = ShiftAmt - 1;
1514 BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftReg)
1515 .addReg(SrcReg).addMBB(BB)
1516 .addReg(ShiftReg2).addMBB(LoopBB);
1517 BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg)
1518 .addReg(ShiftAmtSrcReg).addMBB(BB)
1519 .addReg(ShiftAmtReg2).addMBB(LoopBB);
1520 if (ClearCarry)
1521 BuildMI(LoopBB, dl, TII.get(MSP430::BIC16rc), MSP430::SR)
1522 .addReg(MSP430::SR).addImm(1);
1523 if (Opc == MSP430::ADD8rr || Opc == MSP430::ADD16rr)
1524 BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2)
1525 .addReg(ShiftReg)
1526 .addReg(ShiftReg);
1527 else
1528 BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2)
1529 .addReg(ShiftReg);
1530 BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2)
1531 .addReg(ShiftAmtReg).addImm(1);
1532 BuildMI(LoopBB, dl, TII.get(MSP430::JCC))
1533 .addMBB(LoopBB)
1535
1536 // RemBB:
1537 // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB]
1538 BuildMI(*RemBB, RemBB->begin(), dl, TII.get(MSP430::PHI), DstReg)
1539 .addReg(SrcReg).addMBB(BB)
1540 .addReg(ShiftReg2).addMBB(LoopBB);
1541
1542 MI.eraseFromParent(); // The pseudo instruction is gone now.
1543 return RemBB;
1544}
1545
1548 MachineBasicBlock *BB) const {
1549 unsigned Opc = MI.getOpcode();
1550
1551 if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 ||
1552 Opc == MSP430::Sra8 || Opc == MSP430::Sra16 ||
1553 Opc == MSP430::Srl8 || Opc == MSP430::Srl16 ||
1554 Opc == MSP430::Rrcl8 || Opc == MSP430::Rrcl16)
1555 return EmitShiftInstr(MI, BB);
1556
1558 DebugLoc dl = MI.getDebugLoc();
1559
1560 assert((Opc == MSP430::Select16 || Opc == MSP430::Select8) &&
1561 "Unexpected instr type to insert");
1562
1563 // To "insert" a SELECT instruction, we actually have to insert the diamond
1564 // control-flow pattern. The incoming instruction knows the destination vreg
1565 // to set, the condition code register to branch on, the true/false values to
1566 // select between, and a branch opcode to use.
1567 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1569
1570 // thisMBB:
1571 // ...
1572 // TrueVal = ...
1573 // cmpTY ccX, r1, r2
1574 // jCC copy1MBB
1575 // fallthrough --> copy0MBB
1576 MachineBasicBlock *thisMBB = BB;
1577 MachineFunction *F = BB->getParent();
1578 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
1579 MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB);
1580 F->insert(I, copy0MBB);
1581 F->insert(I, copy1MBB);
1582 // Update machine-CFG edges by transferring all successors of the current
1583 // block to the new block which will contain the Phi node for the select.
1584 copy1MBB->splice(copy1MBB->begin(), BB,
1585 std::next(MachineBasicBlock::iterator(MI)), BB->end());
1586 copy1MBB->transferSuccessorsAndUpdatePHIs(BB);
1587 // Next, add the true and fallthrough blocks as its successors.
1588 BB->addSuccessor(copy0MBB);
1589 BB->addSuccessor(copy1MBB);
1590
1591 BuildMI(BB, dl, TII.get(MSP430::JCC))
1592 .addMBB(copy1MBB)
1593 .addImm(MI.getOperand(3).getImm());
1594
1595 // copy0MBB:
1596 // %FalseValue = ...
1597 // # fallthrough to copy1MBB
1598 BB = copy0MBB;
1599
1600 // Update machine-CFG edges
1601 BB->addSuccessor(copy1MBB);
1602
1603 // copy1MBB:
1604 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
1605 // ...
1606 BB = copy1MBB;
1607 BuildMI(*BB, BB->begin(), dl, TII.get(MSP430::PHI), MI.getOperand(0).getReg())
1608 .addReg(MI.getOperand(2).getReg())
1609 .addMBB(copy0MBB)
1610 .addReg(MI.getOperand(1).getReg())
1611 .addMBB(thisMBB);
1612
1613 MI.eraseFromParent(); // The pseudo instruction is gone now.
1614 return BB;
1615}
std::string Name
Symbol * Sym
Definition: ELF_riscv.cpp:479
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
#define G(x, y, z)
Definition: MD5.cpp:56
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)
unsigned const TargetRegisterInfo * TRI
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Value * RHS
Value * LHS
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
The address of a basic block.
Definition: Constants.h:890
CCState - This class holds information needed while lowering arguments and return values.
void HandleByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, int MinSize, Align MinAlign, ISD::ArgFlagsTy ArgFlags)
Allocate space on the stack large enough to pass an argument by value.
void AnalyzeCallResult(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeCallResult - Analyze the return values of a call, incorporating info about the passed values i...
CallingConv::ID getCallingConv() const
MCRegister AllocateReg(MCPhysReg Reg)
AllocateReg - Attempt to allocate one register.
void AnalyzeReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeReturn - Analyze the returned values of a return, incorporating info about the result values i...
void AnalyzeCallOperands(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeCallOperands - Analyze the outgoing arguments to a call, incorporating info about the passed v...
bool isVarArg() const
void AnalyzeFormalArguments(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeFormalArguments - Analyze an array of argument values, incorporating info about the formals in...
void addLoc(const CCValAssign &V)
CCValAssign - Represent assignment of one arg/retval to a location.
bool isRegLoc() const
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP, bool IsCustom=false)
bool isMemLoc() const
int64_t getLocMemOffset() const
This class represents an Operation in the Expression.
A debug info location.
Definition: DebugLoc.h:33
bool hasStructRetAttr() const
Determine if the function returns a structure through first or second pointer argument.
Definition: Function.h:686
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
This class is used to represent ISD::LOAD nodes.
MSP430MachineFunctionInfo - This class is derived from MachineFunction and contains private MSP430 ta...
const MSP430RegisterInfo * getRegisterInfo() const override
bool hasHWMultF5() const
bool hasHWMult32() const
bool hasHWMult16() const
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
const char * getTargetNodeName(unsigned Opcode) const override
getTargetNodeName - This method returns the name of a target specific DAG node.
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.
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
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.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
Definition: MachineInstr.h:69
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
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...
Definition: SelectionDAG.h:226
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:736
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), AAResults *AA=nullptr)
SDValue 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,...
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
Definition: SelectionDAG.h:746
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
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
Definition: SelectionDAG.h:487
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
SDValue getRegister(unsigned Reg, EVT VT)
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
Definition: SelectionDAG.h:787
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
SDValue getValueType(EVT)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:782
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:482
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
Definition: SelectionDAG.h:813
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVMContext * getContext() const
Definition: SelectionDAG.h:500
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:570
bool empty() const
Definition: SmallVector.h:94
size_t size() const
Definition: SmallVector.h:91
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
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...
void setCmpLibcallCC(RTLIB::Libcall Call, ISD::CondCode CC)
Override the default CondCode to be used to test the result of the comparison libcall against zero.
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 setLibcallCallingConv(RTLIB::Libcall Call, CallingConv::ID CC)
Set the CallingConv that should be used for the specified libcall.
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 setLibcallName(RTLIB::Libcall Call, const char *Name)
Rename the default libcall routine name for the specified libcall.
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...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
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.
bool verifyReturnAddressArgumentIsConstant(SDValue Op, SelectionDAG &DAG) const
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:77
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:224
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM Value Representation.
Definition: Value.h:74
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition: Value.h:434
constexpr ScalarTy getFixedValue() const
Definition: TypeSize.h:202
self_iterator getIterator()
Definition: ilist_node.h:132
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
CondCodes
Definition: MSP430.h:22
@ COND_LO
Definition: MSP430.h:26
@ COND_L
Definition: MSP430.h:28
@ COND_INVALID
Definition: MSP430.h:32
@ COND_E
Definition: MSP430.h:23
@ COND_GE
Definition: MSP430.h:27
@ COND_NE
Definition: MSP430.h:24
@ COND_HS
Definition: MSP430.h:25
@ MSP430_BUILTIN
Used for special MSP430 rtlib functions which have an "optimized" convention using additional registe...
Definition: CallingConv.h:210
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition: CallingConv.h:41
@ MSP430_INTR
Used for MSP430 interrupt routines.
Definition: CallingConv.h:117
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition: ISDOpcodes.h:779
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
Definition: ISDOpcodes.h:1194
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition: ISDOpcodes.h:1190
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition: ISDOpcodes.h:257
@ BSWAP
Byte Swap and Counting operators.
Definition: ISDOpcodes.h:743
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
Definition: ISDOpcodes.h:1223
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:246
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition: ISDOpcodes.h:813
@ GlobalAddress
Definition: ISDOpcodes.h:78
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition: ISDOpcodes.h:262
@ SIGN_EXTEND
Conversion operators.
Definition: ISDOpcodes.h:804
@ BR_CC
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:1145
@ BR_JT
BR_JT - Jumptable branch.
Definition: ISDOpcodes.h:1124
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition: ISDOpcodes.h:756
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
Definition: ISDOpcodes.h:1219
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition: ISDOpcodes.h:673
@ SHL
Shift and rotation operations.
Definition: ISDOpcodes.h:734
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition: ISDOpcodes.h:810
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition: ISDOpcodes.h:771
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
Definition: ISDOpcodes.h:1109
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition: ISDOpcodes.h:848
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition: ISDOpcodes.h:100
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:708
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition: ISDOpcodes.h:52
@ ExternalSymbol
Definition: ISDOpcodes.h:83
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition: ISDOpcodes.h:816
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
Definition: ISDOpcodes.h:1214
@ BRCOND
BRCOND - Conditional branch.
Definition: ISDOpcodes.h:1138
@ BlockAddress
Definition: ISDOpcodes.h:84
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
Definition: ISDOpcodes.h:793
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition: ISDOpcodes.h:61
@ AssertZext
Definition: ISDOpcodes.h:62
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
Definition: ISDOpcodes.h:1552
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
Definition: ISDOpcodes.h:1603
@ CALL
CALL - These operations represent an abstract call instruction, which includes a bunch of information...
@ RRA
Y = R{R,L}A X, rotate right (left) arithmetically.
@ BR_CC
MSP430 conditional branches.
@ DADD
DADD - Decimal addition with carry TODO Nothing generates a node of this type yet.
@ SETCC
SetCC - Operand 0 is condition code, and operand 1 is the flag operand produced by a CMP instruction.
@ RRCL
Rotate right via carry, carry gets cleared beforehand by clrc.
@ RETI_GLUE
Same as RET_GLUE, but used for returning from ISRs.
@ SELECT_CC
SELECT_CC - Operand 0 and operand 1 are selection variable, operand 3 is condition code and operand 4...
@ CMP
CMP - Compare instruction.
@ RRC
Y = RRC X, rotate right via carry.
@ Wrapper
Wrapper - A wrapper node for TargetConstantPool, TargetExternalSymbol, and TargetGlobalAddress.
@ RET_GLUE
Return with a glue operand. Operand 0 is the chain operand.
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit.
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
DWARFExpression::Operation Op
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:860
#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:381
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:307
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
Definition: ValueTypes.h:367
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition: ValueTypes.h:152
This class contains a discriminated union of information about pointers in memory operands,...
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals