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