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