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 MemOp = DAG.getMemcpy(Chain, dl, Dst: PtrOff, Src: Arg, Size: SizeNode,
689 Alignment: Flags.getNonZeroByValAlign(),
690 /*isVolatile*/ isVol: false,
691 /*AlwaysInline=*/true,
692 /*CI=*/nullptr, OverrideTailCall: std::nullopt,
693 DstPtrInfo: MachinePointerInfo(), SrcPtrInfo: MachinePointerInfo());
694 } else {
695 MemOp = DAG.getStore(Chain, dl, Val: Arg, Ptr: PtrOff, PtrInfo: MachinePointerInfo());
696 }
697
698 MemOpChains.push_back(Elt: MemOp);
699 }
700 }
701
702 // Transform all store nodes into one single node because all store nodes are
703 // independent of each other.
704 if (!MemOpChains.empty())
705 Chain = DAG.getNode(Opcode: ISD::TokenFactor, DL: dl, VT: MVT::Other, Ops: MemOpChains);
706
707 // Build a sequence of copy-to-reg nodes chained together with token chain and
708 // flag operands which copy the outgoing args into registers. The InGlue in
709 // necessary since all emitted instructions must be stuck together.
710 SDValue InGlue;
711 for (const auto &[Reg, N] : RegsToPass) {
712 Chain = DAG.getCopyToReg(Chain, dl, Reg, N, Glue: InGlue);
713 InGlue = Chain.getValue(R: 1);
714 }
715
716 // If the callee is a GlobalAddress node (quite common, every direct call is)
717 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
718 // Likewise ExternalSymbol -> TargetExternalSymbol.
719 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Val&: Callee))
720 Callee = DAG.getTargetGlobalAddress(GV: G->getGlobal(), DL: dl, VT: MVT::i16);
721 else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Val&: Callee))
722 Callee = DAG.getTargetExternalSymbol(Sym: E->getSymbol(), VT: MVT::i16);
723
724 // Returns a chain & a flag for retval copy to use.
725 SDVTList NodeTys = DAG.getVTList(VT1: MVT::Other, VT2: MVT::Glue);
726 SmallVector<SDValue, 8> Ops;
727 Ops.push_back(Elt: Chain);
728 Ops.push_back(Elt: Callee);
729
730 // Add argument registers to the end of the list so that they are
731 // known live into the call.
732 for (const auto &[Reg, N] : RegsToPass)
733 Ops.push_back(Elt: DAG.getRegister(Reg, VT: N.getValueType()));
734
735 if (InGlue.getNode())
736 Ops.push_back(Elt: InGlue);
737
738 Chain = DAG.getNode(Opcode: MSP430ISD::CALL, DL: dl, VTList: NodeTys, Ops);
739 InGlue = Chain.getValue(R: 1);
740
741 // Create the CALLSEQ_END node.
742 Chain = DAG.getCALLSEQ_END(Chain, Size1: NumBytes, Size2: 0, Glue: InGlue, DL: dl);
743 InGlue = Chain.getValue(R: 1);
744
745 // Handle result values, copying them out of physregs into vregs that we
746 // return.
747 return LowerCallResult(Chain, InGlue, CallConv, isVarArg, Ins, dl,
748 DAG, InVals);
749}
750
751/// LowerCallResult - Lower the result values of a call into the
752/// appropriate copies out of appropriate physical registers.
753///
754SDValue MSP430TargetLowering::LowerCallResult(
755 SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool isVarArg,
756 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
757 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
758
759 // Assign locations to each value returned by this call.
760 SmallVector<CCValAssign, 16> RVLocs;
761 CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
762 *DAG.getContext());
763
764 AnalyzeReturnValues(State&: CCInfo, RVLocs, Args: Ins);
765
766 // Copy all of the result registers out of their specified physreg.
767 for (unsigned i = 0; i != RVLocs.size(); ++i) {
768 Chain = DAG.getCopyFromReg(Chain, dl, Reg: RVLocs[i].getLocReg(),
769 VT: RVLocs[i].getValVT(), Glue: InGlue).getValue(R: 1);
770 InGlue = Chain.getValue(R: 2);
771 InVals.push_back(Elt: Chain.getValue(R: 0));
772 }
773
774 return Chain;
775}
776
777SDValue MSP430TargetLowering::LowerShifts(SDValue Op,
778 SelectionDAG &DAG) const {
779 unsigned Opc = Op.getOpcode();
780 SDNode* N = Op.getNode();
781 EVT VT = Op.getValueType();
782 SDLoc dl(N);
783
784 // Expand non-constant shifts to loops:
785 if (!isa<ConstantSDNode>(Val: N->getOperand(Num: 1)))
786 return Op;
787
788 uint64_t ShiftAmount = N->getConstantOperandVal(Num: 1);
789
790 // Expand the stuff into sequence of shifts.
791 SDValue Victim = N->getOperand(Num: 0);
792
793 if (ShiftAmount >= 8) {
794 assert(VT == MVT::i16 && "Can not shift i8 by 8 and more");
795 switch(Opc) {
796 default:
797 llvm_unreachable("Unknown shift");
798 case ISD::SHL:
799 // foo << (8 + N) => swpb(zext(foo)) << N
800 Victim = DAG.getZeroExtendInReg(Op: Victim, DL: dl, VT: MVT::i8);
801 Victim = DAG.getNode(Opcode: ISD::BSWAP, DL: dl, VT, Operand: Victim);
802 break;
803 case ISD::SRA:
804 case ISD::SRL:
805 // foo >> (8 + N) => sxt(swpb(foo)) >> N
806 Victim = DAG.getNode(Opcode: ISD::BSWAP, DL: dl, VT, Operand: Victim);
807 Victim = (Opc == ISD::SRA)
808 ? DAG.getNode(Opcode: ISD::SIGN_EXTEND_INREG, DL: dl, VT, N1: Victim,
809 N2: DAG.getValueType(MVT::i8))
810 : DAG.getZeroExtendInReg(Op: Victim, DL: dl, VT: MVT::i8);
811 break;
812 }
813 ShiftAmount -= 8;
814 }
815
816 if (Opc == ISD::SRL && ShiftAmount) {
817 // Emit a special goodness here:
818 // srl A, 1 => clrc; rrc A
819 Victim = DAG.getNode(Opcode: MSP430ISD::RRCL, DL: dl, VT, Operand: Victim);
820 ShiftAmount -= 1;
821 }
822
823 while (ShiftAmount--)
824 Victim = DAG.getNode(Opcode: (Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA),
825 DL: dl, VT, Operand: Victim);
826
827 return Victim;
828}
829
830SDValue MSP430TargetLowering::LowerGlobalAddress(SDValue Op,
831 SelectionDAG &DAG) const {
832 const GlobalValue *GV = cast<GlobalAddressSDNode>(Val&: Op)->getGlobal();
833 int64_t Offset = cast<GlobalAddressSDNode>(Val&: Op)->getOffset();
834 EVT PtrVT = Op.getValueType();
835
836 // Create the TargetGlobalAddress node, folding in the constant offset.
837 SDValue Result = DAG.getTargetGlobalAddress(GV, DL: SDLoc(Op), VT: PtrVT, offset: Offset);
838 return DAG.getNode(Opcode: MSP430ISD::Wrapper, DL: SDLoc(Op), VT: PtrVT, Operand: Result);
839}
840
841SDValue MSP430TargetLowering::LowerExternalSymbol(SDValue Op,
842 SelectionDAG &DAG) const {
843 SDLoc dl(Op);
844 const char *Sym = cast<ExternalSymbolSDNode>(Val&: Op)->getSymbol();
845 EVT PtrVT = Op.getValueType();
846 SDValue Result = DAG.getTargetExternalSymbol(Sym, VT: PtrVT);
847
848 return DAG.getNode(Opcode: MSP430ISD::Wrapper, DL: dl, VT: PtrVT, Operand: Result);
849}
850
851SDValue MSP430TargetLowering::LowerBlockAddress(SDValue Op,
852 SelectionDAG &DAG) const {
853 SDLoc dl(Op);
854 const BlockAddress *BA = cast<BlockAddressSDNode>(Val&: Op)->getBlockAddress();
855 EVT PtrVT = Op.getValueType();
856 SDValue Result = DAG.getTargetBlockAddress(BA, VT: PtrVT);
857
858 return DAG.getNode(Opcode: MSP430ISD::Wrapper, DL: dl, VT: PtrVT, Operand: Result);
859}
860
861static SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC,
862 ISD::CondCode CC, const SDLoc &dl, SelectionDAG &DAG) {
863 // FIXME: Handle bittests someday
864 assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet");
865
866 // FIXME: Handle jump negative someday
867 MSP430CC::CondCodes TCC = MSP430CC::COND_INVALID;
868 switch (CC) {
869 default: llvm_unreachable("Invalid integer condition!");
870 case ISD::SETEQ:
871 TCC = MSP430CC::COND_E; // aka COND_Z
872 // Minor optimization: if LHS is a constant, swap operands, then the
873 // constant can be folded into comparison.
874 if (LHS.getOpcode() == ISD::Constant)
875 std::swap(a&: LHS, b&: RHS);
876 break;
877 case ISD::SETNE:
878 TCC = MSP430CC::COND_NE; // aka COND_NZ
879 // Minor optimization: if LHS is a constant, swap operands, then the
880 // constant can be folded into comparison.
881 if (LHS.getOpcode() == ISD::Constant)
882 std::swap(a&: LHS, b&: RHS);
883 break;
884 case ISD::SETULE:
885 std::swap(a&: LHS, b&: RHS);
886 [[fallthrough]];
887 case ISD::SETUGE:
888 // Turn lhs u>= rhs with lhs constant into rhs u< lhs+1, this allows us to
889 // fold constant into instruction.
890 if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(Val&: LHS)) {
891 LHS = RHS;
892 RHS = DAG.getConstant(Val: C->getSExtValue() + 1, DL: dl, VT: C->getValueType(ResNo: 0));
893 TCC = MSP430CC::COND_LO;
894 break;
895 }
896 TCC = MSP430CC::COND_HS; // aka COND_C
897 break;
898 case ISD::SETUGT:
899 std::swap(a&: LHS, b&: RHS);
900 [[fallthrough]];
901 case ISD::SETULT:
902 // Turn lhs u< rhs with lhs constant into rhs u>= lhs+1, this allows us to
903 // fold constant into instruction.
904 if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(Val&: LHS)) {
905 LHS = RHS;
906 RHS = DAG.getConstant(Val: C->getSExtValue() + 1, DL: dl, VT: C->getValueType(ResNo: 0));
907 TCC = MSP430CC::COND_HS;
908 break;
909 }
910 TCC = MSP430CC::COND_LO; // aka COND_NC
911 break;
912 case ISD::SETLE:
913 std::swap(a&: LHS, b&: RHS);
914 [[fallthrough]];
915 case ISD::SETGE:
916 // Turn lhs >= rhs with lhs constant into rhs < lhs+1, this allows us to
917 // fold constant into instruction.
918 if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(Val&: LHS)) {
919 LHS = RHS;
920 RHS = DAG.getConstant(Val: C->getSExtValue() + 1, DL: dl, VT: C->getValueType(ResNo: 0));
921 TCC = MSP430CC::COND_L;
922 break;
923 }
924 TCC = MSP430CC::COND_GE;
925 break;
926 case ISD::SETGT:
927 std::swap(a&: LHS, b&: RHS);
928 [[fallthrough]];
929 case ISD::SETLT:
930 // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to
931 // fold constant into instruction.
932 if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(Val&: LHS)) {
933 LHS = RHS;
934 RHS = DAG.getConstant(Val: C->getSExtValue() + 1, DL: dl, VT: C->getValueType(ResNo: 0));
935 TCC = MSP430CC::COND_GE;
936 break;
937 }
938 TCC = MSP430CC::COND_L;
939 break;
940 }
941
942 TargetCC = DAG.getConstant(Val: TCC, DL: dl, VT: MVT::i8);
943 return DAG.getNode(Opcode: MSP430ISD::CMP, DL: dl, VT: MVT::Glue, N1: LHS, N2: RHS);
944}
945
946
947SDValue MSP430TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
948 SDValue Chain = Op.getOperand(i: 0);
949 ISD::CondCode CC = cast<CondCodeSDNode>(Val: Op.getOperand(i: 1))->get();
950 SDValue LHS = Op.getOperand(i: 2);
951 SDValue RHS = Op.getOperand(i: 3);
952 SDValue Dest = Op.getOperand(i: 4);
953 SDLoc dl (Op);
954
955 SDValue TargetCC;
956 SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
957
958 return DAG.getNode(Opcode: MSP430ISD::BR_CC, DL: dl, VT: Op.getValueType(),
959 N1: Chain, N2: Dest, N3: TargetCC, N4: Flag);
960}
961
962SDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
963 SDValue LHS = Op.getOperand(i: 0);
964 SDValue RHS = Op.getOperand(i: 1);
965 SDLoc dl (Op);
966
967 // If we are doing an AND and testing against zero, then the CMP
968 // will not be generated. The AND (or BIT) will generate the condition codes,
969 // but they are different from CMP.
970 // FIXME: since we're doing a post-processing, use a pseudoinstr here, so
971 // lowering & isel wouldn't diverge.
972 bool andCC = isNullConstant(V: RHS) && LHS.hasOneUse() &&
973 (LHS.getOpcode() == ISD::AND ||
974 (LHS.getOpcode() == ISD::TRUNCATE &&
975 LHS.getOperand(i: 0).getOpcode() == ISD::AND));
976 ISD::CondCode CC = cast<CondCodeSDNode>(Val: Op.getOperand(i: 2))->get();
977 SDValue TargetCC;
978 SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
979
980 // Get the condition codes directly from the status register, if its easy.
981 // Otherwise a branch will be generated. Note that the AND and BIT
982 // instructions generate different flags than CMP, the carry bit can be used
983 // for NE/EQ.
984 bool Invert = false;
985 bool Shift = false;
986 bool Convert = true;
987 switch (TargetCC->getAsZExtVal()) {
988 default:
989 Convert = false;
990 break;
991 case MSP430CC::COND_HS:
992 // Res = SR & 1, no processing is required
993 break;
994 case MSP430CC::COND_LO:
995 // Res = ~(SR & 1)
996 Invert = true;
997 break;
998 case MSP430CC::COND_NE:
999 if (andCC) {
1000 // C = ~Z, thus Res = SR & 1, no processing is required
1001 } else {
1002 // Res = ~((SR >> 1) & 1)
1003 Shift = true;
1004 Invert = true;
1005 }
1006 break;
1007 case MSP430CC::COND_E:
1008 Shift = true;
1009 // C = ~Z for AND instruction, thus we can put Res = ~(SR & 1), however,
1010 // Res = (SR >> 1) & 1 is 1 word shorter.
1011 break;
1012 }
1013 EVT VT = Op.getValueType();
1014 SDValue One = DAG.getConstant(Val: 1, DL: dl, VT);
1015 if (Convert) {
1016 SDValue SR = DAG.getCopyFromReg(Chain: DAG.getEntryNode(), dl, Reg: MSP430::SR,
1017 VT: MVT::i16, Glue: Flag);
1018 if (Shift)
1019 // FIXME: somewhere this is turned into a SRL, lower it MSP specific?
1020 SR = DAG.getNode(Opcode: ISD::SRA, DL: dl, VT: MVT::i16, N1: SR, N2: One);
1021 SR = DAG.getNode(Opcode: ISD::AND, DL: dl, VT: MVT::i16, N1: SR, N2: One);
1022 if (Invert)
1023 SR = DAG.getNode(Opcode: ISD::XOR, DL: dl, VT: MVT::i16, N1: SR, N2: One);
1024 return SR;
1025 } else {
1026 SDValue Zero = DAG.getConstant(Val: 0, DL: dl, VT);
1027 SDValue Ops[] = {One, Zero, TargetCC, Flag};
1028 return DAG.getNode(Opcode: MSP430ISD::SELECT_CC, DL: dl, VT: Op.getValueType(), Ops);
1029 }
1030}
1031
1032SDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op,
1033 SelectionDAG &DAG) const {
1034 SDValue LHS = Op.getOperand(i: 0);
1035 SDValue RHS = Op.getOperand(i: 1);
1036 SDValue TrueV = Op.getOperand(i: 2);
1037 SDValue FalseV = Op.getOperand(i: 3);
1038 ISD::CondCode CC = cast<CondCodeSDNode>(Val: Op.getOperand(i: 4))->get();
1039 SDLoc dl (Op);
1040
1041 SDValue TargetCC;
1042 SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
1043
1044 SDValue Ops[] = {TrueV, FalseV, TargetCC, Flag};
1045
1046 return DAG.getNode(Opcode: MSP430ISD::SELECT_CC, DL: dl, VT: Op.getValueType(), Ops);
1047}
1048
1049SDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op,
1050 SelectionDAG &DAG) const {
1051 SDValue Val = Op.getOperand(i: 0);
1052 EVT VT = Op.getValueType();
1053 SDLoc dl(Op);
1054
1055 assert(VT == MVT::i16 && "Only support i16 for now!");
1056
1057 return DAG.getNode(Opcode: ISD::SIGN_EXTEND_INREG, DL: dl, VT,
1058 N1: DAG.getNode(Opcode: ISD::ANY_EXTEND, DL: dl, VT, Operand: Val),
1059 N2: DAG.getValueType(Val.getValueType()));
1060}
1061
1062SDValue
1063MSP430TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) const {
1064 MachineFunction &MF = DAG.getMachineFunction();
1065 MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
1066 int ReturnAddrIndex = FuncInfo->getRAIndex();
1067 MVT PtrVT = getFrameIndexTy(DL: MF.getDataLayout());
1068
1069 if (ReturnAddrIndex == 0) {
1070 // Set up a frame object for the return address.
1071 uint64_t SlotSize = PtrVT.getStoreSize();
1072 ReturnAddrIndex = MF.getFrameInfo().CreateFixedObject(Size: SlotSize, SPOffset: -SlotSize,
1073 IsImmutable: true);
1074 FuncInfo->setRAIndex(ReturnAddrIndex);
1075 }
1076
1077 return DAG.getFrameIndex(FI: ReturnAddrIndex, VT: PtrVT);
1078}
1079
1080SDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op,
1081 SelectionDAG &DAG) const {
1082 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
1083 MFI.setReturnAddressIsTaken(true);
1084
1085 unsigned Depth = Op.getConstantOperandVal(i: 0);
1086 SDLoc dl(Op);
1087 EVT PtrVT = Op.getValueType();
1088
1089 if (Depth > 0) {
1090 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
1091 SDValue Offset =
1092 DAG.getConstant(Val: PtrVT.getStoreSize(), DL: dl, VT: MVT::i16);
1093 return DAG.getLoad(VT: PtrVT, dl, Chain: DAG.getEntryNode(),
1094 Ptr: DAG.getNode(Opcode: ISD::ADD, DL: dl, VT: PtrVT, N1: FrameAddr, N2: Offset),
1095 PtrInfo: MachinePointerInfo());
1096 }
1097
1098 // Just load the return address.
1099 SDValue RetAddrFI = getReturnAddressFrameIndex(DAG);
1100 return DAG.getLoad(VT: PtrVT, dl, Chain: DAG.getEntryNode(), Ptr: RetAddrFI,
1101 PtrInfo: MachinePointerInfo());
1102}
1103
1104SDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op,
1105 SelectionDAG &DAG) const {
1106 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
1107 MFI.setFrameAddressIsTaken(true);
1108
1109 EVT VT = Op.getValueType();
1110 SDLoc dl(Op); // FIXME probably not meaningful
1111 unsigned Depth = Op.getConstantOperandVal(i: 0);
1112 SDValue FrameAddr = DAG.getCopyFromReg(Chain: DAG.getEntryNode(), dl,
1113 Reg: MSP430::R4, VT);
1114 while (Depth--)
1115 FrameAddr = DAG.getLoad(VT, dl, Chain: DAG.getEntryNode(), Ptr: FrameAddr,
1116 PtrInfo: MachinePointerInfo());
1117 return FrameAddr;
1118}
1119
1120SDValue MSP430TargetLowering::LowerVASTART(SDValue Op,
1121 SelectionDAG &DAG) const {
1122 MachineFunction &MF = DAG.getMachineFunction();
1123 MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
1124
1125 SDValue Ptr = Op.getOperand(i: 1);
1126 EVT PtrVT = Ptr.getValueType();
1127
1128 // Frame index of first vararg argument
1129 SDValue FrameIndex =
1130 DAG.getFrameIndex(FI: FuncInfo->getVarArgsFrameIndex(), VT: PtrVT);
1131 const Value *SV = cast<SrcValueSDNode>(Val: Op.getOperand(i: 2))->getValue();
1132
1133 // Create a store of the frame index to the location operand
1134 return DAG.getStore(Chain: Op.getOperand(i: 0), dl: SDLoc(Op), Val: FrameIndex, Ptr,
1135 PtrInfo: MachinePointerInfo(SV));
1136}
1137
1138SDValue MSP430TargetLowering::LowerJumpTable(SDValue Op,
1139 SelectionDAG &DAG) const {
1140 JumpTableSDNode *JT = cast<JumpTableSDNode>(Val&: Op);
1141 EVT PtrVT = Op.getValueType();
1142 SDValue Result = DAG.getTargetJumpTable(JTI: JT->getIndex(), VT: PtrVT);
1143 return DAG.getNode(Opcode: MSP430ISD::Wrapper, DL: SDLoc(JT), VT: PtrVT, Operand: Result);
1144}
1145
1146/// getPostIndexedAddressParts - returns true by value, base pointer and
1147/// offset pointer and addressing mode by reference if this node can be
1148/// combined with a load / store to form a post-indexed load / store.
1149bool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
1150 SDValue &Base,
1151 SDValue &Offset,
1152 ISD::MemIndexedMode &AM,
1153 SelectionDAG &DAG) const {
1154
1155 LoadSDNode *LD = cast<LoadSDNode>(Val: N);
1156 if (LD->getExtensionType() != ISD::NON_EXTLOAD)
1157 return false;
1158
1159 EVT VT = LD->getMemoryVT();
1160 if (VT != MVT::i8 && VT != MVT::i16)
1161 return false;
1162
1163 if (Op->getOpcode() != ISD::ADD)
1164 return false;
1165
1166 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Val: Op->getOperand(Num: 1))) {
1167 uint64_t RHSC = RHS->getZExtValue();
1168 if ((VT == MVT::i16 && RHSC != 2) ||
1169 (VT == MVT::i8 && RHSC != 1))
1170 return false;
1171
1172 Base = Op->getOperand(Num: 0);
1173 Offset = DAG.getConstant(Val: RHSC, DL: SDLoc(N), VT);
1174 AM = ISD::POST_INC;
1175 return true;
1176 }
1177
1178 return false;
1179}
1180
1181bool MSP430TargetLowering::isTruncateFree(Type *Ty1,
1182 Type *Ty2) const {
1183 if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
1184 return false;
1185
1186 return (Ty1->getPrimitiveSizeInBits().getFixedValue() >
1187 Ty2->getPrimitiveSizeInBits().getFixedValue());
1188}
1189
1190bool MSP430TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
1191 if (!VT1.isInteger() || !VT2.isInteger())
1192 return false;
1193
1194 return (VT1.getFixedSizeInBits() > VT2.getFixedSizeInBits());
1195}
1196
1197bool MSP430TargetLowering::isZExtFree(Type *Ty1, Type *Ty2) const {
1198 // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
1199 return false && Ty1->isIntegerTy(Bitwidth: 8) && Ty2->isIntegerTy(Bitwidth: 16);
1200}
1201
1202bool MSP430TargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
1203 // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
1204 return false && VT1 == MVT::i8 && VT2 == MVT::i16;
1205}
1206
1207//===----------------------------------------------------------------------===//
1208// Other Lowering Code
1209//===----------------------------------------------------------------------===//
1210
1211MachineBasicBlock *
1212MSP430TargetLowering::EmitShiftInstr(MachineInstr &MI,
1213 MachineBasicBlock *BB) const {
1214 MachineFunction *F = BB->getParent();
1215 MachineRegisterInfo &RI = F->getRegInfo();
1216 DebugLoc dl = MI.getDebugLoc();
1217 const TargetInstrInfo &TII = *F->getSubtarget().getInstrInfo();
1218
1219 unsigned Opc;
1220 bool ClearCarry = false;
1221 const TargetRegisterClass * RC;
1222 switch (MI.getOpcode()) {
1223 default: llvm_unreachable("Invalid shift opcode!");
1224 case MSP430::Shl8:
1225 Opc = MSP430::ADD8rr;
1226 RC = &MSP430::GR8RegClass;
1227 break;
1228 case MSP430::Shl16:
1229 Opc = MSP430::ADD16rr;
1230 RC = &MSP430::GR16RegClass;
1231 break;
1232 case MSP430::Sra8:
1233 Opc = MSP430::RRA8r;
1234 RC = &MSP430::GR8RegClass;
1235 break;
1236 case MSP430::Sra16:
1237 Opc = MSP430::RRA16r;
1238 RC = &MSP430::GR16RegClass;
1239 break;
1240 case MSP430::Srl8:
1241 ClearCarry = true;
1242 Opc = MSP430::RRC8r;
1243 RC = &MSP430::GR8RegClass;
1244 break;
1245 case MSP430::Srl16:
1246 ClearCarry = true;
1247 Opc = MSP430::RRC16r;
1248 RC = &MSP430::GR16RegClass;
1249 break;
1250 case MSP430::Rrcl8:
1251 case MSP430::Rrcl16: {
1252 BuildMI(BB&: *BB, I&: MI, MIMD: dl, MCID: TII.get(Opcode: MSP430::BIC16rc), DestReg: MSP430::SR)
1253 .addReg(RegNo: MSP430::SR).addImm(Val: 1);
1254 Register SrcReg = MI.getOperand(i: 1).getReg();
1255 Register DstReg = MI.getOperand(i: 0).getReg();
1256 unsigned RrcOpc = MI.getOpcode() == MSP430::Rrcl16
1257 ? MSP430::RRC16r : MSP430::RRC8r;
1258 BuildMI(BB&: *BB, I&: MI, MIMD: dl, MCID: TII.get(Opcode: RrcOpc), DestReg: DstReg)
1259 .addReg(RegNo: SrcReg);
1260 MI.eraseFromParent(); // The pseudo instruction is gone now.
1261 return BB;
1262 }
1263 }
1264
1265 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1266 MachineFunction::iterator I = ++BB->getIterator();
1267
1268 // Create loop block
1269 MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(BB: LLVM_BB);
1270 MachineBasicBlock *RemBB = F->CreateMachineBasicBlock(BB: LLVM_BB);
1271
1272 F->insert(MBBI: I, MBB: LoopBB);
1273 F->insert(MBBI: I, MBB: RemBB);
1274
1275 // Update machine-CFG edges by transferring all successors of the current
1276 // block to the block containing instructions after shift.
1277 RemBB->splice(Where: RemBB->begin(), Other: BB, From: std::next(x: MachineBasicBlock::iterator(MI)),
1278 To: BB->end());
1279 RemBB->transferSuccessorsAndUpdatePHIs(FromMBB: BB);
1280
1281 // Add edges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB
1282 BB->addSuccessor(Succ: LoopBB);
1283 BB->addSuccessor(Succ: RemBB);
1284 LoopBB->addSuccessor(Succ: RemBB);
1285 LoopBB->addSuccessor(Succ: LoopBB);
1286
1287 Register ShiftAmtReg = RI.createVirtualRegister(RegClass: &MSP430::GR8RegClass);
1288 Register ShiftAmtReg2 = RI.createVirtualRegister(RegClass: &MSP430::GR8RegClass);
1289 Register ShiftReg = RI.createVirtualRegister(RegClass: RC);
1290 Register ShiftReg2 = RI.createVirtualRegister(RegClass: RC);
1291 Register ShiftAmtSrcReg = MI.getOperand(i: 2).getReg();
1292 Register SrcReg = MI.getOperand(i: 1).getReg();
1293 Register DstReg = MI.getOperand(i: 0).getReg();
1294
1295 // BB:
1296 // cmp 0, N
1297 // je RemBB
1298 BuildMI(BB, MIMD: dl, MCID: TII.get(Opcode: MSP430::CMP8ri))
1299 .addReg(RegNo: ShiftAmtSrcReg).addImm(Val: 0);
1300 BuildMI(BB, MIMD: dl, MCID: TII.get(Opcode: MSP430::JCC))
1301 .addMBB(MBB: RemBB)
1302 .addImm(Val: MSP430CC::COND_E);
1303
1304 // LoopBB:
1305 // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB]
1306 // ShiftAmt = phi [%N, BB], [%ShiftAmt2, LoopBB]
1307 // ShiftReg2 = shift ShiftReg
1308 // ShiftAmt2 = ShiftAmt - 1;
1309 BuildMI(BB: LoopBB, MIMD: dl, MCID: TII.get(Opcode: MSP430::PHI), DestReg: ShiftReg)
1310 .addReg(RegNo: SrcReg).addMBB(MBB: BB)
1311 .addReg(RegNo: ShiftReg2).addMBB(MBB: LoopBB);
1312 BuildMI(BB: LoopBB, MIMD: dl, MCID: TII.get(Opcode: MSP430::PHI), DestReg: ShiftAmtReg)
1313 .addReg(RegNo: ShiftAmtSrcReg).addMBB(MBB: BB)
1314 .addReg(RegNo: ShiftAmtReg2).addMBB(MBB: LoopBB);
1315 if (ClearCarry)
1316 BuildMI(BB: LoopBB, MIMD: dl, MCID: TII.get(Opcode: MSP430::BIC16rc), DestReg: MSP430::SR)
1317 .addReg(RegNo: MSP430::SR).addImm(Val: 1);
1318 if (Opc == MSP430::ADD8rr || Opc == MSP430::ADD16rr)
1319 BuildMI(BB: LoopBB, MIMD: dl, MCID: TII.get(Opcode: Opc), DestReg: ShiftReg2)
1320 .addReg(RegNo: ShiftReg)
1321 .addReg(RegNo: ShiftReg);
1322 else
1323 BuildMI(BB: LoopBB, MIMD: dl, MCID: TII.get(Opcode: Opc), DestReg: ShiftReg2)
1324 .addReg(RegNo: ShiftReg);
1325 BuildMI(BB: LoopBB, MIMD: dl, MCID: TII.get(Opcode: MSP430::SUB8ri), DestReg: ShiftAmtReg2)
1326 .addReg(RegNo: ShiftAmtReg).addImm(Val: 1);
1327 BuildMI(BB: LoopBB, MIMD: dl, MCID: TII.get(Opcode: MSP430::JCC))
1328 .addMBB(MBB: LoopBB)
1329 .addImm(Val: MSP430CC::COND_NE);
1330
1331 // RemBB:
1332 // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB]
1333 BuildMI(BB&: *RemBB, I: RemBB->begin(), MIMD: dl, MCID: TII.get(Opcode: MSP430::PHI), DestReg: DstReg)
1334 .addReg(RegNo: SrcReg).addMBB(MBB: BB)
1335 .addReg(RegNo: ShiftReg2).addMBB(MBB: LoopBB);
1336
1337 MI.eraseFromParent(); // The pseudo instruction is gone now.
1338 return RemBB;
1339}
1340
1341MachineBasicBlock *
1342MSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
1343 MachineBasicBlock *BB) const {
1344 unsigned Opc = MI.getOpcode();
1345
1346 if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 ||
1347 Opc == MSP430::Sra8 || Opc == MSP430::Sra16 ||
1348 Opc == MSP430::Srl8 || Opc == MSP430::Srl16 ||
1349 Opc == MSP430::Rrcl8 || Opc == MSP430::Rrcl16)
1350 return EmitShiftInstr(MI, BB);
1351
1352 const TargetInstrInfo &TII = *BB->getParent()->getSubtarget().getInstrInfo();
1353 DebugLoc dl = MI.getDebugLoc();
1354
1355 assert((Opc == MSP430::Select16 || Opc == MSP430::Select8) &&
1356 "Unexpected instr type to insert");
1357
1358 // To "insert" a SELECT instruction, we actually have to insert the diamond
1359 // control-flow pattern. The incoming instruction knows the destination vreg
1360 // to set, the condition code register to branch on, the true/false values to
1361 // select between, and a branch opcode to use.
1362 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1363 MachineFunction::iterator I = ++BB->getIterator();
1364
1365 // thisMBB:
1366 // ...
1367 // TrueVal = ...
1368 // cmpTY ccX, r1, r2
1369 // jCC copy1MBB
1370 // fallthrough --> copy0MBB
1371 MachineBasicBlock *thisMBB = BB;
1372 MachineFunction *F = BB->getParent();
1373 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(BB: LLVM_BB);
1374 MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(BB: LLVM_BB);
1375 F->insert(MBBI: I, MBB: copy0MBB);
1376 F->insert(MBBI: I, MBB: copy1MBB);
1377 // Update machine-CFG edges by transferring all successors of the current
1378 // block to the new block which will contain the Phi node for the select.
1379 copy1MBB->splice(Where: copy1MBB->begin(), Other: BB,
1380 From: std::next(x: MachineBasicBlock::iterator(MI)), To: BB->end());
1381 copy1MBB->transferSuccessorsAndUpdatePHIs(FromMBB: BB);
1382 // Next, add the true and fallthrough blocks as its successors.
1383 BB->addSuccessor(Succ: copy0MBB);
1384 BB->addSuccessor(Succ: copy1MBB);
1385
1386 BuildMI(BB, MIMD: dl, MCID: TII.get(Opcode: MSP430::JCC))
1387 .addMBB(MBB: copy1MBB)
1388 .addImm(Val: MI.getOperand(i: 3).getImm());
1389
1390 // copy0MBB:
1391 // %FalseValue = ...
1392 // # fallthrough to copy1MBB
1393 BB = copy0MBB;
1394
1395 // Update machine-CFG edges
1396 BB->addSuccessor(Succ: copy1MBB);
1397
1398 // copy1MBB:
1399 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
1400 // ...
1401 BB = copy1MBB;
1402 BuildMI(BB&: *BB, I: BB->begin(), MIMD: dl, MCID: TII.get(Opcode: MSP430::PHI), DestReg: MI.getOperand(i: 0).getReg())
1403 .addReg(RegNo: MI.getOperand(i: 2).getReg())
1404 .addMBB(MBB: copy0MBB)
1405 .addReg(RegNo: MI.getOperand(i: 1).getReg())
1406 .addMBB(MBB: thisMBB);
1407
1408 MI.eraseFromParent(); // The pseudo instruction is gone now.
1409 return BB;
1410}
1411