LLVM 17.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)
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
336}
337
339 SelectionDAG &DAG) const {
340 switch (Op.getOpcode()) {
341 case ISD::SHL: // FALLTHROUGH
342 case ISD::SRL:
343 case ISD::SRA: return LowerShifts(Op, DAG);
344 case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
345 case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
346 case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG);
347 case ISD::SETCC: return LowerSETCC(Op, DAG);
348 case ISD::BR_CC: return LowerBR_CC(Op, DAG);
349 case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
350 case ISD::SIGN_EXTEND: return LowerSIGN_EXTEND(Op, DAG);
351 case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
352 case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
353 case ISD::VASTART: return LowerVASTART(Op, DAG);
354 case ISD::JumpTable: return LowerJumpTable(Op, DAG);
355 default:
356 llvm_unreachable("unimplemented operand");
357 }
358}
359
360// Define non profitable transforms into shifts
362 unsigned Amount) const {
363 return !(Amount == 8 || Amount == 9 || Amount<=2);
364}
365
366// Implemented to verify test case assertions in
367// tests/codegen/msp430/shift-amount-threshold-b.ll
370 return Immed >= -32 && Immed < 32;
372}
373
374//===----------------------------------------------------------------------===//
375// MSP430 Inline Assembly Support
376//===----------------------------------------------------------------------===//
377
378/// getConstraintType - Given a constraint letter, return the type of
379/// constraint it is for this target.
382 if (Constraint.size() == 1) {
383 switch (Constraint[0]) {
384 case 'r':
385 return C_RegisterClass;
386 default:
387 break;
388 }
389 }
390 return TargetLowering::getConstraintType(Constraint);
391}
392
393std::pair<unsigned, const TargetRegisterClass *>
395 const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
396 if (Constraint.size() == 1) {
397 // GCC Constraint Letters
398 switch (Constraint[0]) {
399 default: break;
400 case 'r': // GENERAL_REGS
401 if (VT == MVT::i8)
402 return std::make_pair(0U, &MSP430::GR8RegClass);
403
404 return std::make_pair(0U, &MSP430::GR16RegClass);
405 }
406 }
407
409}
410
411//===----------------------------------------------------------------------===//
412// Calling Convention Implementation
413//===----------------------------------------------------------------------===//
414
415#include "MSP430GenCallingConv.inc"
416
417/// For each argument in a function store the number of pieces it is composed
418/// of.
419template<typename ArgT>
422 unsigned CurrentArgIndex;
423
424 if (Args.empty())
425 return;
426
427 CurrentArgIndex = Args[0].OrigArgIndex;
428 Out.push_back(0);
429
430 for (auto &Arg : Args) {
431 if (CurrentArgIndex == Arg.OrigArgIndex) {
432 Out.back() += 1;
433 } else {
434 Out.push_back(1);
435 CurrentArgIndex = Arg.OrigArgIndex;
436 }
437 }
438}
439
440static void AnalyzeVarArgs(CCState &State,
442 State.AnalyzeCallOperands(Outs, CC_MSP430_AssignStack);
443}
444
445static void AnalyzeVarArgs(CCState &State,
447 State.AnalyzeFormalArguments(Ins, CC_MSP430_AssignStack);
448}
449
450/// Analyze incoming and outgoing function arguments. We need custom C++ code
451/// to handle special constraints in the ABI like reversing the order of the
452/// pieces of splitted arguments. In addition, all pieces of a certain argument
453/// have to be passed either using registers or the stack but never mixing both.
454template<typename ArgT>
455static void AnalyzeArguments(CCState &State,
457 const SmallVectorImpl<ArgT> &Args) {
458 static const MCPhysReg CRegList[] = {
459 MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15
460 };
461 static const unsigned CNbRegs = std::size(CRegList);
462 static const MCPhysReg BuiltinRegList[] = {
463 MSP430::R8, MSP430::R9, MSP430::R10, MSP430::R11,
464 MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15
465 };
466 static const unsigned BuiltinNbRegs = std::size(BuiltinRegList);
467
468 ArrayRef<MCPhysReg> RegList;
469 unsigned NbRegs;
470
471 bool Builtin = (State.getCallingConv() == CallingConv::MSP430_BUILTIN);
472 if (Builtin) {
473 RegList = BuiltinRegList;
474 NbRegs = BuiltinNbRegs;
475 } else {
476 RegList = CRegList;
477 NbRegs = CNbRegs;
478 }
479
480 if (State.isVarArg()) {
481 AnalyzeVarArgs(State, Args);
482 return;
483 }
484
485 SmallVector<unsigned, 4> ArgsParts;
486 ParseFunctionArgs(Args, ArgsParts);
487
488 if (Builtin) {
489 assert(ArgsParts.size() == 2 &&
490 "Builtin calling convention requires two arguments");
491 }
492
493 unsigned RegsLeft = NbRegs;
494 bool UsedStack = false;
495 unsigned ValNo = 0;
496
497 for (unsigned i = 0, e = ArgsParts.size(); i != e; i++) {
498 MVT ArgVT = Args[ValNo].VT;
499 ISD::ArgFlagsTy ArgFlags = Args[ValNo].Flags;
500 MVT LocVT = ArgVT;
502
503 // Promote i8 to i16
504 if (LocVT == MVT::i8) {
505 LocVT = MVT::i16;
506 if (ArgFlags.isSExt())
507 LocInfo = CCValAssign::SExt;
508 else if (ArgFlags.isZExt())
509 LocInfo = CCValAssign::ZExt;
510 else
511 LocInfo = CCValAssign::AExt;
512 }
513
514 // Handle byval arguments
515 if (ArgFlags.isByVal()) {
516 State.HandleByVal(ValNo++, ArgVT, LocVT, LocInfo, 2, Align(2), ArgFlags);
517 continue;
518 }
519
520 unsigned Parts = ArgsParts[i];
521
522 if (Builtin) {
523 assert(Parts == 4 &&
524 "Builtin calling convention requires 64-bit arguments");
525 }
526
527 if (!UsedStack && Parts == 2 && RegsLeft == 1) {
528 // Special case for 32-bit register split, see EABI section 3.3.3
529 unsigned Reg = State.AllocateReg(RegList);
530 State.addLoc(CCValAssign::getReg(ValNo++, ArgVT, Reg, LocVT, LocInfo));
531 RegsLeft -= 1;
532
533 UsedStack = true;
534 CC_MSP430_AssignStack(ValNo++, ArgVT, LocVT, LocInfo, ArgFlags, State);
535 } else if (Parts <= RegsLeft) {
536 for (unsigned j = 0; j < Parts; j++) {
537 unsigned Reg = State.AllocateReg(RegList);
538 State.addLoc(CCValAssign::getReg(ValNo++, ArgVT, Reg, LocVT, LocInfo));
539 RegsLeft--;
540 }
541 } else {
542 UsedStack = true;
543 for (unsigned j = 0; j < Parts; j++)
544 CC_MSP430_AssignStack(ValNo++, ArgVT, LocVT, LocInfo, ArgFlags, State);
545 }
546 }
547}
548
549static void AnalyzeRetResult(CCState &State,
551 State.AnalyzeCallResult(Ins, RetCC_MSP430);
552}
553
554static void AnalyzeRetResult(CCState &State,
556 State.AnalyzeReturn(Outs, RetCC_MSP430);
557}
558
559template<typename ArgT>
560static void AnalyzeReturnValues(CCState &State,
562 const SmallVectorImpl<ArgT> &Args) {
563 AnalyzeRetResult(State, Args);
564}
565
566SDValue MSP430TargetLowering::LowerFormalArguments(
567 SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
568 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
569 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
570
571 switch (CallConv) {
572 default:
573 report_fatal_error("Unsupported calling convention");
574 case CallingConv::C:
576 return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals);
578 if (Ins.empty())
579 return Chain;
580 report_fatal_error("ISRs cannot have arguments");
581 }
582}
583
585MSP430TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
586 SmallVectorImpl<SDValue> &InVals) const {
587 SelectionDAG &DAG = CLI.DAG;
588 SDLoc &dl = CLI.DL;
590 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
592 SDValue Chain = CLI.Chain;
593 SDValue Callee = CLI.Callee;
594 bool &isTailCall = CLI.IsTailCall;
595 CallingConv::ID CallConv = CLI.CallConv;
596 bool isVarArg = CLI.IsVarArg;
597
598 // MSP430 target does not yet support tail call optimization.
599 isTailCall = false;
600
601 switch (CallConv) {
602 default:
603 report_fatal_error("Unsupported calling convention");
606 case CallingConv::C:
607 return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
608 Outs, OutVals, Ins, dl, DAG, InVals);
610 report_fatal_error("ISRs cannot be called directly");
611 }
612}
613
614/// LowerCCCArguments - transform physical registers into virtual registers and
615/// generate load operations for arguments places on the stack.
616// FIXME: struct return stuff
617SDValue MSP430TargetLowering::LowerCCCArguments(
618 SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
619 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
620 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
622 MachineFrameInfo &MFI = MF.getFrameInfo();
625
626 // Assign locations to all of the incoming arguments.
628 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
629 *DAG.getContext());
630 AnalyzeArguments(CCInfo, ArgLocs, Ins);
631
632 // Create frame index for the start of the first vararg value
633 if (isVarArg) {
634 unsigned Offset = CCInfo.getStackSize();
635 FuncInfo->setVarArgsFrameIndex(MFI.CreateFixedObject(1, Offset, true));
636 }
637
638 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
639 CCValAssign &VA = ArgLocs[i];
640 if (VA.isRegLoc()) {
641 // Arguments passed in registers
642 EVT RegVT = VA.getLocVT();
643 switch (RegVT.getSimpleVT().SimpleTy) {
644 default:
645 {
646#ifndef NDEBUG
647 errs() << "LowerFormalArguments Unhandled argument type: "
648 << RegVT << "\n";
649#endif
650 llvm_unreachable(nullptr);
651 }
652 case MVT::i16:
653 Register VReg = RegInfo.createVirtualRegister(&MSP430::GR16RegClass);
654 RegInfo.addLiveIn(VA.getLocReg(), VReg);
655 SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, RegVT);
656
657 // If this is an 8-bit value, it is really passed promoted to 16
658 // bits. Insert an assert[sz]ext to capture this, then truncate to the
659 // right size.
660 if (VA.getLocInfo() == CCValAssign::SExt)
661 ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue,
662 DAG.getValueType(VA.getValVT()));
663 else if (VA.getLocInfo() == CCValAssign::ZExt)
664 ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue,
665 DAG.getValueType(VA.getValVT()));
666
667 if (VA.getLocInfo() != CCValAssign::Full)
668 ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
669
670 InVals.push_back(ArgValue);
671 }
672 } else {
673 // Only arguments passed on the stack should make it here.
674 assert(VA.isMemLoc());
675
676 SDValue InVal;
677 ISD::ArgFlagsTy Flags = Ins[i].Flags;
678
679 if (Flags.isByVal()) {
680 MVT PtrVT = VA.getLocVT();
681 int FI = MFI.CreateFixedObject(Flags.getByValSize(),
682 VA.getLocMemOffset(), true);
683 InVal = DAG.getFrameIndex(FI, PtrVT);
684 } else {
685 // Load the argument to a virtual register
686 unsigned ObjSize = VA.getLocVT().getSizeInBits()/8;
687 if (ObjSize > 2) {
688 errs() << "LowerFormalArguments Unhandled argument type: "
689 << VA.getLocVT() << "\n";
690 }
691 // Create the frame index object for this incoming parameter...
692 int FI = MFI.CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);
693
694 // Create the SelectionDAG nodes corresponding to a load
695 //from this parameter
696 SDValue FIN = DAG.getFrameIndex(FI, MVT::i16);
697 InVal = DAG.getLoad(
698 VA.getLocVT(), dl, Chain, FIN,
700 }
701
702 InVals.push_back(InVal);
703 }
704 }
705
706 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
707 if (Ins[i].Flags.isSRet()) {
708 Register Reg = FuncInfo->getSRetReturnReg();
709 if (!Reg) {
711 getRegClassFor(MVT::i16));
712 FuncInfo->setSRetReturnReg(Reg);
713 }
714 SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, InVals[i]);
715 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain);
716 }
717 }
718
719 return Chain;
720}
721
722bool
723MSP430TargetLowering::CanLowerReturn(CallingConv::ID CallConv,
724 MachineFunction &MF,
725 bool IsVarArg,
727 LLVMContext &Context) const {
729 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
730 return CCInfo.CheckReturn(Outs, RetCC_MSP430);
731}
732
734MSP430TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
735 bool isVarArg,
737 const SmallVectorImpl<SDValue> &OutVals,
738 const SDLoc &dl, SelectionDAG &DAG) const {
739
741
742 // CCValAssign - represent the assignment of the return value to a location
744
745 // ISRs cannot return any value.
746 if (CallConv == CallingConv::MSP430_INTR && !Outs.empty())
747 report_fatal_error("ISRs cannot return any value");
748
749 // CCState - Info about the registers and stack slot.
750 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
751 *DAG.getContext());
752
753 // Analize return values.
754 AnalyzeReturnValues(CCInfo, RVLocs, Outs);
755
756 SDValue Glue;
757 SmallVector<SDValue, 4> RetOps(1, Chain);
758
759 // Copy the result values into the output registers.
760 for (unsigned i = 0; i != RVLocs.size(); ++i) {
761 CCValAssign &VA = RVLocs[i];
762 assert(VA.isRegLoc() && "Can only return in registers!");
763
764 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
765 OutVals[i], Glue);
766
767 // Guarantee that all emitted copies are stuck together,
768 // avoiding something bad.
769 Glue = Chain.getValue(1);
770 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
771 }
772
773 if (MF.getFunction().hasStructRetAttr()) {
775 Register Reg = FuncInfo->getSRetReturnReg();
776
777 if (!Reg)
778 llvm_unreachable("sret virtual register not created in entry block");
779
780 MVT PtrVT = getFrameIndexTy(DAG.getDataLayout());
781 SDValue Val =
782 DAG.getCopyFromReg(Chain, dl, Reg, PtrVT);
783 unsigned R12 = MSP430::R12;
784
785 Chain = DAG.getCopyToReg(Chain, dl, R12, Val, Glue);
786 Glue = Chain.getValue(1);
787 RetOps.push_back(DAG.getRegister(R12, PtrVT));
788 }
789
790 unsigned Opc = (CallConv == CallingConv::MSP430_INTR ?
792
793 RetOps[0] = Chain; // Update chain.
794
795 // Add the glue if we have it.
796 if (Glue.getNode())
797 RetOps.push_back(Glue);
798
799 return DAG.getNode(Opc, dl, MVT::Other, RetOps);
800}
801
802/// LowerCCCCallTo - functions arguments are copied from virtual regs to
803/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
804SDValue MSP430TargetLowering::LowerCCCCallTo(
805 SDValue Chain, SDValue Callee, CallingConv::ID CallConv, bool isVarArg,
806 bool isTailCall, const SmallVectorImpl<ISD::OutputArg> &Outs,
807 const SmallVectorImpl<SDValue> &OutVals,
808 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
809 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
810 // Analyze operands of the call, assigning locations to each operand.
812 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
813 *DAG.getContext());
814 AnalyzeArguments(CCInfo, ArgLocs, Outs);
815
816 // Get a count of how many bytes are to be pushed on the stack.
817 unsigned NumBytes = CCInfo.getStackSize();
818 MVT PtrVT = getFrameIndexTy(DAG.getDataLayout());
819
820 Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, dl);
821
823 SmallVector<SDValue, 12> MemOpChains;
825
826 // Walk the register/memloc assignments, inserting copies/loads.
827 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
828 CCValAssign &VA = ArgLocs[i];
829
830 SDValue Arg = OutVals[i];
831
832 // Promote the value if needed.
833 switch (VA.getLocInfo()) {
834 default: llvm_unreachable("Unknown loc info!");
835 case CCValAssign::Full: break;
837 Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
838 break;
840 Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
841 break;
843 Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
844 break;
845 }
846
847 // Arguments that can be passed on register must be kept at RegsToPass
848 // vector
849 if (VA.isRegLoc()) {
850 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
851 } else {
852 assert(VA.isMemLoc());
853
854 if (!StackPtr.getNode())
855 StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SP, PtrVT);
856
857 SDValue PtrOff =
858 DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr,
859 DAG.getIntPtrConstant(VA.getLocMemOffset(), dl));
860
862 ISD::ArgFlagsTy Flags = Outs[i].Flags;
863
864 if (Flags.isByVal()) {
865 SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), dl, MVT::i16);
866 MemOp = DAG.getMemcpy(
867 Chain, dl, PtrOff, Arg, SizeNode, Flags.getNonZeroByValAlign(),
868 /*isVolatile*/ false,
869 /*AlwaysInline=*/true,
870 /*isTailCall=*/false, MachinePointerInfo(), MachinePointerInfo());
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 = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
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 = false;
1152 if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) {
1153 if (RHSC->isZero() && LHS.hasOneUse() &&
1154 (LHS.getOpcode() == ISD::AND ||
1155 (LHS.getOpcode() == ISD::TRUNCATE &&
1156 LHS.getOperand(0).getOpcode() == ISD::AND))) {
1157 andCC = true;
1158 }
1159 }
1160 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
1161 SDValue TargetCC;
1162 SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
1163
1164 // Get the condition codes directly from the status register, if its easy.
1165 // Otherwise a branch will be generated. Note that the AND and BIT
1166 // instructions generate different flags than CMP, the carry bit can be used
1167 // for NE/EQ.
1168 bool Invert = false;
1169 bool Shift = false;
1170 bool Convert = true;
1171 switch (cast<ConstantSDNode>(TargetCC)->getZExtValue()) {
1172 default:
1173 Convert = false;
1174 break;
1175 case MSP430CC::COND_HS:
1176 // Res = SR & 1, no processing is required
1177 break;
1178 case MSP430CC::COND_LO:
1179 // Res = ~(SR & 1)
1180 Invert = true;
1181 break;
1182 case MSP430CC::COND_NE:
1183 if (andCC) {
1184 // C = ~Z, thus Res = SR & 1, no processing is required
1185 } else {
1186 // Res = ~((SR >> 1) & 1)
1187 Shift = true;
1188 Invert = true;
1189 }
1190 break;
1191 case MSP430CC::COND_E:
1192 Shift = true;
1193 // C = ~Z for AND instruction, thus we can put Res = ~(SR & 1), however,
1194 // Res = (SR >> 1) & 1 is 1 word shorter.
1195 break;
1196 }
1197 EVT VT = Op.getValueType();
1198 SDValue One = DAG.getConstant(1, dl, VT);
1199 if (Convert) {
1200 SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SR,
1201 MVT::i16, Flag);
1202 if (Shift)
1203 // FIXME: somewhere this is turned into a SRL, lower it MSP specific?
1204 SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One);
1205 SR = DAG.getNode(ISD::AND, dl, MVT::i16, SR, One);
1206 if (Invert)
1207 SR = DAG.getNode(ISD::XOR, dl, MVT::i16, SR, One);
1208 return SR;
1209 } else {
1210 SDValue Zero = DAG.getConstant(0, dl, VT);
1211 SDValue Ops[] = {One, Zero, TargetCC, Flag};
1212 return DAG.getNode(MSP430ISD::SELECT_CC, dl, Op.getValueType(), Ops);
1213 }
1214}
1215
1217 SelectionDAG &DAG) const {
1218 SDValue LHS = Op.getOperand(0);
1219 SDValue RHS = Op.getOperand(1);
1220 SDValue TrueV = Op.getOperand(2);
1221 SDValue FalseV = Op.getOperand(3);
1222 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
1223 SDLoc dl (Op);
1224
1225 SDValue TargetCC;
1226 SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
1227
1228 SDValue Ops[] = {TrueV, FalseV, TargetCC, Flag};
1229
1230 return DAG.getNode(MSP430ISD::SELECT_CC, dl, Op.getValueType(), Ops);
1231}
1232
1234 SelectionDAG &DAG) const {
1235 SDValue Val = Op.getOperand(0);
1236 EVT VT = Op.getValueType();
1237 SDLoc dl(Op);
1238
1239 assert(VT == MVT::i16 && "Only support i16 for now!");
1240
1241 return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT,
1242 DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val),
1243 DAG.getValueType(Val.getValueType()));
1244}
1245
1246SDValue
1250 int ReturnAddrIndex = FuncInfo->getRAIndex();
1251 MVT PtrVT = getFrameIndexTy(MF.getDataLayout());
1252
1253 if (ReturnAddrIndex == 0) {
1254 // Set up a frame object for the return address.
1255 uint64_t SlotSize = PtrVT.getStoreSize();
1256 ReturnAddrIndex = MF.getFrameInfo().CreateFixedObject(SlotSize, -SlotSize,
1257 true);
1258 FuncInfo->setRAIndex(ReturnAddrIndex);
1259 }
1260
1261 return DAG.getFrameIndex(ReturnAddrIndex, PtrVT);
1262}
1263
1265 SelectionDAG &DAG) const {
1267 MFI.setReturnAddressIsTaken(true);
1268
1270 return SDValue();
1271
1272 unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
1273 SDLoc dl(Op);
1274 EVT PtrVT = Op.getValueType();
1275
1276 if (Depth > 0) {
1277 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
1278 SDValue Offset =
1279 DAG.getConstant(PtrVT.getStoreSize(), dl, MVT::i16);
1280 return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(),
1281 DAG.getNode(ISD::ADD, dl, PtrVT, FrameAddr, Offset),
1283 }
1284
1285 // Just load the return address.
1286 SDValue RetAddrFI = getReturnAddressFrameIndex(DAG);
1287 return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), RetAddrFI,
1289}
1290
1292 SelectionDAG &DAG) const {
1294 MFI.setFrameAddressIsTaken(true);
1295
1296 EVT VT = Op.getValueType();
1297 SDLoc dl(Op); // FIXME probably not meaningful
1298 unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
1299 SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl,
1300 MSP430::R4, VT);
1301 while (Depth--)
1302 FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
1304 return FrameAddr;
1305}
1306
1308 SelectionDAG &DAG) const {
1311
1312 SDValue Ptr = Op.getOperand(1);
1313 EVT PtrVT = Ptr.getValueType();
1314
1315 // Frame index of first vararg argument
1316 SDValue FrameIndex =
1317 DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);
1318 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
1319
1320 // Create a store of the frame index to the location operand
1321 return DAG.getStore(Op.getOperand(0), SDLoc(Op), FrameIndex, Ptr,
1322 MachinePointerInfo(SV));
1323}
1324
1326 SelectionDAG &DAG) const {
1327 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
1328 EVT PtrVT = Op.getValueType();
1329 SDValue Result = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
1330 return DAG.getNode(MSP430ISD::Wrapper, SDLoc(JT), PtrVT, Result);
1331}
1332
1333/// getPostIndexedAddressParts - returns true by value, base pointer and
1334/// offset pointer and addressing mode by reference if this node can be
1335/// combined with a load / store to form a post-indexed load / store.
1336bool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
1337 SDValue &Base,
1338 SDValue &Offset,
1340 SelectionDAG &DAG) const {
1341
1342 LoadSDNode *LD = cast<LoadSDNode>(N);
1343 if (LD->getExtensionType() != ISD::NON_EXTLOAD)
1344 return false;
1345
1346 EVT VT = LD->getMemoryVT();
1347 if (VT != MVT::i8 && VT != MVT::i16)
1348 return false;
1349
1350 if (Op->getOpcode() != ISD::ADD)
1351 return false;
1352
1353 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) {
1354 uint64_t RHSC = RHS->getZExtValue();
1355 if ((VT == MVT::i16 && RHSC != 2) ||
1356 (VT == MVT::i8 && RHSC != 1))
1357 return false;
1358
1359 Base = Op->getOperand(0);
1360 Offset = DAG.getConstant(RHSC, SDLoc(N), VT);
1361 AM = ISD::POST_INC;
1362 return true;
1363 }
1364
1365 return false;
1366}
1367
1368
1369const char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
1370 switch ((MSP430ISD::NodeType)Opcode) {
1371 case MSP430ISD::FIRST_NUMBER: break;
1372 case MSP430ISD::RET_GLUE: return "MSP430ISD::RET_GLUE";
1373 case MSP430ISD::RETI_GLUE: return "MSP430ISD::RETI_GLUE";
1374 case MSP430ISD::RRA: return "MSP430ISD::RRA";
1375 case MSP430ISD::RLA: return "MSP430ISD::RLA";
1376 case MSP430ISD::RRC: return "MSP430ISD::RRC";
1377 case MSP430ISD::RRCL: return "MSP430ISD::RRCL";
1378 case MSP430ISD::CALL: return "MSP430ISD::CALL";
1379 case MSP430ISD::Wrapper: return "MSP430ISD::Wrapper";
1380 case MSP430ISD::BR_CC: return "MSP430ISD::BR_CC";
1381 case MSP430ISD::CMP: return "MSP430ISD::CMP";
1382 case MSP430ISD::SETCC: return "MSP430ISD::SETCC";
1383 case MSP430ISD::SELECT_CC: return "MSP430ISD::SELECT_CC";
1384 case MSP430ISD::DADD: return "MSP430ISD::DADD";
1385 }
1386 return nullptr;
1387}
1388
1390 Type *Ty2) const {
1391 if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
1392 return false;
1393
1394 return (Ty1->getPrimitiveSizeInBits().getFixedValue() >
1396}
1397
1399 if (!VT1.isInteger() || !VT2.isInteger())
1400 return false;
1401
1402 return (VT1.getFixedSizeInBits() > VT2.getFixedSizeInBits());
1403}
1404
1406 // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
1407 return false && Ty1->isIntegerTy(8) && Ty2->isIntegerTy(16);
1408}
1409
1411 // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
1412 return false && VT1 == MVT::i8 && VT2 == MVT::i16;
1413}
1414
1415//===----------------------------------------------------------------------===//
1416// Other Lowering Code
1417//===----------------------------------------------------------------------===//
1418
1421 MachineBasicBlock *BB) const {
1422 MachineFunction *F = BB->getParent();
1423 MachineRegisterInfo &RI = F->getRegInfo();
1424 DebugLoc dl = MI.getDebugLoc();
1425 const TargetInstrInfo &TII = *F->getSubtarget().getInstrInfo();
1426
1427 unsigned Opc;
1428 bool ClearCarry = false;
1429 const TargetRegisterClass * RC;
1430 switch (MI.getOpcode()) {
1431 default: llvm_unreachable("Invalid shift opcode!");
1432 case MSP430::Shl8:
1433 Opc = MSP430::ADD8rr;
1434 RC = &MSP430::GR8RegClass;
1435 break;
1436 case MSP430::Shl16:
1437 Opc = MSP430::ADD16rr;
1438 RC = &MSP430::GR16RegClass;
1439 break;
1440 case MSP430::Sra8:
1441 Opc = MSP430::RRA8r;
1442 RC = &MSP430::GR8RegClass;
1443 break;
1444 case MSP430::Sra16:
1445 Opc = MSP430::RRA16r;
1446 RC = &MSP430::GR16RegClass;
1447 break;
1448 case MSP430::Srl8:
1449 ClearCarry = true;
1450 Opc = MSP430::RRC8r;
1451 RC = &MSP430::GR8RegClass;
1452 break;
1453 case MSP430::Srl16:
1454 ClearCarry = true;
1455 Opc = MSP430::RRC16r;
1456 RC = &MSP430::GR16RegClass;
1457 break;
1458 case MSP430::Rrcl8:
1459 case MSP430::Rrcl16: {
1460 BuildMI(*BB, MI, dl, TII.get(MSP430::BIC16rc), MSP430::SR)
1461 .addReg(MSP430::SR).addImm(1);
1462 Register SrcReg = MI.getOperand(1).getReg();
1463 Register DstReg = MI.getOperand(0).getReg();
1464 unsigned RrcOpc = MI.getOpcode() == MSP430::Rrcl16
1465 ? MSP430::RRC16r : MSP430::RRC8r;
1466 BuildMI(*BB, MI, dl, TII.get(RrcOpc), DstReg)
1467 .addReg(SrcReg);
1468 MI.eraseFromParent(); // The pseudo instruction is gone now.
1469 return BB;
1470 }
1471 }
1472
1473 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1475
1476 // Create loop block
1477 MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB);
1478 MachineBasicBlock *RemBB = F->CreateMachineBasicBlock(LLVM_BB);
1479
1480 F->insert(I, LoopBB);
1481 F->insert(I, RemBB);
1482
1483 // Update machine-CFG edges by transferring all successors of the current
1484 // block to the block containing instructions after shift.
1485 RemBB->splice(RemBB->begin(), BB, std::next(MachineBasicBlock::iterator(MI)),
1486 BB->end());
1488
1489 // Add edges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB
1490 BB->addSuccessor(LoopBB);
1491 BB->addSuccessor(RemBB);
1492 LoopBB->addSuccessor(RemBB);
1493 LoopBB->addSuccessor(LoopBB);
1494
1495 Register ShiftAmtReg = RI.createVirtualRegister(&MSP430::GR8RegClass);
1496 Register ShiftAmtReg2 = RI.createVirtualRegister(&MSP430::GR8RegClass);
1497 Register ShiftReg = RI.createVirtualRegister(RC);
1498 Register ShiftReg2 = RI.createVirtualRegister(RC);
1499 Register ShiftAmtSrcReg = MI.getOperand(2).getReg();
1500 Register SrcReg = MI.getOperand(1).getReg();
1501 Register DstReg = MI.getOperand(0).getReg();
1502
1503 // BB:
1504 // cmp 0, N
1505 // je RemBB
1506 BuildMI(BB, dl, TII.get(MSP430::CMP8ri))
1507 .addReg(ShiftAmtSrcReg).addImm(0);
1508 BuildMI(BB, dl, TII.get(MSP430::JCC))
1509 .addMBB(RemBB)
1511
1512 // LoopBB:
1513 // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB]
1514 // ShiftAmt = phi [%N, BB], [%ShiftAmt2, LoopBB]
1515 // ShiftReg2 = shift ShiftReg
1516 // ShiftAmt2 = ShiftAmt - 1;
1517 BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftReg)
1518 .addReg(SrcReg).addMBB(BB)
1519 .addReg(ShiftReg2).addMBB(LoopBB);
1520 BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg)
1521 .addReg(ShiftAmtSrcReg).addMBB(BB)
1522 .addReg(ShiftAmtReg2).addMBB(LoopBB);
1523 if (ClearCarry)
1524 BuildMI(LoopBB, dl, TII.get(MSP430::BIC16rc), MSP430::SR)
1525 .addReg(MSP430::SR).addImm(1);
1526 if (Opc == MSP430::ADD8rr || Opc == MSP430::ADD16rr)
1527 BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2)
1528 .addReg(ShiftReg)
1529 .addReg(ShiftReg);
1530 else
1531 BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2)
1532 .addReg(ShiftReg);
1533 BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2)
1534 .addReg(ShiftAmtReg).addImm(1);
1535 BuildMI(LoopBB, dl, TII.get(MSP430::JCC))
1536 .addMBB(LoopBB)
1538
1539 // RemBB:
1540 // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB]
1541 BuildMI(*RemBB, RemBB->begin(), dl, TII.get(MSP430::PHI), DstReg)
1542 .addReg(SrcReg).addMBB(BB)
1543 .addReg(ShiftReg2).addMBB(LoopBB);
1544
1545 MI.eraseFromParent(); // The pseudo instruction is gone now.
1546 return RemBB;
1547}
1548
1551 MachineBasicBlock *BB) const {
1552 unsigned Opc = MI.getOpcode();
1553
1554 if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 ||
1555 Opc == MSP430::Sra8 || Opc == MSP430::Sra16 ||
1556 Opc == MSP430::Srl8 || Opc == MSP430::Srl16 ||
1557 Opc == MSP430::Rrcl8 || Opc == MSP430::Rrcl16)
1558 return EmitShiftInstr(MI, BB);
1559
1561 DebugLoc dl = MI.getDebugLoc();
1562
1563 assert((Opc == MSP430::Select16 || Opc == MSP430::Select8) &&
1564 "Unexpected instr type to insert");
1565
1566 // To "insert" a SELECT instruction, we actually have to insert the diamond
1567 // control-flow pattern. The incoming instruction knows the destination vreg
1568 // to set, the condition code register to branch on, the true/false values to
1569 // select between, and a branch opcode to use.
1570 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1572
1573 // thisMBB:
1574 // ...
1575 // TrueVal = ...
1576 // cmpTY ccX, r1, r2
1577 // jCC copy1MBB
1578 // fallthrough --> copy0MBB
1579 MachineBasicBlock *thisMBB = BB;
1580 MachineFunction *F = BB->getParent();
1581 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
1582 MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB);
1583 F->insert(I, copy0MBB);
1584 F->insert(I, copy1MBB);
1585 // Update machine-CFG edges by transferring all successors of the current
1586 // block to the new block which will contain the Phi node for the select.
1587 copy1MBB->splice(copy1MBB->begin(), BB,
1588 std::next(MachineBasicBlock::iterator(MI)), BB->end());
1589 copy1MBB->transferSuccessorsAndUpdatePHIs(BB);
1590 // Next, add the true and fallthrough blocks as its successors.
1591 BB->addSuccessor(copy0MBB);
1592 BB->addSuccessor(copy1MBB);
1593
1594 BuildMI(BB, dl, TII.get(MSP430::JCC))
1595 .addMBB(copy1MBB)
1596 .addImm(MI.getOperand(3).getImm());
1597
1598 // copy0MBB:
1599 // %FalseValue = ...
1600 // # fallthrough to copy1MBB
1601 BB = copy0MBB;
1602
1603 // Update machine-CFG edges
1604 BB->addSuccessor(copy1MBB);
1605
1606 // copy1MBB:
1607 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
1608 // ...
1609 BB = copy1MBB;
1610 BuildMI(*BB, BB->begin(), dl, TII.get(MSP430::PHI), MI.getOperand(0).getReg())
1611 .addReg(MI.getOperand(2).getReg())
1612 .addMBB(copy0MBB)
1613 .addReg(MI.getOperand(1).getReg())
1614 .addMBB(thisMBB);
1615
1616 MI.eraseFromParent(); // The pseudo instruction is gone now.
1617 return BB;
1618}
amdgpu Simplify well known AMD library false FunctionCallee Callee
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
SmallVector< MachineOperand, 4 > Cond
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
std::string Name
Symbol * Sym
Definition: ELF_riscv.cpp:463
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
typename CallsiteContextGraph< DerivedCCG, FuncTy, CallTy >::FuncInfo FuncInfo
const char LLVMTargetMachineRef TM
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
@ Flags
Definition: TextStubV5.cpp:93
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:56
The address of a basic block.
Definition: Constants.h:874
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
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:630
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:68
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.
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:225
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:721
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
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:731
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 getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), AAResults *AA=nullptr)
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:472
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:773
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:768
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:469
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
Definition: SelectionDAG.h:799
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVMContext * getContext() const
Definition: SelectionDAG.h:485
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:554
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:577
void push_back(const T &Elt)
Definition: SmallVector.h:416
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
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 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:78
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:229
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:182
self_iterator getIterator()
Definition: ilist_node.h:82
#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:207
@ 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:114
@ 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:749
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
Definition: ISDOpcodes.h:1069
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition: ISDOpcodes.h:1065
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition: ISDOpcodes.h:250
@ BSWAP
Byte Swap and Counting operators.
Definition: ISDOpcodes.h:713
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
Definition: ISDOpcodes.h:1098
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:239
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition: ISDOpcodes.h:779
@ RETURNADDR
Definition: ISDOpcodes.h:95
@ GlobalAddress
Definition: ISDOpcodes.h:78
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition: ISDOpcodes.h:255
@ SIGN_EXTEND
Conversion operators.
Definition: ISDOpcodes.h:773
@ BR_CC
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:1020
@ BR_JT
BR_JT - Jumptable branch.
Definition: ISDOpcodes.h:1003
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition: ISDOpcodes.h:726
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
Definition: ISDOpcodes.h:1094
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition: ISDOpcodes.h:650
@ SHL
Shift and rotation operations.
Definition: ISDOpcodes.h:704
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition: ISDOpcodes.h:776
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition: ISDOpcodes.h:741
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
Definition: ISDOpcodes.h:988
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition: ISDOpcodes.h:794
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition: ISDOpcodes.h:94
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:679
@ 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:782
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
Definition: ISDOpcodes.h:1089
@ BRCOND
BRCOND - Conditional branch.
Definition: ISDOpcodes.h:1013
@ 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:762
@ 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:1396
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
Definition: ISDOpcodes.h:1447
@ 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:445
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:406
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
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:34
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
Definition: ValueTypes.h:373
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:299
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
Definition: ValueTypes.h:359
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition: ValueTypes.h:144
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