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"
15#include "MSP430MachineFunctionInfo.h"
16#include "MSP430SelectionDAGInfo.h"
17#include "MSP430Subtarget.h"
18#include "MSP430TargetMachine.h"
19#include "llvm/CodeGen/CallingConvLower.h"
20#include "llvm/CodeGen/MachineFrameInfo.h"
21#include "llvm/CodeGen/MachineFunction.h"
22#include "llvm/CodeGen/MachineInstrBuilder.h"
23#include "llvm/CodeGen/MachineRegisterInfo.h"
24#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
25#include "llvm/CodeGen/ValueTypes.h"
26#include "llvm/IR/CallingConv.h"
27#include "llvm/IR/DerivedTypes.h"
28#include "llvm/IR/Function.h"
29#include "llvm/IR/Intrinsics.h"
30#include "llvm/Support/CommandLine.h"
31#include "llvm/Support/Debug.h"
32#include "llvm/Support/ErrorHandling.h"
33#include "llvm/Support/raw_ostream.h"
34using namespace llvm;
35
36#define DEBUG_TYPE "msp430-lower"
37
38static cl::opt<bool>MSP430NoLegalImmediate(
39 "msp430-no-legal-immediate", cl::Hidden,
40 cl::desc("Enable non legal immediates (for testing purposes only)"),
41 cl::init(Val: false));
42
43MSP430TargetLowering::MSP430TargetLowering(const TargetMachine &TM,
44 const MSP430Subtarget &STI)
45 : TargetLowering(TM) {
46
47 // Set up the register classes.
48 addRegisterClass(VT: MVT::i8, RC: &MSP430::GR8RegClass);
49 addRegisterClass(VT: MVT::i16, RC: &MSP430::GR16RegClass);
50
51 // Compute derived properties from the register classes
52 computeRegisterProperties(TRI: STI.getRegisterInfo());
53
54 // Provide all sorts of operation actions
55 setStackPointerRegisterToSaveRestore(MSP430::SP);
56 setBooleanContents(ZeroOrOneBooleanContent);
57 setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?
58
59 // We have post-incremented loads / stores.
60 setIndexedLoadAction(IdxModes: ISD::POST_INC, VT: MVT::i8, Action: Legal);
61 setIndexedLoadAction(IdxModes: ISD::POST_INC, VT: MVT::i16, Action: Legal);
62
63 for (MVT VT : MVT::integer_valuetypes()) {
64 setLoadExtAction(ExtType: ISD::EXTLOAD, ValVT: VT, MemVT: MVT::i1, Action: Promote);
65 setLoadExtAction(ExtType: ISD::SEXTLOAD, ValVT: VT, MemVT: MVT::i1, Action: Promote);
66 setLoadExtAction(ExtType: ISD::ZEXTLOAD, ValVT: VT, MemVT: MVT::i1, Action: Promote);
67 setLoadExtAction(ExtType: ISD::SEXTLOAD, ValVT: VT, MemVT: MVT::i8, Action: Expand);
68 setLoadExtAction(ExtType: ISD::SEXTLOAD, ValVT: VT, MemVT: MVT::i16, Action: Expand);
69 }
70
71 // We don't have any truncstores
72 setTruncStoreAction(ValVT: MVT::i16, MemVT: MVT::i8, Action: Expand);
73
74 setOperationAction(Op: ISD::SRA, VT: MVT::i8, Action: Custom);
75 setOperationAction(Op: ISD::SHL, VT: MVT::i8, Action: Custom);
76 setOperationAction(Op: ISD::SRL, VT: MVT::i8, Action: Custom);
77 setOperationAction(Op: ISD::SRA, VT: MVT::i16, Action: Custom);
78 setOperationAction(Op: ISD::SHL, VT: MVT::i16, Action: Custom);
79 setOperationAction(Op: ISD::SRL, VT: MVT::i16, Action: Custom);
80 setOperationAction(Op: ISD::ROTL, VT: MVT::i8, Action: Expand);
81 setOperationAction(Op: ISD::ROTR, VT: MVT::i8, Action: Expand);
82 setOperationAction(Op: ISD::ROTL, VT: MVT::i16, Action: Expand);
83 setOperationAction(Op: ISD::ROTR, VT: MVT::i16, Action: Expand);
84 setOperationAction(Op: ISD::GlobalAddress, VT: MVT::i16, Action: Custom);
85 setOperationAction(Op: ISD::ExternalSymbol, VT: MVT::i16, Action: Custom);
86 setOperationAction(Op: ISD::BlockAddress, VT: MVT::i16, Action: Custom);
87 setOperationAction(Op: ISD::BR_JT, VT: MVT::Other, Action: Expand);
88 setOperationAction(Op: ISD::BR_CC, VT: MVT::i8, Action: Custom);
89 setOperationAction(Op: ISD::BR_CC, VT: MVT::i16, Action: Custom);
90 setOperationAction(Op: ISD::BRCOND, VT: MVT::Other, Action: Expand);
91 setOperationAction(Op: ISD::SETCC, VT: MVT::i8, Action: Custom);
92 setOperationAction(Op: ISD::SETCC, VT: MVT::i16, Action: Custom);
93 setOperationAction(Op: ISD::SELECT, VT: MVT::i8, Action: Expand);
94 setOperationAction(Op: ISD::SELECT, VT: MVT::i16, Action: Expand);
95 setOperationAction(Op: ISD::SELECT_CC, VT: MVT::i8, Action: Custom);
96 setOperationAction(Op: ISD::SELECT_CC, VT: MVT::i16, Action: Custom);
97 setOperationAction(Op: ISD::SIGN_EXTEND, VT: MVT::i16, Action: Custom);
98 setOperationAction(Op: ISD::DYNAMIC_STACKALLOC, VT: MVT::i8, Action: Expand);
99 setOperationAction(Op: ISD::DYNAMIC_STACKALLOC, VT: MVT::i16, Action: Expand);
100 setOperationAction(Op: ISD::STACKSAVE, VT: MVT::Other, Action: Expand);
101 setOperationAction(Op: ISD::STACKRESTORE, VT: MVT::Other, Action: Expand);
102
103 setOperationAction(Op: ISD::CTTZ, VT: MVT::i8, Action: Expand);
104 setOperationAction(Op: ISD::CTTZ, VT: MVT::i16, Action: Expand);
105 setOperationAction(Op: ISD::CTLZ, VT: MVT::i8, Action: Expand);
106 setOperationAction(Op: ISD::CTLZ, VT: MVT::i16, Action: Expand);
107 setOperationAction(Op: ISD::CTPOP, VT: MVT::i8, Action: Expand);
108 setOperationAction(Op: ISD::CTPOP, VT: MVT::i16, Action: Expand);
109
110 setOperationAction(Op: ISD::SHL_PARTS, VT: MVT::i8, Action: Expand);
111 setOperationAction(Op: ISD::SHL_PARTS, VT: MVT::i16, Action: Expand);
112 setOperationAction(Op: ISD::SRL_PARTS, VT: MVT::i8, Action: Expand);
113 setOperationAction(Op: ISD::SRL_PARTS, VT: MVT::i16, Action: Expand);
114 setOperationAction(Op: ISD::SRA_PARTS, VT: MVT::i8, Action: Expand);
115 setOperationAction(Op: ISD::SRA_PARTS, VT: MVT::i16, Action: Expand);
116
117 setOperationAction(Op: ISD::SIGN_EXTEND_INREG, VT: MVT::i1, Action: Expand);
118
119 // FIXME: Implement efficiently multiplication by a constant
120 setOperationAction(Op: ISD::MUL, VT: MVT::i8, Action: Promote);
121 setOperationAction(Op: ISD::MULHS, VT: MVT::i8, Action: Promote);
122 setOperationAction(Op: ISD::MULHU, VT: MVT::i8, Action: Promote);
123 setOperationAction(Op: ISD::SMUL_LOHI, VT: MVT::i8, Action: Promote);
124 setOperationAction(Op: ISD::UMUL_LOHI, VT: MVT::i8, Action: Promote);
125 setOperationAction(Op: ISD::MUL, VT: MVT::i16, Action: LibCall);
126 setOperationAction(Op: ISD::MULHS, VT: MVT::i16, Action: Expand);
127 setOperationAction(Op: ISD::MULHU, VT: MVT::i16, Action: Expand);
128 setOperationAction(Op: ISD::SMUL_LOHI, VT: MVT::i16, Action: Expand);
129 setOperationAction(Op: ISD::UMUL_LOHI, VT: MVT::i16, Action: Expand);
130
131 setOperationAction(Op: ISD::UDIV, VT: MVT::i8, Action: Promote);
132 setOperationAction(Op: ISD::UDIVREM, VT: MVT::i8, Action: Promote);
133 setOperationAction(Op: ISD::UREM, VT: MVT::i8, Action: Promote);
134 setOperationAction(Op: ISD::SDIV, VT: MVT::i8, Action: Promote);
135 setOperationAction(Op: ISD::SDIVREM, VT: MVT::i8, Action: Promote);
136 setOperationAction(Op: ISD::SREM, VT: MVT::i8, Action: Promote);
137 setOperationAction(Op: ISD::UDIV, VT: MVT::i16, Action: LibCall);
138 setOperationAction(Op: ISD::UDIVREM, VT: MVT::i16, Action: Expand);
139 setOperationAction(Op: ISD::UREM, VT: MVT::i16, Action: LibCall);
140 setOperationAction(Op: ISD::SDIV, VT: MVT::i16, Action: LibCall);
141 setOperationAction(Op: ISD::SDIVREM, VT: MVT::i16, Action: Expand);
142 setOperationAction(Op: ISD::SREM, VT: MVT::i16, Action: LibCall);
143
144 // varargs support
145 setOperationAction(Op: ISD::VASTART, VT: MVT::Other, Action: Custom);
146 setOperationAction(Op: ISD::VAARG, VT: MVT::Other, Action: Expand);
147 setOperationAction(Op: ISD::VAEND, VT: MVT::Other, Action: Expand);
148 setOperationAction(Op: ISD::VACOPY, VT: MVT::Other, Action: Expand);
149 setOperationAction(Op: ISD::JumpTable, VT: MVT::i16, Action: Custom);
150
151 if (STI.hasHWMult16()) {
152 const struct {
153 const RTLIB::Libcall Op;
154 const RTLIB::LibcallImpl Impl;
155 } LibraryCalls[] = {
156 // Integer Multiply - EABI Table 9
157 {.Op: RTLIB::MUL_I16, .Impl: RTLIB::__mspabi_mpyi_hw},
158 {.Op: RTLIB::MUL_I32, .Impl: RTLIB::__mspabi_mpyl_hw},
159 {.Op: RTLIB::MUL_I64, .Impl: RTLIB::__mspabi_mpyll_hw},
160 // TODO The __mspabi_mpysl*_hw functions ARE implemented in libgcc
161 // TODO The __mspabi_mpyul*_hw functions ARE implemented in libgcc
162 };
163 for (const auto &LC : LibraryCalls) {
164 setLibcallImpl(Call: LC.Op, Impl: LC.Impl);
165 }
166 } else if (STI.hasHWMult32()) {
167 const struct {
168 const RTLIB::Libcall Op;
169 const RTLIB::LibcallImpl Impl;
170 } LibraryCalls[] = {
171 // Integer Multiply - EABI Table 9
172 {.Op: RTLIB::MUL_I16, .Impl: RTLIB::__mspabi_mpyi_hw},
173 {.Op: RTLIB::MUL_I32, .Impl: RTLIB::__mspabi_mpyl_hw32},
174 {.Op: RTLIB::MUL_I64, .Impl: RTLIB::__mspabi_mpyll_hw32},
175 // TODO The __mspabi_mpysl*_hw32 functions ARE implemented in libgcc
176 // TODO The __mspabi_mpyul*_hw32 functions ARE implemented in libgcc
177 };
178 for (const auto &LC : LibraryCalls) {
179 setLibcallImpl(Call: LC.Op, Impl: LC.Impl);
180 }
181 } else if (STI.hasHWMultF5()) {
182 const struct {
183 const RTLIB::Libcall Op;
184 const RTLIB::LibcallImpl Impl;
185 } LibraryCalls[] = {
186 // Integer Multiply - EABI Table 9
187 {.Op: RTLIB::MUL_I16, .Impl: RTLIB::__mspabi_mpyi_f5hw},
188 {.Op: RTLIB::MUL_I32, .Impl: RTLIB::__mspabi_mpyl_f5hw},
189 {.Op: RTLIB::MUL_I64, .Impl: RTLIB::__mspabi_mpyll_f5hw},
190 // TODO The __mspabi_mpysl*_f5hw functions ARE implemented in libgcc
191 // TODO The __mspabi_mpyul*_f5hw functions ARE implemented in libgcc
192 };
193 for (const auto &LC : LibraryCalls) {
194 setLibcallImpl(Call: LC.Op, Impl: LC.Impl);
195 }
196 } else { // NoHWMult
197 const struct {
198 const RTLIB::Libcall Op;
199 const RTLIB::LibcallImpl Impl;
200 } LibraryCalls[] = {
201 // Integer Multiply - EABI Table 9
202 {.Op: RTLIB::MUL_I16, .Impl: RTLIB::__mspabi_mpyi},
203 {.Op: RTLIB::MUL_I32, .Impl: RTLIB::__mspabi_mpyl},
204 {.Op: RTLIB::MUL_I64, .Impl: RTLIB::__mspabi_mpyll},
205 // The __mspabi_mpysl* functions are NOT implemented in libgcc
206 // The __mspabi_mpyul* functions are NOT implemented in libgcc
207 };
208 for (const auto &LC : LibraryCalls) {
209 setLibcallImpl(Call: LC.Op, Impl: LC.Impl);
210 }
211 setLibcallCallingConv(Call: RTLIB::MUL_I64, CC: CallingConv::MSP430_BUILTIN);
212 }
213
214 setMinFunctionAlignment(Align(2));
215 setPrefFunctionAlignment(Align(2));
216 setMaxAtomicSizeInBitsSupported(0);
217}
218
219SDValue MSP430TargetLowering::LowerOperation(SDValue Op,
220 SelectionDAG &DAG) const {
221 switch (Op.getOpcode()) {
222 case ISD::SHL: // FALLTHROUGH
223 case ISD::SRL:
224 case ISD::SRA: return LowerShifts(Op, DAG);
225 case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
226 case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
227 case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG);
228 case ISD::SETCC: return LowerSETCC(Op, DAG);
229 case ISD::BR_CC: return LowerBR_CC(Op, DAG);
230 case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
231 case ISD::SIGN_EXTEND: return LowerSIGN_EXTEND(Op, DAG);
232 case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
233 case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
234 case ISD::VASTART: return LowerVASTART(Op, DAG);
235 case ISD::JumpTable: return LowerJumpTable(Op, DAG);
236 default:
237 llvm_unreachable("unimplemented operand");
238 }
239}
240
241// Define non profitable transforms into shifts
242bool MSP430TargetLowering::shouldAvoidTransformToShift(EVT VT,
243 unsigned Amount) const {
244 return !(Amount == 8 || Amount == 9 || Amount<=2);
245}
246
247// Implemented to verify test case assertions in
248// tests/codegen/msp430/shift-amount-threshold-b.ll
249bool MSP430TargetLowering::isLegalICmpImmediate(int64_t Immed) const {
250 if (MSP430NoLegalImmediate)
251 return Immed >= -32 && Immed < 32;
252 return TargetLowering::isLegalICmpImmediate(Immed);
253}
254
255//===----------------------------------------------------------------------===//
256// MSP430 Inline Assembly Support
257//===----------------------------------------------------------------------===//
258
259/// getConstraintType - Given a constraint letter, return the type of
260/// constraint it is for this target.
261TargetLowering::ConstraintType
262MSP430TargetLowering::getConstraintType(StringRef Constraint) const {
263 if (Constraint.size() == 1) {
264 switch (Constraint[0]) {
265 case 'r':
266 return C_RegisterClass;
267 default:
268 break;
269 }
270 }
271 return TargetLowering::getConstraintType(Constraint);
272}
273
274std::pair<unsigned, const TargetRegisterClass *>
275MSP430TargetLowering::getRegForInlineAsmConstraint(
276 const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
277 if (Constraint.size() == 1) {
278 // GCC Constraint Letters
279 switch (Constraint[0]) {
280 default: break;
281 case 'r': // GENERAL_REGS
282 if (VT == MVT::i8)
283 return std::make_pair(x: 0U, y: &MSP430::GR8RegClass);
284
285 return std::make_pair(x: 0U, y: &MSP430::GR16RegClass);
286 }
287 }
288
289 return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
290}
291
292//===----------------------------------------------------------------------===//
293// Calling Convention Implementation
294//===----------------------------------------------------------------------===//
295
296#include "MSP430GenCallingConv.inc"
297
298/// For each argument in a function store the number of pieces it is composed
299/// of.
300template<typename ArgT>
301static void ParseFunctionArgs(const SmallVectorImpl<ArgT> &Args,
302 SmallVectorImpl<unsigned> &Out) {
303 unsigned CurrentArgIndex;
304
305 if (Args.empty())
306 return;
307
308 CurrentArgIndex = Args[0].OrigArgIndex;
309 Out.push_back(Elt: 0);
310
311 for (auto &Arg : Args) {
312 if (CurrentArgIndex == Arg.OrigArgIndex) {
313 Out.back() += 1;
314 } else {
315 Out.push_back(Elt: 1);
316 CurrentArgIndex = Arg.OrigArgIndex;
317 }
318 }
319}
320
321static void AnalyzeVarArgs(CCState &State,
322 const SmallVectorImpl<ISD::OutputArg> &Outs) {
323 State.AnalyzeCallOperands(Outs, Fn: CC_MSP430_AssignStack);
324}
325
326static void AnalyzeVarArgs(CCState &State,
327 const SmallVectorImpl<ISD::InputArg> &Ins) {
328 State.AnalyzeFormalArguments(Ins, Fn: CC_MSP430_AssignStack);
329}
330
331/// Analyze incoming and outgoing function arguments. We need custom C++ code
332/// to handle special constraints in the ABI like reversing the order of the
333/// pieces of splitted arguments. In addition, all pieces of a certain argument
334/// have to be passed either using registers or the stack but never mixing both.
335template<typename ArgT>
336static void AnalyzeArguments(CCState &State,
337 SmallVectorImpl<CCValAssign> &ArgLocs,
338 const SmallVectorImpl<ArgT> &Args) {
339 static const MCPhysReg CRegList[] = {
340 MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15
341 };
342 static const unsigned CNbRegs = std::size(CRegList);
343 static const MCPhysReg BuiltinRegList[] = {
344 MSP430::R8, MSP430::R9, MSP430::R10, MSP430::R11,
345 MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15
346 };
347 static const unsigned BuiltinNbRegs = std::size(BuiltinRegList);
348
349 ArrayRef<MCPhysReg> RegList;
350 unsigned NbRegs;
351
352 bool Builtin = (State.getCallingConv() == CallingConv::MSP430_BUILTIN);
353 if (Builtin) {
354 RegList = BuiltinRegList;
355 NbRegs = BuiltinNbRegs;
356 } else {
357 RegList = CRegList;
358 NbRegs = CNbRegs;
359 }
360
361 if (State.isVarArg()) {
362 AnalyzeVarArgs(State, Args);
363 return;
364 }
365
366 SmallVector<unsigned, 4> ArgsParts;
367 ParseFunctionArgs(Args, ArgsParts);
368
369 if (Builtin) {
370 assert(ArgsParts.size() == 2 &&
371 "Builtin calling convention requires two arguments");
372 }
373
374 unsigned RegsLeft = NbRegs;
375 bool UsedStack = false;
376 unsigned ValNo = 0;
377
378 for (unsigned i = 0, e = ArgsParts.size(); i != e; i++) {
379 MVT ArgVT = Args[ValNo].VT;
380 ISD::ArgFlagsTy ArgFlags = Args[ValNo].Flags;
381 MVT LocVT = ArgVT;
382 CCValAssign::LocInfo LocInfo = CCValAssign::Full;
383
384 // Promote i8 to i16
385 if (LocVT == MVT::i8) {
386 LocVT = MVT::i16;
387 if (ArgFlags.isSExt())
388 LocInfo = CCValAssign::SExt;
389 else if (ArgFlags.isZExt())
390 LocInfo = CCValAssign::ZExt;
391 else
392 LocInfo = CCValAssign::AExt;
393 }
394
395 // Handle byval arguments
396 if (ArgFlags.isByVal()) {
397 State.HandleByVal(ValNo: ValNo++, ValVT: ArgVT, LocVT, LocInfo, MinSize: 2, MinAlign: Align(2), ArgFlags);
398 continue;
399 }
400
401 unsigned Parts = ArgsParts[i];
402
403 if (Builtin) {
404 assert(Parts == 4 &&
405 "Builtin calling convention requires 64-bit arguments");
406 }
407
408 if (!UsedStack && Parts == 2 && RegsLeft == 1) {
409 // Special case for 32-bit register split, see EABI section 3.3.3
410 MCRegister Reg = State.AllocateReg(Regs: RegList);
411 State.addLoc(V: CCValAssign::getReg(ValNo: ValNo++, ValVT: ArgVT, Reg, LocVT, HTP: LocInfo));
412 RegsLeft -= 1;
413
414 UsedStack = true;
415 CC_MSP430_AssignStack(ValNo: ValNo++, ValVT: ArgVT, LocVT, LocInfo, ArgFlags, State);
416 } else if (Parts <= RegsLeft) {
417 for (unsigned j = 0; j < Parts; j++) {
418 MCRegister Reg = State.AllocateReg(Regs: RegList);
419 State.addLoc(V: CCValAssign::getReg(ValNo: ValNo++, ValVT: ArgVT, Reg, LocVT, HTP: LocInfo));
420 RegsLeft--;
421 }
422 } else {
423 UsedStack = true;
424 for (unsigned j = 0; j < Parts; j++)
425 CC_MSP430_AssignStack(ValNo: ValNo++, ValVT: ArgVT, LocVT, LocInfo, ArgFlags, State);
426 }
427 }
428}
429
430static void AnalyzeRetResult(CCState &State,
431 const SmallVectorImpl<ISD::InputArg> &Ins) {
432 State.AnalyzeCallResult(Ins, Fn: RetCC_MSP430);
433}
434
435static void AnalyzeRetResult(CCState &State,
436 const SmallVectorImpl<ISD::OutputArg> &Outs) {
437 State.AnalyzeReturn(Outs, Fn: RetCC_MSP430);
438}
439
440template<typename ArgT>
441static void AnalyzeReturnValues(CCState &State,
442 SmallVectorImpl<CCValAssign> &RVLocs,
443 const SmallVectorImpl<ArgT> &Args) {
444 AnalyzeRetResult(State, Args);
445}
446
447SDValue MSP430TargetLowering::LowerFormalArguments(
448 SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
449 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
450 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
451
452 switch (CallConv) {
453 default:
454 report_fatal_error(reason: "Unsupported calling convention");
455 case CallingConv::C:
456 case CallingConv::Fast:
457 return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals);
458 case CallingConv::MSP430_INTR:
459 if (Ins.empty())
460 return Chain;
461 report_fatal_error(reason: "ISRs cannot have arguments");
462 }
463}
464
465SDValue
466MSP430TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
467 SmallVectorImpl<SDValue> &InVals) const {
468 SelectionDAG &DAG = CLI.DAG;
469 SDLoc &dl = CLI.DL;
470 SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
471 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
472 SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
473 SDValue Chain = CLI.Chain;
474 SDValue Callee = CLI.Callee;
475 bool &isTailCall = CLI.IsTailCall;
476 CallingConv::ID CallConv = CLI.CallConv;
477 bool isVarArg = CLI.IsVarArg;
478
479 // MSP430 target does not yet support tail call optimization.
480 isTailCall = false;
481
482 switch (CallConv) {
483 default:
484 report_fatal_error(reason: "Unsupported calling convention");
485 case CallingConv::MSP430_BUILTIN:
486 case CallingConv::Fast:
487 case CallingConv::C:
488 return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
489 Outs, OutVals, Ins, dl, DAG, InVals);
490 case CallingConv::MSP430_INTR:
491 report_fatal_error(reason: "ISRs cannot be called directly");
492 }
493}
494
495/// LowerCCCArguments - transform physical registers into virtual registers and
496/// generate load operations for arguments places on the stack.
497// FIXME: struct return stuff
498SDValue MSP430TargetLowering::LowerCCCArguments(
499 SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
500 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
501 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
502 MachineFunction &MF = DAG.getMachineFunction();
503 MachineFrameInfo &MFI = MF.getFrameInfo();
504 MachineRegisterInfo &RegInfo = MF.getRegInfo();
505 MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
506
507 // Assign locations to all of the incoming arguments.
508 SmallVector<CCValAssign, 16> ArgLocs;
509 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
510 *DAG.getContext());
511 AnalyzeArguments(State&: CCInfo, ArgLocs, Args: Ins);
512
513 // Create frame index for the start of the first vararg value
514 if (isVarArg) {
515 unsigned Offset = CCInfo.getStackSize();
516 FuncInfo->setVarArgsFrameIndex(MFI.CreateFixedObject(Size: 1, SPOffset: Offset, IsImmutable: true));
517 }
518
519 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
520 CCValAssign &VA = ArgLocs[i];
521 if (VA.isRegLoc()) {
522 // Arguments passed in registers
523 EVT RegVT = VA.getLocVT();
524 switch (RegVT.getSimpleVT().SimpleTy) {
525 default:
526 {
527#ifndef NDEBUG
528 errs() << "LowerFormalArguments Unhandled argument type: "
529 << RegVT << "\n";
530#endif
531 llvm_unreachable(nullptr);
532 }
533 case MVT::i16:
534 Register VReg = RegInfo.createVirtualRegister(RegClass: &MSP430::GR16RegClass);
535 RegInfo.addLiveIn(Reg: VA.getLocReg(), vreg: VReg);
536 SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, Reg: VReg, VT: RegVT);
537
538 // If this is an 8-bit value, it is really passed promoted to 16
539 // bits. Insert an assert[sz]ext to capture this, then truncate to the
540 // right size.
541 if (VA.getLocInfo() == CCValAssign::SExt)
542 ArgValue = DAG.getNode(Opcode: ISD::AssertSext, DL: dl, VT: RegVT, N1: ArgValue,
543 N2: DAG.getValueType(VA.getValVT()));
544 else if (VA.getLocInfo() == CCValAssign::ZExt)
545 ArgValue = DAG.getNode(Opcode: ISD::AssertZext, DL: dl, VT: RegVT, N1: ArgValue,
546 N2: DAG.getValueType(VA.getValVT()));
547
548 if (VA.getLocInfo() != CCValAssign::Full)
549 ArgValue = DAG.getNode(Opcode: ISD::TRUNCATE, DL: dl, VT: VA.getValVT(), Operand: ArgValue);
550
551 InVals.push_back(Elt: ArgValue);
552 }
553 } else {
554 // Only arguments passed on the stack should make it here.
555 assert(VA.isMemLoc());
556
557 SDValue InVal;
558 ISD::ArgFlagsTy Flags = Ins[i].Flags;
559
560 if (Flags.isByVal()) {
561 MVT PtrVT = VA.getLocVT();
562 int FI = MFI.CreateFixedObject(Size: Flags.getByValSize(),
563 SPOffset: VA.getLocMemOffset(), IsImmutable: true);
564 InVal = DAG.getFrameIndex(FI, VT: PtrVT);
565 } else {
566 // Load the argument to a virtual register
567 unsigned ObjSize = VA.getLocVT().getSizeInBits()/8;
568 if (ObjSize > 2) {
569 errs() << "LowerFormalArguments Unhandled argument type: "
570 << VA.getLocVT() << "\n";
571 }
572 // Create the frame index object for this incoming parameter...
573 int FI = MFI.CreateFixedObject(Size: ObjSize, SPOffset: VA.getLocMemOffset(), IsImmutable: true);
574
575 // Create the SelectionDAG nodes corresponding to a load
576 //from this parameter
577 SDValue FIN = DAG.getFrameIndex(FI, VT: MVT::i16);
578 InVal = DAG.getLoad(
579 VT: VA.getLocVT(), dl, Chain, Ptr: FIN,
580 PtrInfo: MachinePointerInfo::getFixedStack(MF&: DAG.getMachineFunction(), FI));
581 }
582
583 InVals.push_back(Elt: InVal);
584 }
585 }
586
587 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
588 if (Ins[i].Flags.isSRet()) {
589 Register Reg = FuncInfo->getSRetReturnReg();
590 if (!Reg) {
591 Reg = MF.getRegInfo().createVirtualRegister(
592 RegClass: getRegClassFor(VT: MVT::i16));
593 FuncInfo->setSRetReturnReg(Reg);
594 }
595 SDValue Copy = DAG.getCopyToReg(Chain: DAG.getEntryNode(), dl, Reg, N: InVals[i]);
596 Chain = DAG.getNode(Opcode: ISD::TokenFactor, DL: dl, VT: MVT::Other, N1: Copy, N2: Chain);
597 }
598 }
599
600 return Chain;
601}
602
603bool
604MSP430TargetLowering::CanLowerReturn(CallingConv::ID CallConv,
605 MachineFunction &MF,
606 bool IsVarArg,
607 const SmallVectorImpl<ISD::OutputArg> &Outs,
608 LLVMContext &Context,
609 const Type *RetTy) const {
610 SmallVector<CCValAssign, 16> RVLocs;
611 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
612 return CCInfo.CheckReturn(Outs, Fn: RetCC_MSP430);
613}
614
615SDValue
616MSP430TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
617 bool isVarArg,
618 const SmallVectorImpl<ISD::OutputArg> &Outs,
619 const SmallVectorImpl<SDValue> &OutVals,
620 const SDLoc &dl, SelectionDAG &DAG) const {
621
622 MachineFunction &MF = DAG.getMachineFunction();
623
624 // CCValAssign - represent the assignment of the return value to a location
625 SmallVector<CCValAssign, 16> RVLocs;
626
627 // ISRs cannot return any value.
628 if (CallConv == CallingConv::MSP430_INTR && !Outs.empty())
629 report_fatal_error(reason: "ISRs cannot return any value");
630
631 // CCState - Info about the registers and stack slot.
632 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
633 *DAG.getContext());
634
635 // Analize return values.
636 AnalyzeReturnValues(State&: CCInfo, RVLocs, Args: Outs);
637
638 SDValue Glue;
639 SmallVector<SDValue, 4> RetOps(1, Chain);
640
641 // Copy the result values into the output registers.
642 for (unsigned i = 0; i != RVLocs.size(); ++i) {
643 CCValAssign &VA = RVLocs[i];
644 assert(VA.isRegLoc() && "Can only return in registers!");
645
646 Chain = DAG.getCopyToReg(Chain, dl, Reg: VA.getLocReg(),
647 N: OutVals[i], Glue);
648
649 // Guarantee that all emitted copies are stuck together,
650 // avoiding something bad.
651 Glue = Chain.getValue(R: 1);
652 RetOps.push_back(Elt: DAG.getRegister(Reg: VA.getLocReg(), VT: VA.getLocVT()));
653 }
654
655 if (MF.getFunction().hasStructRetAttr()) {
656 MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
657 Register Reg = FuncInfo->getSRetReturnReg();
658
659 if (!Reg)
660 llvm_unreachable("sret virtual register not created in entry block");
661
662 MVT PtrVT = getFrameIndexTy(DL: DAG.getDataLayout());
663 SDValue Val =
664 DAG.getCopyFromReg(Chain, dl, Reg, VT: PtrVT);
665 unsigned R12 = MSP430::R12;
666
667 Chain = DAG.getCopyToReg(Chain, dl, Reg: R12, N: Val, Glue);
668 Glue = Chain.getValue(R: 1);
669 RetOps.push_back(Elt: DAG.getRegister(Reg: R12, VT: PtrVT));
670 }
671
672 unsigned Opc = (CallConv == CallingConv::MSP430_INTR ?
673 MSP430ISD::RETI_GLUE : MSP430ISD::RET_GLUE);
674
675 RetOps[0] = Chain; // Update chain.
676
677 // Add the glue if we have it.
678 if (Glue.getNode())
679 RetOps.push_back(Elt: Glue);
680
681 return DAG.getNode(Opcode: Opc, DL: dl, VT: MVT::Other, Ops: RetOps);
682}
683
684/// LowerCCCCallTo - functions arguments are copied from virtual regs to
685/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
686SDValue MSP430TargetLowering::LowerCCCCallTo(
687 SDValue Chain, SDValue Callee, CallingConv::ID CallConv, bool isVarArg,
688 bool isTailCall, const SmallVectorImpl<ISD::OutputArg> &Outs,
689 const SmallVectorImpl<SDValue> &OutVals,
690 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
691 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
692 // Analyze operands of the call, assigning locations to each operand.
693 SmallVector<CCValAssign, 16> ArgLocs;
694 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
695 *DAG.getContext());
696 AnalyzeArguments(State&: CCInfo, ArgLocs, Args: Outs);
697
698 // Get a count of how many bytes are to be pushed on the stack.
699 unsigned NumBytes = CCInfo.getStackSize();
700 MVT PtrVT = getFrameIndexTy(DL: DAG.getDataLayout());
701
702 Chain = DAG.getCALLSEQ_START(Chain, InSize: NumBytes, OutSize: 0, DL: dl);
703
704 SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass;
705 SmallVector<SDValue, 12> MemOpChains;
706 SDValue StackPtr;
707
708 // Walk the register/memloc assignments, inserting copies/loads.
709 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
710 CCValAssign &VA = ArgLocs[i];
711
712 SDValue Arg = OutVals[i];
713
714 // Promote the value if needed.
715 switch (VA.getLocInfo()) {
716 default: llvm_unreachable("Unknown loc info!");
717 case CCValAssign::Full: break;
718 case CCValAssign::SExt:
719 Arg = DAG.getNode(Opcode: ISD::SIGN_EXTEND, DL: dl, VT: VA.getLocVT(), Operand: Arg);
720 break;
721 case CCValAssign::ZExt:
722 Arg = DAG.getNode(Opcode: ISD::ZERO_EXTEND, DL: dl, VT: VA.getLocVT(), Operand: Arg);
723 break;
724 case CCValAssign::AExt:
725 Arg = DAG.getNode(Opcode: ISD::ANY_EXTEND, DL: dl, VT: VA.getLocVT(), Operand: Arg);
726 break;
727 }
728
729 // Arguments that can be passed on register must be kept at RegsToPass
730 // vector
731 if (VA.isRegLoc()) {
732 RegsToPass.push_back(Elt: std::make_pair(x: VA.getLocReg(), y&: Arg));
733 } else {
734 assert(VA.isMemLoc());
735
736 if (!StackPtr.getNode())
737 StackPtr = DAG.getCopyFromReg(Chain, dl, Reg: MSP430::SP, VT: PtrVT);
738
739 SDValue PtrOff =
740 DAG.getNode(Opcode: ISD::ADD, DL: dl, VT: PtrVT, N1: StackPtr,
741 N2: DAG.getIntPtrConstant(Val: VA.getLocMemOffset(), DL: dl));
742
743 SDValue MemOp;
744 ISD::ArgFlagsTy Flags = Outs[i].Flags;
745
746 if (Flags.isByVal()) {
747 SDValue SizeNode = DAG.getConstant(Val: Flags.getByValSize(), DL: dl, VT: MVT::i16);
748 MemOp = DAG.getMemcpy(Chain, dl, Dst: PtrOff, Src: Arg, Size: SizeNode,
749 Alignment: Flags.getNonZeroByValAlign(),
750 /*isVolatile*/ isVol: false,
751 /*AlwaysInline=*/true,
752 /*CI=*/nullptr, OverrideTailCall: std::nullopt,
753 DstPtrInfo: MachinePointerInfo(), SrcPtrInfo: MachinePointerInfo());
754 } else {
755 MemOp = DAG.getStore(Chain, dl, Val: Arg, Ptr: PtrOff, PtrInfo: MachinePointerInfo());
756 }
757
758 MemOpChains.push_back(Elt: MemOp);
759 }
760 }
761
762 // Transform all store nodes into one single node because all store nodes are
763 // independent of each other.
764 if (!MemOpChains.empty())
765 Chain = DAG.getNode(Opcode: ISD::TokenFactor, DL: dl, VT: MVT::Other, Ops: MemOpChains);
766
767 // Build a sequence of copy-to-reg nodes chained together with token chain and
768 // flag operands which copy the outgoing args into registers. The InGlue in
769 // necessary since all emitted instructions must be stuck together.
770 SDValue InGlue;
771 for (const auto &[Reg, N] : RegsToPass) {
772 Chain = DAG.getCopyToReg(Chain, dl, Reg, N, Glue: InGlue);
773 InGlue = Chain.getValue(R: 1);
774 }
775
776 // If the callee is a GlobalAddress node (quite common, every direct call is)
777 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
778 // Likewise ExternalSymbol -> TargetExternalSymbol.
779 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Val&: Callee))
780 Callee = DAG.getTargetGlobalAddress(GV: G->getGlobal(), DL: dl, VT: MVT::i16);
781 else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Val&: Callee))
782 Callee = DAG.getTargetExternalSymbol(Sym: E->getSymbol(), VT: MVT::i16);
783
784 // Returns a chain & a flag for retval copy to use.
785 SDVTList NodeTys = DAG.getVTList(VT1: MVT::Other, VT2: MVT::Glue);
786 SmallVector<SDValue, 8> Ops;
787 Ops.push_back(Elt: Chain);
788 Ops.push_back(Elt: Callee);
789
790 // Add argument registers to the end of the list so that they are
791 // known live into the call.
792 for (const auto &[Reg, N] : RegsToPass)
793 Ops.push_back(Elt: DAG.getRegister(Reg, VT: N.getValueType()));
794
795 if (InGlue.getNode())
796 Ops.push_back(Elt: InGlue);
797
798 Chain = DAG.getNode(Opcode: MSP430ISD::CALL, DL: dl, VTList: NodeTys, Ops);
799 InGlue = Chain.getValue(R: 1);
800
801 // Create the CALLSEQ_END node.
802 Chain = DAG.getCALLSEQ_END(Chain, Size1: NumBytes, Size2: 0, Glue: InGlue, DL: dl);
803 InGlue = Chain.getValue(R: 1);
804
805 // Handle result values, copying them out of physregs into vregs that we
806 // return.
807 return LowerCallResult(Chain, InGlue, CallConv, isVarArg, Ins, dl,
808 DAG, InVals);
809}
810
811/// LowerCallResult - Lower the result values of a call into the
812/// appropriate copies out of appropriate physical registers.
813///
814SDValue MSP430TargetLowering::LowerCallResult(
815 SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool isVarArg,
816 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
817 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
818
819 // Assign locations to each value returned by this call.
820 SmallVector<CCValAssign, 16> RVLocs;
821 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
822 *DAG.getContext());
823
824 AnalyzeReturnValues(State&: CCInfo, RVLocs, Args: Ins);
825
826 // Copy all of the result registers out of their specified physreg.
827 for (unsigned i = 0; i != RVLocs.size(); ++i) {
828 Chain = DAG.getCopyFromReg(Chain, dl, Reg: RVLocs[i].getLocReg(),
829 VT: RVLocs[i].getValVT(), Glue: InGlue).getValue(R: 1);
830 InGlue = Chain.getValue(R: 2);
831 InVals.push_back(Elt: Chain.getValue(R: 0));
832 }
833
834 return Chain;
835}
836
837SDValue MSP430TargetLowering::LowerShifts(SDValue Op,
838 SelectionDAG &DAG) const {
839 unsigned Opc = Op.getOpcode();
840 SDNode* N = Op.getNode();
841 EVT VT = Op.getValueType();
842 SDLoc dl(N);
843
844 // Expand non-constant shifts to loops:
845 if (!isa<ConstantSDNode>(Val: N->getOperand(Num: 1)))
846 return Op;
847
848 uint64_t ShiftAmount = N->getConstantOperandVal(Num: 1);
849
850 // Expand the stuff into sequence of shifts.
851 SDValue Victim = N->getOperand(Num: 0);
852
853 if (ShiftAmount >= 8) {
854 assert(VT == MVT::i16 && "Can not shift i8 by 8 and more");
855 switch(Opc) {
856 default:
857 llvm_unreachable("Unknown shift");
858 case ISD::SHL:
859 // foo << (8 + N) => swpb(zext(foo)) << N
860 Victim = DAG.getZeroExtendInReg(Op: Victim, DL: dl, VT: MVT::i8);
861 Victim = DAG.getNode(Opcode: ISD::BSWAP, DL: dl, VT, Operand: Victim);
862 break;
863 case ISD::SRA:
864 case ISD::SRL:
865 // foo >> (8 + N) => sxt(swpb(foo)) >> N
866 Victim = DAG.getNode(Opcode: ISD::BSWAP, DL: dl, VT, Operand: Victim);
867 Victim = (Opc == ISD::SRA)
868 ? DAG.getNode(Opcode: ISD::SIGN_EXTEND_INREG, DL: dl, VT, N1: Victim,
869 N2: DAG.getValueType(MVT::i8))
870 : DAG.getZeroExtendInReg(Op: Victim, DL: dl, VT: MVT::i8);
871 break;
872 }
873 ShiftAmount -= 8;
874 }
875
876 if (Opc == ISD::SRL && ShiftAmount) {
877 // Emit a special goodness here:
878 // srl A, 1 => clrc; rrc A
879 Victim = DAG.getNode(Opcode: MSP430ISD::RRCL, DL: dl, VT, Operand: Victim);
880 ShiftAmount -= 1;
881 }
882
883 while (ShiftAmount--)
884 Victim = DAG.getNode(Opcode: (Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA),
885 DL: dl, VT, Operand: Victim);
886
887 return Victim;
888}
889
890SDValue MSP430TargetLowering::LowerGlobalAddress(SDValue Op,
891 SelectionDAG &DAG) const {
892 const GlobalValue *GV = cast<GlobalAddressSDNode>(Val&: Op)->getGlobal();
893 int64_t Offset = cast<GlobalAddressSDNode>(Val&: Op)->getOffset();
894 EVT PtrVT = Op.getValueType();
895
896 // Create the TargetGlobalAddress node, folding in the constant offset.
897 SDValue Result = DAG.getTargetGlobalAddress(GV, DL: SDLoc(Op), VT: PtrVT, offset: Offset);
898 return DAG.getNode(Opcode: MSP430ISD::Wrapper, DL: SDLoc(Op), VT: PtrVT, Operand: Result);
899}
900
901SDValue MSP430TargetLowering::LowerExternalSymbol(SDValue Op,
902 SelectionDAG &DAG) const {
903 SDLoc dl(Op);
904 const char *Sym = cast<ExternalSymbolSDNode>(Val&: Op)->getSymbol();
905 EVT PtrVT = Op.getValueType();
906 SDValue Result = DAG.getTargetExternalSymbol(Sym, VT: PtrVT);
907
908 return DAG.getNode(Opcode: MSP430ISD::Wrapper, DL: dl, VT: PtrVT, Operand: Result);
909}
910
911SDValue MSP430TargetLowering::LowerBlockAddress(SDValue Op,
912 SelectionDAG &DAG) const {
913 SDLoc dl(Op);
914 const BlockAddress *BA = cast<BlockAddressSDNode>(Val&: Op)->getBlockAddress();
915 EVT PtrVT = Op.getValueType();
916 SDValue Result = DAG.getTargetBlockAddress(BA, VT: PtrVT);
917
918 return DAG.getNode(Opcode: MSP430ISD::Wrapper, DL: dl, VT: PtrVT, Operand: Result);
919}
920
921static SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC,
922 ISD::CondCode CC, const SDLoc &dl, SelectionDAG &DAG) {
923 // FIXME: Handle bittests someday
924 assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet");
925
926 // FIXME: Handle jump negative someday
927 MSP430CC::CondCodes TCC = MSP430CC::COND_INVALID;
928 switch (CC) {
929 default: llvm_unreachable("Invalid integer condition!");
930 case ISD::SETEQ:
931 TCC = MSP430CC::COND_E; // aka COND_Z
932 // Minor optimization: if LHS is a constant, swap operands, then the
933 // constant can be folded into comparison.
934 if (LHS.getOpcode() == ISD::Constant)
935 std::swap(a&: LHS, b&: RHS);
936 break;
937 case ISD::SETNE:
938 TCC = MSP430CC::COND_NE; // aka COND_NZ
939 // Minor optimization: if LHS is a constant, swap operands, then the
940 // constant can be folded into comparison.
941 if (LHS.getOpcode() == ISD::Constant)
942 std::swap(a&: LHS, b&: RHS);
943 break;
944 case ISD::SETULE:
945 std::swap(a&: LHS, b&: RHS);
946 [[fallthrough]];
947 case ISD::SETUGE:
948 // Turn lhs u>= rhs with lhs constant into rhs u< lhs+1, this allows us to
949 // fold constant into instruction.
950 if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(Val&: LHS)) {
951 LHS = RHS;
952 RHS = DAG.getConstant(Val: C->getSExtValue() + 1, DL: dl, VT: C->getValueType(ResNo: 0));
953 TCC = MSP430CC::COND_LO;
954 break;
955 }
956 TCC = MSP430CC::COND_HS; // aka COND_C
957 break;
958 case ISD::SETUGT:
959 std::swap(a&: LHS, b&: RHS);
960 [[fallthrough]];
961 case ISD::SETULT:
962 // Turn lhs u< rhs with lhs constant into rhs u>= lhs+1, this allows us to
963 // fold constant into instruction.
964 if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(Val&: LHS)) {
965 LHS = RHS;
966 RHS = DAG.getConstant(Val: C->getSExtValue() + 1, DL: dl, VT: C->getValueType(ResNo: 0));
967 TCC = MSP430CC::COND_HS;
968 break;
969 }
970 TCC = MSP430CC::COND_LO; // aka COND_NC
971 break;
972 case ISD::SETLE:
973 std::swap(a&: LHS, b&: RHS);
974 [[fallthrough]];
975 case ISD::SETGE:
976 // Turn lhs >= rhs with lhs constant into rhs < lhs+1, this allows us to
977 // fold constant into instruction.
978 if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(Val&: LHS)) {
979 LHS = RHS;
980 RHS = DAG.getConstant(Val: C->getSExtValue() + 1, DL: dl, VT: C->getValueType(ResNo: 0));
981 TCC = MSP430CC::COND_L;
982 break;
983 }
984 TCC = MSP430CC::COND_GE;
985 break;
986 case ISD::SETGT:
987 std::swap(a&: LHS, b&: RHS);
988 [[fallthrough]];
989 case ISD::SETLT:
990 // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to
991 // fold constant into instruction.
992 if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(Val&: LHS)) {
993 LHS = RHS;
994 RHS = DAG.getConstant(Val: C->getSExtValue() + 1, DL: dl, VT: C->getValueType(ResNo: 0));
995 TCC = MSP430CC::COND_GE;
996 break;
997 }
998 TCC = MSP430CC::COND_L;
999 break;
1000 }
1001
1002 TargetCC = DAG.getConstant(Val: TCC, DL: dl, VT: MVT::i8);
1003 return DAG.getNode(Opcode: MSP430ISD::CMP, DL: dl, VT: MVT::Glue, N1: LHS, N2: RHS);
1004}
1005
1006
1007SDValue MSP430TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
1008 SDValue Chain = Op.getOperand(i: 0);
1009 ISD::CondCode CC = cast<CondCodeSDNode>(Val: Op.getOperand(i: 1))->get();
1010 SDValue LHS = Op.getOperand(i: 2);
1011 SDValue RHS = Op.getOperand(i: 3);
1012 SDValue Dest = Op.getOperand(i: 4);
1013 SDLoc dl (Op);
1014
1015 SDValue TargetCC;
1016 SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
1017
1018 return DAG.getNode(Opcode: MSP430ISD::BR_CC, DL: dl, VT: Op.getValueType(),
1019 N1: Chain, N2: Dest, N3: TargetCC, N4: Flag);
1020}
1021
1022SDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
1023 SDValue LHS = Op.getOperand(i: 0);
1024 SDValue RHS = Op.getOperand(i: 1);
1025 SDLoc dl (Op);
1026
1027 // If we are doing an AND and testing against zero, then the CMP
1028 // will not be generated. The AND (or BIT) will generate the condition codes,
1029 // but they are different from CMP.
1030 // FIXME: since we're doing a post-processing, use a pseudoinstr here, so
1031 // lowering & isel wouldn't diverge.
1032 bool andCC = isNullConstant(V: RHS) && LHS.hasOneUse() &&
1033 (LHS.getOpcode() == ISD::AND ||
1034 (LHS.getOpcode() == ISD::TRUNCATE &&
1035 LHS.getOperand(i: 0).getOpcode() == ISD::AND));
1036 ISD::CondCode CC = cast<CondCodeSDNode>(Val: Op.getOperand(i: 2))->get();
1037 SDValue TargetCC;
1038 SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
1039
1040 // Get the condition codes directly from the status register, if its easy.
1041 // Otherwise a branch will be generated. Note that the AND and BIT
1042 // instructions generate different flags than CMP, the carry bit can be used
1043 // for NE/EQ.
1044 bool Invert = false;
1045 bool Shift = false;
1046 bool Convert = true;
1047 switch (TargetCC->getAsZExtVal()) {
1048 default:
1049 Convert = false;
1050 break;
1051 case MSP430CC::COND_HS:
1052 // Res = SR & 1, no processing is required
1053 break;
1054 case MSP430CC::COND_LO:
1055 // Res = ~(SR & 1)
1056 Invert = true;
1057 break;
1058 case MSP430CC::COND_NE:
1059 if (andCC) {
1060 // C = ~Z, thus Res = SR & 1, no processing is required
1061 } else {
1062 // Res = ~((SR >> 1) & 1)
1063 Shift = true;
1064 Invert = true;
1065 }
1066 break;
1067 case MSP430CC::COND_E:
1068 Shift = true;
1069 // C = ~Z for AND instruction, thus we can put Res = ~(SR & 1), however,
1070 // Res = (SR >> 1) & 1 is 1 word shorter.
1071 break;
1072 }
1073 EVT VT = Op.getValueType();
1074 SDValue One = DAG.getConstant(Val: 1, DL: dl, VT);
1075 if (Convert) {
1076 SDValue SR = DAG.getCopyFromReg(Chain: DAG.getEntryNode(), dl, Reg: MSP430::SR,
1077 VT: MVT::i16, Glue: Flag);
1078 if (Shift)
1079 // FIXME: somewhere this is turned into a SRL, lower it MSP specific?
1080 SR = DAG.getNode(Opcode: ISD::SRA, DL: dl, VT: MVT::i16, N1: SR, N2: One);
1081 SR = DAG.getNode(Opcode: ISD::AND, DL: dl, VT: MVT::i16, N1: SR, N2: One);
1082 if (Invert)
1083 SR = DAG.getNode(Opcode: ISD::XOR, DL: dl, VT: MVT::i16, N1: SR, N2: One);
1084 return SR;
1085 } else {
1086 SDValue Zero = DAG.getConstant(Val: 0, DL: dl, VT);
1087 SDValue Ops[] = {One, Zero, TargetCC, Flag};
1088 return DAG.getNode(Opcode: MSP430ISD::SELECT_CC, DL: dl, VT: Op.getValueType(), Ops);
1089 }
1090}
1091
1092SDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op,
1093 SelectionDAG &DAG) const {
1094 SDValue LHS = Op.getOperand(i: 0);
1095 SDValue RHS = Op.getOperand(i: 1);
1096 SDValue TrueV = Op.getOperand(i: 2);
1097 SDValue FalseV = Op.getOperand(i: 3);
1098 ISD::CondCode CC = cast<CondCodeSDNode>(Val: Op.getOperand(i: 4))->get();
1099 SDLoc dl (Op);
1100
1101 SDValue TargetCC;
1102 SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
1103
1104 SDValue Ops[] = {TrueV, FalseV, TargetCC, Flag};
1105
1106 return DAG.getNode(Opcode: MSP430ISD::SELECT_CC, DL: dl, VT: Op.getValueType(), Ops);
1107}
1108
1109SDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op,
1110 SelectionDAG &DAG) const {
1111 SDValue Val = Op.getOperand(i: 0);
1112 EVT VT = Op.getValueType();
1113 SDLoc dl(Op);
1114
1115 assert(VT == MVT::i16 && "Only support i16 for now!");
1116
1117 return DAG.getNode(Opcode: ISD::SIGN_EXTEND_INREG, DL: dl, VT,
1118 N1: DAG.getNode(Opcode: ISD::ANY_EXTEND, DL: dl, VT, Operand: Val),
1119 N2: DAG.getValueType(Val.getValueType()));
1120}
1121
1122SDValue
1123MSP430TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) const {
1124 MachineFunction &MF = DAG.getMachineFunction();
1125 MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
1126 int ReturnAddrIndex = FuncInfo->getRAIndex();
1127 MVT PtrVT = getFrameIndexTy(DL: MF.getDataLayout());
1128
1129 if (ReturnAddrIndex == 0) {
1130 // Set up a frame object for the return address.
1131 uint64_t SlotSize = PtrVT.getStoreSize();
1132 ReturnAddrIndex = MF.getFrameInfo().CreateFixedObject(Size: SlotSize, SPOffset: -SlotSize,
1133 IsImmutable: true);
1134 FuncInfo->setRAIndex(ReturnAddrIndex);
1135 }
1136
1137 return DAG.getFrameIndex(FI: ReturnAddrIndex, VT: PtrVT);
1138}
1139
1140SDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op,
1141 SelectionDAG &DAG) const {
1142 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
1143 MFI.setReturnAddressIsTaken(true);
1144
1145 if (verifyReturnAddressArgumentIsConstant(Op, DAG))
1146 return SDValue();
1147
1148 unsigned Depth = Op.getConstantOperandVal(i: 0);
1149 SDLoc dl(Op);
1150 EVT PtrVT = Op.getValueType();
1151
1152 if (Depth > 0) {
1153 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
1154 SDValue Offset =
1155 DAG.getConstant(Val: PtrVT.getStoreSize(), DL: dl, VT: MVT::i16);
1156 return DAG.getLoad(VT: PtrVT, dl, Chain: DAG.getEntryNode(),
1157 Ptr: DAG.getNode(Opcode: ISD::ADD, DL: dl, VT: PtrVT, N1: FrameAddr, N2: Offset),
1158 PtrInfo: MachinePointerInfo());
1159 }
1160
1161 // Just load the return address.
1162 SDValue RetAddrFI = getReturnAddressFrameIndex(DAG);
1163 return DAG.getLoad(VT: PtrVT, dl, Chain: DAG.getEntryNode(), Ptr: RetAddrFI,
1164 PtrInfo: MachinePointerInfo());
1165}
1166
1167SDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op,
1168 SelectionDAG &DAG) const {
1169 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
1170 MFI.setFrameAddressIsTaken(true);
1171
1172 EVT VT = Op.getValueType();
1173 SDLoc dl(Op); // FIXME probably not meaningful
1174 unsigned Depth = Op.getConstantOperandVal(i: 0);
1175 SDValue FrameAddr = DAG.getCopyFromReg(Chain: DAG.getEntryNode(), dl,
1176 Reg: MSP430::R4, VT);
1177 while (Depth--)
1178 FrameAddr = DAG.getLoad(VT, dl, Chain: DAG.getEntryNode(), Ptr: FrameAddr,
1179 PtrInfo: MachinePointerInfo());
1180 return FrameAddr;
1181}
1182
1183SDValue MSP430TargetLowering::LowerVASTART(SDValue Op,
1184 SelectionDAG &DAG) const {
1185 MachineFunction &MF = DAG.getMachineFunction();
1186 MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
1187
1188 SDValue Ptr = Op.getOperand(i: 1);
1189 EVT PtrVT = Ptr.getValueType();
1190
1191 // Frame index of first vararg argument
1192 SDValue FrameIndex =
1193 DAG.getFrameIndex(FI: FuncInfo->getVarArgsFrameIndex(), VT: PtrVT);
1194 const Value *SV = cast<SrcValueSDNode>(Val: Op.getOperand(i: 2))->getValue();
1195
1196 // Create a store of the frame index to the location operand
1197 return DAG.getStore(Chain: Op.getOperand(i: 0), dl: SDLoc(Op), Val: FrameIndex, Ptr,
1198 PtrInfo: MachinePointerInfo(SV));
1199}
1200
1201SDValue MSP430TargetLowering::LowerJumpTable(SDValue Op,
1202 SelectionDAG &DAG) const {
1203 JumpTableSDNode *JT = cast<JumpTableSDNode>(Val&: Op);
1204 EVT PtrVT = Op.getValueType();
1205 SDValue Result = DAG.getTargetJumpTable(JTI: JT->getIndex(), VT: PtrVT);
1206 return DAG.getNode(Opcode: MSP430ISD::Wrapper, DL: SDLoc(JT), VT: PtrVT, Operand: Result);
1207}
1208
1209/// getPostIndexedAddressParts - returns true by value, base pointer and
1210/// offset pointer and addressing mode by reference if this node can be
1211/// combined with a load / store to form a post-indexed load / store.
1212bool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
1213 SDValue &Base,
1214 SDValue &Offset,
1215 ISD::MemIndexedMode &AM,
1216 SelectionDAG &DAG) const {
1217
1218 LoadSDNode *LD = cast<LoadSDNode>(Val: N);
1219 if (LD->getExtensionType() != ISD::NON_EXTLOAD)
1220 return false;
1221
1222 EVT VT = LD->getMemoryVT();
1223 if (VT != MVT::i8 && VT != MVT::i16)
1224 return false;
1225
1226 if (Op->getOpcode() != ISD::ADD)
1227 return false;
1228
1229 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Val: Op->getOperand(Num: 1))) {
1230 uint64_t RHSC = RHS->getZExtValue();
1231 if ((VT == MVT::i16 && RHSC != 2) ||
1232 (VT == MVT::i8 && RHSC != 1))
1233 return false;
1234
1235 Base = Op->getOperand(Num: 0);
1236 Offset = DAG.getConstant(Val: RHSC, DL: SDLoc(N), VT);
1237 AM = ISD::POST_INC;
1238 return true;
1239 }
1240
1241 return false;
1242}
1243
1244bool MSP430TargetLowering::isTruncateFree(Type *Ty1,
1245 Type *Ty2) const {
1246 if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
1247 return false;
1248
1249 return (Ty1->getPrimitiveSizeInBits().getFixedValue() >
1250 Ty2->getPrimitiveSizeInBits().getFixedValue());
1251}
1252
1253bool MSP430TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
1254 if (!VT1.isInteger() || !VT2.isInteger())
1255 return false;
1256
1257 return (VT1.getFixedSizeInBits() > VT2.getFixedSizeInBits());
1258}
1259
1260bool MSP430TargetLowering::isZExtFree(Type *Ty1, Type *Ty2) const {
1261 // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
1262 return false && Ty1->isIntegerTy(Bitwidth: 8) && Ty2->isIntegerTy(Bitwidth: 16);
1263}
1264
1265bool MSP430TargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
1266 // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
1267 return false && VT1 == MVT::i8 && VT2 == MVT::i16;
1268}
1269
1270//===----------------------------------------------------------------------===//
1271// Other Lowering Code
1272//===----------------------------------------------------------------------===//
1273
1274MachineBasicBlock *
1275MSP430TargetLowering::EmitShiftInstr(MachineInstr &MI,
1276 MachineBasicBlock *BB) const {
1277 MachineFunction *F = BB->getParent();
1278 MachineRegisterInfo &RI = F->getRegInfo();
1279 DebugLoc dl = MI.getDebugLoc();
1280 const TargetInstrInfo &TII = *F->getSubtarget().getInstrInfo();
1281
1282 unsigned Opc;
1283 bool ClearCarry = false;
1284 const TargetRegisterClass * RC;
1285 switch (MI.getOpcode()) {
1286 default: llvm_unreachable("Invalid shift opcode!");
1287 case MSP430::Shl8:
1288 Opc = MSP430::ADD8rr;
1289 RC = &MSP430::GR8RegClass;
1290 break;
1291 case MSP430::Shl16:
1292 Opc = MSP430::ADD16rr;
1293 RC = &MSP430::GR16RegClass;
1294 break;
1295 case MSP430::Sra8:
1296 Opc = MSP430::RRA8r;
1297 RC = &MSP430::GR8RegClass;
1298 break;
1299 case MSP430::Sra16:
1300 Opc = MSP430::RRA16r;
1301 RC = &MSP430::GR16RegClass;
1302 break;
1303 case MSP430::Srl8:
1304 ClearCarry = true;
1305 Opc = MSP430::RRC8r;
1306 RC = &MSP430::GR8RegClass;
1307 break;
1308 case MSP430::Srl16:
1309 ClearCarry = true;
1310 Opc = MSP430::RRC16r;
1311 RC = &MSP430::GR16RegClass;
1312 break;
1313 case MSP430::Rrcl8:
1314 case MSP430::Rrcl16: {
1315 BuildMI(BB&: *BB, I&: MI, MIMD: dl, MCID: TII.get(Opcode: MSP430::BIC16rc), DestReg: MSP430::SR)
1316 .addReg(RegNo: MSP430::SR).addImm(Val: 1);
1317 Register SrcReg = MI.getOperand(i: 1).getReg();
1318 Register DstReg = MI.getOperand(i: 0).getReg();
1319 unsigned RrcOpc = MI.getOpcode() == MSP430::Rrcl16
1320 ? MSP430::RRC16r : MSP430::RRC8r;
1321 BuildMI(BB&: *BB, I&: MI, MIMD: dl, MCID: TII.get(Opcode: RrcOpc), DestReg: DstReg)
1322 .addReg(RegNo: SrcReg);
1323 MI.eraseFromParent(); // The pseudo instruction is gone now.
1324 return BB;
1325 }
1326 }
1327
1328 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1329 MachineFunction::iterator I = ++BB->getIterator();
1330
1331 // Create loop block
1332 MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(BB: LLVM_BB);
1333 MachineBasicBlock *RemBB = F->CreateMachineBasicBlock(BB: LLVM_BB);
1334
1335 F->insert(MBBI: I, MBB: LoopBB);
1336 F->insert(MBBI: I, MBB: RemBB);
1337
1338 // Update machine-CFG edges by transferring all successors of the current
1339 // block to the block containing instructions after shift.
1340 RemBB->splice(Where: RemBB->begin(), Other: BB, From: std::next(x: MachineBasicBlock::iterator(MI)),
1341 To: BB->end());
1342 RemBB->transferSuccessorsAndUpdatePHIs(FromMBB: BB);
1343
1344 // Add edges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB
1345 BB->addSuccessor(Succ: LoopBB);
1346 BB->addSuccessor(Succ: RemBB);
1347 LoopBB->addSuccessor(Succ: RemBB);
1348 LoopBB->addSuccessor(Succ: LoopBB);
1349
1350 Register ShiftAmtReg = RI.createVirtualRegister(RegClass: &MSP430::GR8RegClass);
1351 Register ShiftAmtReg2 = RI.createVirtualRegister(RegClass: &MSP430::GR8RegClass);
1352 Register ShiftReg = RI.createVirtualRegister(RegClass: RC);
1353 Register ShiftReg2 = RI.createVirtualRegister(RegClass: RC);
1354 Register ShiftAmtSrcReg = MI.getOperand(i: 2).getReg();
1355 Register SrcReg = MI.getOperand(i: 1).getReg();
1356 Register DstReg = MI.getOperand(i: 0).getReg();
1357
1358 // BB:
1359 // cmp 0, N
1360 // je RemBB
1361 BuildMI(BB, MIMD: dl, MCID: TII.get(Opcode: MSP430::CMP8ri))
1362 .addReg(RegNo: ShiftAmtSrcReg).addImm(Val: 0);
1363 BuildMI(BB, MIMD: dl, MCID: TII.get(Opcode: MSP430::JCC))
1364 .addMBB(MBB: RemBB)
1365 .addImm(Val: MSP430CC::COND_E);
1366
1367 // LoopBB:
1368 // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB]
1369 // ShiftAmt = phi [%N, BB], [%ShiftAmt2, LoopBB]
1370 // ShiftReg2 = shift ShiftReg
1371 // ShiftAmt2 = ShiftAmt - 1;
1372 BuildMI(BB: LoopBB, MIMD: dl, MCID: TII.get(Opcode: MSP430::PHI), DestReg: ShiftReg)
1373 .addReg(RegNo: SrcReg).addMBB(MBB: BB)
1374 .addReg(RegNo: ShiftReg2).addMBB(MBB: LoopBB);
1375 BuildMI(BB: LoopBB, MIMD: dl, MCID: TII.get(Opcode: MSP430::PHI), DestReg: ShiftAmtReg)
1376 .addReg(RegNo: ShiftAmtSrcReg).addMBB(MBB: BB)
1377 .addReg(RegNo: ShiftAmtReg2).addMBB(MBB: LoopBB);
1378 if (ClearCarry)
1379 BuildMI(BB: LoopBB, MIMD: dl, MCID: TII.get(Opcode: MSP430::BIC16rc), DestReg: MSP430::SR)
1380 .addReg(RegNo: MSP430::SR).addImm(Val: 1);
1381 if (Opc == MSP430::ADD8rr || Opc == MSP430::ADD16rr)
1382 BuildMI(BB: LoopBB, MIMD: dl, MCID: TII.get(Opcode: Opc), DestReg: ShiftReg2)
1383 .addReg(RegNo: ShiftReg)
1384 .addReg(RegNo: ShiftReg);
1385 else
1386 BuildMI(BB: LoopBB, MIMD: dl, MCID: TII.get(Opcode: Opc), DestReg: ShiftReg2)
1387 .addReg(RegNo: ShiftReg);
1388 BuildMI(BB: LoopBB, MIMD: dl, MCID: TII.get(Opcode: MSP430::SUB8ri), DestReg: ShiftAmtReg2)
1389 .addReg(RegNo: ShiftAmtReg).addImm(Val: 1);
1390 BuildMI(BB: LoopBB, MIMD: dl, MCID: TII.get(Opcode: MSP430::JCC))
1391 .addMBB(MBB: LoopBB)
1392 .addImm(Val: MSP430CC::COND_NE);
1393
1394 // RemBB:
1395 // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB]
1396 BuildMI(BB&: *RemBB, I: RemBB->begin(), MIMD: dl, MCID: TII.get(Opcode: MSP430::PHI), DestReg: DstReg)
1397 .addReg(RegNo: SrcReg).addMBB(MBB: BB)
1398 .addReg(RegNo: ShiftReg2).addMBB(MBB: LoopBB);
1399
1400 MI.eraseFromParent(); // The pseudo instruction is gone now.
1401 return RemBB;
1402}
1403
1404MachineBasicBlock *
1405MSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
1406 MachineBasicBlock *BB) const {
1407 unsigned Opc = MI.getOpcode();
1408
1409 if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 ||
1410 Opc == MSP430::Sra8 || Opc == MSP430::Sra16 ||
1411 Opc == MSP430::Srl8 || Opc == MSP430::Srl16 ||
1412 Opc == MSP430::Rrcl8 || Opc == MSP430::Rrcl16)
1413 return EmitShiftInstr(MI, BB);
1414
1415 const TargetInstrInfo &TII = *BB->getParent()->getSubtarget().getInstrInfo();
1416 DebugLoc dl = MI.getDebugLoc();
1417
1418 assert((Opc == MSP430::Select16 || Opc == MSP430::Select8) &&
1419 "Unexpected instr type to insert");
1420
1421 // To "insert" a SELECT instruction, we actually have to insert the diamond
1422 // control-flow pattern. The incoming instruction knows the destination vreg
1423 // to set, the condition code register to branch on, the true/false values to
1424 // select between, and a branch opcode to use.
1425 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1426 MachineFunction::iterator I = ++BB->getIterator();
1427
1428 // thisMBB:
1429 // ...
1430 // TrueVal = ...
1431 // cmpTY ccX, r1, r2
1432 // jCC copy1MBB
1433 // fallthrough --> copy0MBB
1434 MachineBasicBlock *thisMBB = BB;
1435 MachineFunction *F = BB->getParent();
1436 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(BB: LLVM_BB);
1437 MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(BB: LLVM_BB);
1438 F->insert(MBBI: I, MBB: copy0MBB);
1439 F->insert(MBBI: I, MBB: copy1MBB);
1440 // Update machine-CFG edges by transferring all successors of the current
1441 // block to the new block which will contain the Phi node for the select.
1442 copy1MBB->splice(Where: copy1MBB->begin(), Other: BB,
1443 From: std::next(x: MachineBasicBlock::iterator(MI)), To: BB->end());
1444 copy1MBB->transferSuccessorsAndUpdatePHIs(FromMBB: BB);
1445 // Next, add the true and fallthrough blocks as its successors.
1446 BB->addSuccessor(Succ: copy0MBB);
1447 BB->addSuccessor(Succ: copy1MBB);
1448
1449 BuildMI(BB, MIMD: dl, MCID: TII.get(Opcode: MSP430::JCC))
1450 .addMBB(MBB: copy1MBB)
1451 .addImm(Val: MI.getOperand(i: 3).getImm());
1452
1453 // copy0MBB:
1454 // %FalseValue = ...
1455 // # fallthrough to copy1MBB
1456 BB = copy0MBB;
1457
1458 // Update machine-CFG edges
1459 BB->addSuccessor(Succ: copy1MBB);
1460
1461 // copy1MBB:
1462 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
1463 // ...
1464 BB = copy1MBB;
1465 BuildMI(BB&: *BB, I: BB->begin(), MIMD: dl, MCID: TII.get(Opcode: MSP430::PHI), DestReg: MI.getOperand(i: 0).getReg())
1466 .addReg(RegNo: MI.getOperand(i: 2).getReg())
1467 .addMBB(MBB: copy0MBB)
1468 .addReg(RegNo: MI.getOperand(i: 1).getReg())
1469 .addMBB(MBB: thisMBB);
1470
1471 MI.eraseFromParent(); // The pseudo instruction is gone now.
1472 return BB;
1473}
1474