1193323Sed//===-- MSP430ISelLowering.cpp - MSP430 DAG Lowering Implementation  ------===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file implements the MSP430TargetLowering class.
11193323Sed//
12193323Sed//===----------------------------------------------------------------------===//
13193323Sed
14193323Sed#define DEBUG_TYPE "msp430-lower"
15193323Sed
16193323Sed#include "MSP430ISelLowering.h"
17193323Sed#include "MSP430.h"
18200581Srdivacky#include "MSP430MachineFunctionInfo.h"
19249423Sdim#include "MSP430Subtarget.h"
20193323Sed#include "MSP430TargetMachine.h"
21193323Sed#include "llvm/CodeGen/CallingConvLower.h"
22193323Sed#include "llvm/CodeGen/MachineFrameInfo.h"
23193323Sed#include "llvm/CodeGen/MachineFunction.h"
24193323Sed#include "llvm/CodeGen/MachineInstrBuilder.h"
25193323Sed#include "llvm/CodeGen/MachineRegisterInfo.h"
26193323Sed#include "llvm/CodeGen/SelectionDAGISel.h"
27203954Srdivacky#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
28193323Sed#include "llvm/CodeGen/ValueTypes.h"
29249423Sdim#include "llvm/IR/CallingConv.h"
30249423Sdim#include "llvm/IR/DerivedTypes.h"
31249423Sdim#include "llvm/IR/Function.h"
32249423Sdim#include "llvm/IR/GlobalAlias.h"
33249423Sdim#include "llvm/IR/GlobalVariable.h"
34249423Sdim#include "llvm/IR/Intrinsics.h"
35200581Srdivacky#include "llvm/Support/CommandLine.h"
36193323Sed#include "llvm/Support/Debug.h"
37198090Srdivacky#include "llvm/Support/ErrorHandling.h"
38198090Srdivacky#include "llvm/Support/raw_ostream.h"
39193323Sedusing namespace llvm;
40193323Sed
41200581Srdivackytypedef enum {
42200581Srdivacky  NoHWMult,
43200581Srdivacky  HWMultIntr,
44200581Srdivacky  HWMultNoIntr
45200581Srdivacky} HWMultUseMode;
46200581Srdivacky
47200581Srdivackystatic cl::opt<HWMultUseMode>
48263508SdimHWMultMode("msp430-hwmult-mode", cl::Hidden,
49200581Srdivacky           cl::desc("Hardware multiplier use mode"),
50200581Srdivacky           cl::init(HWMultNoIntr),
51200581Srdivacky           cl::values(
52200581Srdivacky             clEnumValN(NoHWMult, "no",
53200581Srdivacky                "Do not use hardware multiplier"),
54200581Srdivacky             clEnumValN(HWMultIntr, "interrupts",
55200581Srdivacky                "Assume hardware multiplier can be used inside interrupts"),
56200581Srdivacky             clEnumValN(HWMultNoIntr, "use",
57200581Srdivacky                "Assume hardware multiplier cannot be used inside interrupts"),
58200581Srdivacky             clEnumValEnd));
59200581Srdivacky
60193323SedMSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) :
61198090Srdivacky  TargetLowering(tm, new TargetLoweringObjectFileELF()),
62239462Sdim  Subtarget(*tm.getSubtargetImpl()) {
63193323Sed
64243830Sdim  TD = getDataLayout();
65200581Srdivacky
66193323Sed  // Set up the register classes.
67239462Sdim  addRegisterClass(MVT::i8,  &MSP430::GR8RegClass);
68239462Sdim  addRegisterClass(MVT::i16, &MSP430::GR16RegClass);
69193323Sed
70193323Sed  // Compute derived properties from the register classes
71193323Sed  computeRegisterProperties();
72193323Sed
73193323Sed  // Provide all sorts of operation actions
74193323Sed
75193323Sed  // Division is expensive
76193323Sed  setIntDivIsCheap(false);
77193323Sed
78193323Sed  setStackPointerRegisterToSaveRestore(MSP430::SPW);
79193323Sed  setBooleanContents(ZeroOrOneBooleanContent);
80226633Sdim  setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?
81193323Sed
82199481Srdivacky  // We have post-incremented loads / stores.
83199481Srdivacky  setIndexedLoadAction(ISD::POST_INC, MVT::i8, Legal);
84199481Srdivacky  setIndexedLoadAction(ISD::POST_INC, MVT::i16, Legal);
85199481Srdivacky
86199481Srdivacky  setLoadExtAction(ISD::EXTLOAD,  MVT::i1,  Promote);
87199481Srdivacky  setLoadExtAction(ISD::SEXTLOAD, MVT::i1,  Promote);
88199481Srdivacky  setLoadExtAction(ISD::ZEXTLOAD, MVT::i1,  Promote);
89199481Srdivacky  setLoadExtAction(ISD::SEXTLOAD, MVT::i8,  Expand);
90193323Sed  setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Expand);
91193323Sed
92193323Sed  // We don't have any truncstores
93193323Sed  setTruncStoreAction(MVT::i16, MVT::i8, Expand);
94193323Sed
95193323Sed  setOperationAction(ISD::SRA,              MVT::i8,    Custom);
96193323Sed  setOperationAction(ISD::SHL,              MVT::i8,    Custom);
97193323Sed  setOperationAction(ISD::SRL,              MVT::i8,    Custom);
98193323Sed  setOperationAction(ISD::SRA,              MVT::i16,   Custom);
99193323Sed  setOperationAction(ISD::SHL,              MVT::i16,   Custom);
100193323Sed  setOperationAction(ISD::SRL,              MVT::i16,   Custom);
101193323Sed  setOperationAction(ISD::ROTL,             MVT::i8,    Expand);
102193323Sed  setOperationAction(ISD::ROTR,             MVT::i8,    Expand);
103193323Sed  setOperationAction(ISD::ROTL,             MVT::i16,   Expand);
104193323Sed  setOperationAction(ISD::ROTR,             MVT::i16,   Expand);
105193323Sed  setOperationAction(ISD::GlobalAddress,    MVT::i16,   Custom);
106193323Sed  setOperationAction(ISD::ExternalSymbol,   MVT::i16,   Custom);
107207618Srdivacky  setOperationAction(ISD::BlockAddress,     MVT::i16,   Custom);
108193323Sed  setOperationAction(ISD::BR_JT,            MVT::Other, Expand);
109193323Sed  setOperationAction(ISD::BR_CC,            MVT::i8,    Custom);
110193323Sed  setOperationAction(ISD::BR_CC,            MVT::i16,   Custom);
111193323Sed  setOperationAction(ISD::BRCOND,           MVT::Other, Expand);
112200581Srdivacky  setOperationAction(ISD::SETCC,            MVT::i8,    Custom);
113200581Srdivacky  setOperationAction(ISD::SETCC,            MVT::i16,   Custom);
114193323Sed  setOperationAction(ISD::SELECT,           MVT::i8,    Expand);
115193323Sed  setOperationAction(ISD::SELECT,           MVT::i16,   Expand);
116193323Sed  setOperationAction(ISD::SELECT_CC,        MVT::i8,    Custom);
117193323Sed  setOperationAction(ISD::SELECT_CC,        MVT::i16,   Custom);
118193323Sed  setOperationAction(ISD::SIGN_EXTEND,      MVT::i16,   Custom);
119198090Srdivacky  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i8, Expand);
120198090Srdivacky  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i16, Expand);
121193323Sed
122198090Srdivacky  setOperationAction(ISD::CTTZ,             MVT::i8,    Expand);
123198090Srdivacky  setOperationAction(ISD::CTTZ,             MVT::i16,   Expand);
124234353Sdim  setOperationAction(ISD::CTTZ_ZERO_UNDEF,  MVT::i8,    Expand);
125234353Sdim  setOperationAction(ISD::CTTZ_ZERO_UNDEF,  MVT::i16,   Expand);
126198090Srdivacky  setOperationAction(ISD::CTLZ,             MVT::i8,    Expand);
127198090Srdivacky  setOperationAction(ISD::CTLZ,             MVT::i16,   Expand);
128234353Sdim  setOperationAction(ISD::CTLZ_ZERO_UNDEF,  MVT::i8,    Expand);
129234353Sdim  setOperationAction(ISD::CTLZ_ZERO_UNDEF,  MVT::i16,   Expand);
130198090Srdivacky  setOperationAction(ISD::CTPOP,            MVT::i8,    Expand);
131198090Srdivacky  setOperationAction(ISD::CTPOP,            MVT::i16,   Expand);
132198090Srdivacky
133198090Srdivacky  setOperationAction(ISD::SHL_PARTS,        MVT::i8,    Expand);
134198090Srdivacky  setOperationAction(ISD::SHL_PARTS,        MVT::i16,   Expand);
135198090Srdivacky  setOperationAction(ISD::SRL_PARTS,        MVT::i8,    Expand);
136198090Srdivacky  setOperationAction(ISD::SRL_PARTS,        MVT::i16,   Expand);
137198090Srdivacky  setOperationAction(ISD::SRA_PARTS,        MVT::i8,    Expand);
138198090Srdivacky  setOperationAction(ISD::SRA_PARTS,        MVT::i16,   Expand);
139198090Srdivacky
140198090Srdivacky  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1,   Expand);
141198090Srdivacky
142193323Sed  // FIXME: Implement efficiently multiplication by a constant
143199481Srdivacky  setOperationAction(ISD::MUL,              MVT::i8,    Expand);
144199481Srdivacky  setOperationAction(ISD::MULHS,            MVT::i8,    Expand);
145199481Srdivacky  setOperationAction(ISD::MULHU,            MVT::i8,    Expand);
146199481Srdivacky  setOperationAction(ISD::SMUL_LOHI,        MVT::i8,    Expand);
147199481Srdivacky  setOperationAction(ISD::UMUL_LOHI,        MVT::i8,    Expand);
148193323Sed  setOperationAction(ISD::MUL,              MVT::i16,   Expand);
149193323Sed  setOperationAction(ISD::MULHS,            MVT::i16,   Expand);
150193323Sed  setOperationAction(ISD::MULHU,            MVT::i16,   Expand);
151193323Sed  setOperationAction(ISD::SMUL_LOHI,        MVT::i16,   Expand);
152193323Sed  setOperationAction(ISD::UMUL_LOHI,        MVT::i16,   Expand);
153193323Sed
154199481Srdivacky  setOperationAction(ISD::UDIV,             MVT::i8,    Expand);
155199481Srdivacky  setOperationAction(ISD::UDIVREM,          MVT::i8,    Expand);
156199481Srdivacky  setOperationAction(ISD::UREM,             MVT::i8,    Expand);
157199481Srdivacky  setOperationAction(ISD::SDIV,             MVT::i8,    Expand);
158199481Srdivacky  setOperationAction(ISD::SDIVREM,          MVT::i8,    Expand);
159199481Srdivacky  setOperationAction(ISD::SREM,             MVT::i8,    Expand);
160193323Sed  setOperationAction(ISD::UDIV,             MVT::i16,   Expand);
161193323Sed  setOperationAction(ISD::UDIVREM,          MVT::i16,   Expand);
162193323Sed  setOperationAction(ISD::UREM,             MVT::i16,   Expand);
163193323Sed  setOperationAction(ISD::SDIV,             MVT::i16,   Expand);
164193323Sed  setOperationAction(ISD::SDIVREM,          MVT::i16,   Expand);
165193323Sed  setOperationAction(ISD::SREM,             MVT::i16,   Expand);
166200581Srdivacky
167249423Sdim  // varargs support
168249423Sdim  setOperationAction(ISD::VASTART,          MVT::Other, Custom);
169249423Sdim  setOperationAction(ISD::VAARG,            MVT::Other, Expand);
170249423Sdim  setOperationAction(ISD::VAEND,            MVT::Other, Expand);
171249423Sdim  setOperationAction(ISD::VACOPY,           MVT::Other, Expand);
172263508Sdim  setOperationAction(ISD::JumpTable,        MVT::i16,   Custom);
173249423Sdim
174200581Srdivacky  // Libcalls names.
175200581Srdivacky  if (HWMultMode == HWMultIntr) {
176200581Srdivacky    setLibcallName(RTLIB::MUL_I8,  "__mulqi3hw");
177200581Srdivacky    setLibcallName(RTLIB::MUL_I16, "__mulhi3hw");
178200581Srdivacky  } else if (HWMultMode == HWMultNoIntr) {
179200581Srdivacky    setLibcallName(RTLIB::MUL_I8,  "__mulqi3hw_noint");
180200581Srdivacky    setLibcallName(RTLIB::MUL_I16, "__mulhi3hw_noint");
181200581Srdivacky  }
182223017Sdim
183223017Sdim  setMinFunctionAlignment(1);
184223017Sdim  setPrefFunctionAlignment(2);
185193323Sed}
186193323Sed
187207618SrdivackySDValue MSP430TargetLowering::LowerOperation(SDValue Op,
188207618Srdivacky                                             SelectionDAG &DAG) const {
189193323Sed  switch (Op.getOpcode()) {
190193323Sed  case ISD::SHL: // FALLTHROUGH
191193323Sed  case ISD::SRL:
192193323Sed  case ISD::SRA:              return LowerShifts(Op, DAG);
193193323Sed  case ISD::GlobalAddress:    return LowerGlobalAddress(Op, DAG);
194207618Srdivacky  case ISD::BlockAddress:     return LowerBlockAddress(Op, DAG);
195193323Sed  case ISD::ExternalSymbol:   return LowerExternalSymbol(Op, DAG);
196200581Srdivacky  case ISD::SETCC:            return LowerSETCC(Op, DAG);
197193323Sed  case ISD::BR_CC:            return LowerBR_CC(Op, DAG);
198193323Sed  case ISD::SELECT_CC:        return LowerSELECT_CC(Op, DAG);
199193323Sed  case ISD::SIGN_EXTEND:      return LowerSIGN_EXTEND(Op, DAG);
200200581Srdivacky  case ISD::RETURNADDR:       return LowerRETURNADDR(Op, DAG);
201200581Srdivacky  case ISD::FRAMEADDR:        return LowerFRAMEADDR(Op, DAG);
202249423Sdim  case ISD::VASTART:          return LowerVASTART(Op, DAG);
203263508Sdim  case ISD::JumpTable:        return LowerJumpTable(Op, DAG);
204193323Sed  default:
205198090Srdivacky    llvm_unreachable("unimplemented operand");
206193323Sed  }
207193323Sed}
208193323Sed
209193323Sed//===----------------------------------------------------------------------===//
210198090Srdivacky//                       MSP430 Inline Assembly Support
211198090Srdivacky//===----------------------------------------------------------------------===//
212198090Srdivacky
213198090Srdivacky/// getConstraintType - Given a constraint letter, return the type of
214198090Srdivacky/// constraint it is for this target.
215198090SrdivackyTargetLowering::ConstraintType
216198090SrdivackyMSP430TargetLowering::getConstraintType(const std::string &Constraint) const {
217198090Srdivacky  if (Constraint.size() == 1) {
218198090Srdivacky    switch (Constraint[0]) {
219198090Srdivacky    case 'r':
220198090Srdivacky      return C_RegisterClass;
221198090Srdivacky    default:
222198090Srdivacky      break;
223198090Srdivacky    }
224198090Srdivacky  }
225198090Srdivacky  return TargetLowering::getConstraintType(Constraint);
226198090Srdivacky}
227198090Srdivacky
228198090Srdivackystd::pair<unsigned, const TargetRegisterClass*>
229198090SrdivackyMSP430TargetLowering::
230198090SrdivackygetRegForInlineAsmConstraint(const std::string &Constraint,
231263508Sdim                             MVT VT) const {
232198090Srdivacky  if (Constraint.size() == 1) {
233198090Srdivacky    // GCC Constraint Letters
234198090Srdivacky    switch (Constraint[0]) {
235198090Srdivacky    default: break;
236198090Srdivacky    case 'r':   // GENERAL_REGS
237198090Srdivacky      if (VT == MVT::i8)
238239462Sdim        return std::make_pair(0U, &MSP430::GR8RegClass);
239198090Srdivacky
240239462Sdim      return std::make_pair(0U, &MSP430::GR16RegClass);
241198090Srdivacky    }
242198090Srdivacky  }
243198090Srdivacky
244198090Srdivacky  return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
245198090Srdivacky}
246198090Srdivacky
247198090Srdivacky//===----------------------------------------------------------------------===//
248193323Sed//                      Calling Convention Implementation
249193323Sed//===----------------------------------------------------------------------===//
250193323Sed
251193323Sed#include "MSP430GenCallingConv.inc"
252193323Sed
253263508Sdim/// For each argument in a function store the number of pieces it is composed
254263508Sdim/// of.
255263508Sdimtemplate<typename ArgT>
256263508Sdimstatic void ParseFunctionArgs(const SmallVectorImpl<ArgT> &Args,
257263508Sdim                              SmallVectorImpl<unsigned> &Out) {
258263508Sdim  unsigned CurrentArgIndex = ~0U;
259263508Sdim  for (unsigned i = 0, e = Args.size(); i != e; i++) {
260263508Sdim    if (CurrentArgIndex == Args[i].OrigArgIndex) {
261263508Sdim      Out.back()++;
262263508Sdim    } else {
263263508Sdim      Out.push_back(1);
264263508Sdim      CurrentArgIndex++;
265263508Sdim    }
266263508Sdim  }
267263508Sdim}
268263508Sdim
269263508Sdimstatic void AnalyzeVarArgs(CCState &State,
270263508Sdim                           const SmallVectorImpl<ISD::OutputArg> &Outs) {
271263508Sdim  State.AnalyzeCallOperands(Outs, CC_MSP430_AssignStack);
272263508Sdim}
273263508Sdim
274263508Sdimstatic void AnalyzeVarArgs(CCState &State,
275263508Sdim                           const SmallVectorImpl<ISD::InputArg> &Ins) {
276263508Sdim  State.AnalyzeFormalArguments(Ins, CC_MSP430_AssignStack);
277263508Sdim}
278263508Sdim
279263508Sdim/// Analyze incoming and outgoing function arguments. We need custom C++ code
280263508Sdim/// to handle special constraints in the ABI like reversing the order of the
281263508Sdim/// pieces of splitted arguments. In addition, all pieces of a certain argument
282263508Sdim/// have to be passed either using registers or the stack but never mixing both.
283263508Sdimtemplate<typename ArgT>
284263508Sdimstatic void AnalyzeArguments(CCState &State,
285263508Sdim                             SmallVectorImpl<CCValAssign> &ArgLocs,
286263508Sdim                             const SmallVectorImpl<ArgT> &Args) {
287263508Sdim  static const uint16_t RegList[] = {
288263508Sdim    MSP430::R15W, MSP430::R14W, MSP430::R13W, MSP430::R12W
289263508Sdim  };
290263508Sdim  static const unsigned NbRegs = array_lengthof(RegList);
291263508Sdim
292263508Sdim  if (State.isVarArg()) {
293263508Sdim    AnalyzeVarArgs(State, Args);
294263508Sdim    return;
295263508Sdim  }
296263508Sdim
297263508Sdim  SmallVector<unsigned, 4> ArgsParts;
298263508Sdim  ParseFunctionArgs(Args, ArgsParts);
299263508Sdim
300263508Sdim  unsigned RegsLeft = NbRegs;
301263508Sdim  bool UseStack = false;
302263508Sdim  unsigned ValNo = 0;
303263508Sdim
304263508Sdim  for (unsigned i = 0, e = ArgsParts.size(); i != e; i++) {
305263508Sdim    MVT ArgVT = Args[ValNo].VT;
306263508Sdim    ISD::ArgFlagsTy ArgFlags = Args[ValNo].Flags;
307263508Sdim    MVT LocVT = ArgVT;
308263508Sdim    CCValAssign::LocInfo LocInfo = CCValAssign::Full;
309263508Sdim
310263508Sdim    // Promote i8 to i16
311263508Sdim    if (LocVT == MVT::i8) {
312263508Sdim      LocVT = MVT::i16;
313263508Sdim      if (ArgFlags.isSExt())
314263508Sdim          LocInfo = CCValAssign::SExt;
315263508Sdim      else if (ArgFlags.isZExt())
316263508Sdim          LocInfo = CCValAssign::ZExt;
317263508Sdim      else
318263508Sdim          LocInfo = CCValAssign::AExt;
319263508Sdim    }
320263508Sdim
321263508Sdim    // Handle byval arguments
322263508Sdim    if (ArgFlags.isByVal()) {
323263508Sdim      State.HandleByVal(ValNo++, ArgVT, LocVT, LocInfo, 2, 2, ArgFlags);
324263508Sdim      continue;
325263508Sdim    }
326263508Sdim
327263508Sdim    unsigned Parts = ArgsParts[i];
328263508Sdim
329263508Sdim    if (!UseStack && Parts <= RegsLeft) {
330263508Sdim      unsigned FirstVal = ValNo;
331263508Sdim      for (unsigned j = 0; j < Parts; j++) {
332263508Sdim        unsigned Reg = State.AllocateReg(RegList, NbRegs);
333263508Sdim        State.addLoc(CCValAssign::getReg(ValNo++, ArgVT, Reg, LocVT, LocInfo));
334263508Sdim        RegsLeft--;
335263508Sdim      }
336263508Sdim
337263508Sdim      // Reverse the order of the pieces to agree with the "big endian" format
338263508Sdim      // required in the calling convention ABI.
339263508Sdim      SmallVectorImpl<CCValAssign>::iterator B = ArgLocs.begin() + FirstVal;
340263508Sdim      std::reverse(B, B + Parts);
341263508Sdim    } else {
342263508Sdim      UseStack = true;
343263508Sdim      for (unsigned j = 0; j < Parts; j++)
344263508Sdim        CC_MSP430_AssignStack(ValNo++, ArgVT, LocVT, LocInfo, ArgFlags, State);
345263508Sdim    }
346263508Sdim  }
347263508Sdim}
348263508Sdim
349263508Sdimstatic void AnalyzeRetResult(CCState &State,
350263508Sdim                             const SmallVectorImpl<ISD::InputArg> &Ins) {
351263508Sdim  State.AnalyzeCallResult(Ins, RetCC_MSP430);
352263508Sdim}
353263508Sdim
354263508Sdimstatic void AnalyzeRetResult(CCState &State,
355263508Sdim                             const SmallVectorImpl<ISD::OutputArg> &Outs) {
356263508Sdim  State.AnalyzeReturn(Outs, RetCC_MSP430);
357263508Sdim}
358263508Sdim
359263508Sdimtemplate<typename ArgT>
360263508Sdimstatic void AnalyzeReturnValues(CCState &State,
361263508Sdim                                SmallVectorImpl<CCValAssign> &RVLocs,
362263508Sdim                                const SmallVectorImpl<ArgT> &Args) {
363263508Sdim  AnalyzeRetResult(State, Args);
364263508Sdim
365263508Sdim  // Reverse splitted return values to get the "big endian" format required
366263508Sdim  // to agree with the calling convention ABI.
367263508Sdim  std::reverse(RVLocs.begin(), RVLocs.end());
368263508Sdim}
369263508Sdim
370198090SrdivackySDValue
371198090SrdivackyMSP430TargetLowering::LowerFormalArguments(SDValue Chain,
372198090Srdivacky                                           CallingConv::ID CallConv,
373198090Srdivacky                                           bool isVarArg,
374198090Srdivacky                                           const SmallVectorImpl<ISD::InputArg>
375198090Srdivacky                                             &Ins,
376263508Sdim                                           SDLoc dl,
377198090Srdivacky                                           SelectionDAG &DAG,
378207618Srdivacky                                           SmallVectorImpl<SDValue> &InVals)
379207618Srdivacky                                             const {
380198090Srdivacky
381198090Srdivacky  switch (CallConv) {
382193323Sed  default:
383198090Srdivacky    llvm_unreachable("Unsupported calling convention");
384193323Sed  case CallingConv::C:
385193323Sed  case CallingConv::Fast:
386198090Srdivacky    return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals);
387200581Srdivacky  case CallingConv::MSP430_INTR:
388234353Sdim    if (Ins.empty())
389234353Sdim      return Chain;
390207618Srdivacky    report_fatal_error("ISRs cannot have arguments");
391193323Sed  }
392193323Sed}
393193323Sed
394198090SrdivackySDValue
395239462SdimMSP430TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
396207618Srdivacky                                SmallVectorImpl<SDValue> &InVals) const {
397239462Sdim  SelectionDAG &DAG                     = CLI.DAG;
398263508Sdim  SDLoc &dl                             = CLI.DL;
399263508Sdim  SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
400263508Sdim  SmallVectorImpl<SDValue> &OutVals     = CLI.OutVals;
401263508Sdim  SmallVectorImpl<ISD::InputArg> &Ins   = CLI.Ins;
402239462Sdim  SDValue Chain                         = CLI.Chain;
403239462Sdim  SDValue Callee                        = CLI.Callee;
404239462Sdim  bool &isTailCall                      = CLI.IsTailCall;
405239462Sdim  CallingConv::ID CallConv              = CLI.CallConv;
406239462Sdim  bool isVarArg                         = CLI.IsVarArg;
407239462Sdim
408203954Srdivacky  // MSP430 target does not yet support tail call optimization.
409203954Srdivacky  isTailCall = false;
410198090Srdivacky
411198090Srdivacky  switch (CallConv) {
412193323Sed  default:
413198090Srdivacky    llvm_unreachable("Unsupported calling convention");
414193323Sed  case CallingConv::Fast:
415193323Sed  case CallingConv::C:
416198090Srdivacky    return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
417210299Sed                          Outs, OutVals, Ins, dl, DAG, InVals);
418200581Srdivacky  case CallingConv::MSP430_INTR:
419207618Srdivacky    report_fatal_error("ISRs cannot be called directly");
420193323Sed  }
421193323Sed}
422193323Sed
423193323Sed/// LowerCCCArguments - transform physical registers into virtual registers and
424193323Sed/// generate load operations for arguments places on the stack.
425193323Sed// FIXME: struct return stuff
426198090SrdivackySDValue
427198090SrdivackyMSP430TargetLowering::LowerCCCArguments(SDValue Chain,
428198090Srdivacky                                        CallingConv::ID CallConv,
429198090Srdivacky                                        bool isVarArg,
430198090Srdivacky                                        const SmallVectorImpl<ISD::InputArg>
431198090Srdivacky                                          &Ins,
432263508Sdim                                        SDLoc dl,
433198090Srdivacky                                        SelectionDAG &DAG,
434207618Srdivacky                                        SmallVectorImpl<SDValue> &InVals)
435207618Srdivacky                                          const {
436193323Sed  MachineFunction &MF = DAG.getMachineFunction();
437193323Sed  MachineFrameInfo *MFI = MF.getFrameInfo();
438193323Sed  MachineRegisterInfo &RegInfo = MF.getRegInfo();
439249423Sdim  MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
440193323Sed
441193323Sed  // Assign locations to all of the incoming arguments.
442193323Sed  SmallVector<CCValAssign, 16> ArgLocs;
443223017Sdim  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
444239462Sdim                 getTargetMachine(), ArgLocs, *DAG.getContext());
445263508Sdim  AnalyzeArguments(CCInfo, ArgLocs, Ins);
446193323Sed
447249423Sdim  // Create frame index for the start of the first vararg value
448249423Sdim  if (isVarArg) {
449249423Sdim    unsigned Offset = CCInfo.getNextStackOffset();
450249423Sdim    FuncInfo->setVarArgsFrameIndex(MFI->CreateFixedObject(1, Offset, true));
451249423Sdim  }
452193323Sed
453193323Sed  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
454193323Sed    CCValAssign &VA = ArgLocs[i];
455193323Sed    if (VA.isRegLoc()) {
456193323Sed      // Arguments passed in registers
457198090Srdivacky      EVT RegVT = VA.getLocVT();
458198090Srdivacky      switch (RegVT.getSimpleVT().SimpleTy) {
459219077Sdim      default:
460198090Srdivacky        {
461198090Srdivacky#ifndef NDEBUG
462198090Srdivacky          errs() << "LowerFormalArguments Unhandled argument type: "
463198090Srdivacky               << RegVT.getSimpleVT().SimpleTy << "\n";
464198090Srdivacky#endif
465198090Srdivacky          llvm_unreachable(0);
466198090Srdivacky        }
467193323Sed      case MVT::i16:
468239462Sdim        unsigned VReg = RegInfo.createVirtualRegister(&MSP430::GR16RegClass);
469193323Sed        RegInfo.addLiveIn(VA.getLocReg(), VReg);
470198090Srdivacky        SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, RegVT);
471193323Sed
472193323Sed        // If this is an 8-bit value, it is really passed promoted to 16
473193323Sed        // bits. Insert an assert[sz]ext to capture this, then truncate to the
474193323Sed        // right size.
475193323Sed        if (VA.getLocInfo() == CCValAssign::SExt)
476193323Sed          ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue,
477193323Sed                                 DAG.getValueType(VA.getValVT()));
478193323Sed        else if (VA.getLocInfo() == CCValAssign::ZExt)
479193323Sed          ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue,
480193323Sed                                 DAG.getValueType(VA.getValVT()));
481193323Sed
482193323Sed        if (VA.getLocInfo() != CCValAssign::Full)
483193323Sed          ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
484193323Sed
485198090Srdivacky        InVals.push_back(ArgValue);
486193323Sed      }
487193323Sed    } else {
488193323Sed      // Sanity check
489193323Sed      assert(VA.isMemLoc());
490249423Sdim
491249423Sdim      SDValue InVal;
492249423Sdim      ISD::ArgFlagsTy Flags = Ins[i].Flags;
493249423Sdim
494249423Sdim      if (Flags.isByVal()) {
495249423Sdim        int FI = MFI->CreateFixedObject(Flags.getByValSize(),
496249423Sdim                                        VA.getLocMemOffset(), true);
497249423Sdim        InVal = DAG.getFrameIndex(FI, getPointerTy());
498249423Sdim      } else {
499249423Sdim        // Load the argument to a virtual register
500249423Sdim        unsigned ObjSize = VA.getLocVT().getSizeInBits()/8;
501249423Sdim        if (ObjSize > 2) {
502249423Sdim            errs() << "LowerFormalArguments Unhandled argument type: "
503249423Sdim                << EVT(VA.getLocVT()).getEVTString()
504249423Sdim                << "\n";
505249423Sdim        }
506249423Sdim        // Create the frame index object for this incoming parameter...
507249423Sdim        int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);
508249423Sdim
509249423Sdim        // Create the SelectionDAG nodes corresponding to a load
510249423Sdim        //from this parameter
511249423Sdim        SDValue FIN = DAG.getFrameIndex(FI, MVT::i16);
512249423Sdim        InVal = DAG.getLoad(VA.getLocVT(), dl, Chain, FIN,
513249423Sdim                            MachinePointerInfo::getFixedStack(FI),
514249423Sdim                            false, false, false, 0);
515193323Sed      }
516193323Sed
517249423Sdim      InVals.push_back(InVal);
518193323Sed    }
519193323Sed  }
520193323Sed
521198090Srdivacky  return Chain;
522193323Sed}
523193323Sed
524198090SrdivackySDValue
525198090SrdivackyMSP430TargetLowering::LowerReturn(SDValue Chain,
526198090Srdivacky                                  CallingConv::ID CallConv, bool isVarArg,
527198090Srdivacky                                  const SmallVectorImpl<ISD::OutputArg> &Outs,
528210299Sed                                  const SmallVectorImpl<SDValue> &OutVals,
529263508Sdim                                  SDLoc dl, SelectionDAG &DAG) const {
530198090Srdivacky
531193323Sed  // CCValAssign - represent the assignment of the return value to a location
532193323Sed  SmallVector<CCValAssign, 16> RVLocs;
533193323Sed
534200581Srdivacky  // ISRs cannot return any value.
535234353Sdim  if (CallConv == CallingConv::MSP430_INTR && !Outs.empty())
536207618Srdivacky    report_fatal_error("ISRs cannot return any value");
537200581Srdivacky
538193323Sed  // CCState - Info about the registers and stack slot.
539223017Sdim  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
540239462Sdim                 getTargetMachine(), RVLocs, *DAG.getContext());
541193323Sed
542198090Srdivacky  // Analize return values.
543263508Sdim  AnalyzeReturnValues(CCInfo, RVLocs, Outs);
544193323Sed
545193323Sed  SDValue Flag;
546249423Sdim  SmallVector<SDValue, 4> RetOps(1, Chain);
547193323Sed
548193323Sed  // Copy the result values into the output registers.
549193323Sed  for (unsigned i = 0; i != RVLocs.size(); ++i) {
550193323Sed    CCValAssign &VA = RVLocs[i];
551193323Sed    assert(VA.isRegLoc() && "Can only return in registers!");
552193323Sed
553193323Sed    Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
554210299Sed                             OutVals[i], Flag);
555193323Sed
556193323Sed    // Guarantee that all emitted copies are stuck together,
557193323Sed    // avoiding something bad.
558193323Sed    Flag = Chain.getValue(1);
559249423Sdim    RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
560193323Sed  }
561193323Sed
562200581Srdivacky  unsigned Opc = (CallConv == CallingConv::MSP430_INTR ?
563200581Srdivacky                  MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG);
564200581Srdivacky
565249423Sdim  RetOps[0] = Chain;  // Update chain.
566249423Sdim
567249423Sdim  // Add the flag if we have it.
568193323Sed  if (Flag.getNode())
569249423Sdim    RetOps.push_back(Flag);
570193323Sed
571249423Sdim  return DAG.getNode(Opc, dl, MVT::Other, &RetOps[0], RetOps.size());
572193323Sed}
573193323Sed
574193323Sed/// LowerCCCCallTo - functions arguments are copied from virtual regs to
575193323Sed/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
576263508Sdim// TODO: sret.
577198090SrdivackySDValue
578198090SrdivackyMSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee,
579198090Srdivacky                                     CallingConv::ID CallConv, bool isVarArg,
580198090Srdivacky                                     bool isTailCall,
581198090Srdivacky                                     const SmallVectorImpl<ISD::OutputArg>
582198090Srdivacky                                       &Outs,
583210299Sed                                     const SmallVectorImpl<SDValue> &OutVals,
584198090Srdivacky                                     const SmallVectorImpl<ISD::InputArg> &Ins,
585263508Sdim                                     SDLoc dl, SelectionDAG &DAG,
586207618Srdivacky                                     SmallVectorImpl<SDValue> &InVals) const {
587193323Sed  // Analyze operands of the call, assigning locations to each operand.
588193323Sed  SmallVector<CCValAssign, 16> ArgLocs;
589223017Sdim  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
590239462Sdim                 getTargetMachine(), ArgLocs, *DAG.getContext());
591263508Sdim  AnalyzeArguments(CCInfo, ArgLocs, Outs);
592193323Sed
593193323Sed  // Get a count of how many bytes are to be pushed on the stack.
594193323Sed  unsigned NumBytes = CCInfo.getNextStackOffset();
595193323Sed
596193323Sed  Chain = DAG.getCALLSEQ_START(Chain ,DAG.getConstant(NumBytes,
597263508Sdim                                                      getPointerTy(), true),
598263508Sdim                               dl);
599193323Sed
600193323Sed  SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass;
601193323Sed  SmallVector<SDValue, 12> MemOpChains;
602193323Sed  SDValue StackPtr;
603193323Sed
604193323Sed  // Walk the register/memloc assignments, inserting copies/loads.
605193323Sed  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
606193323Sed    CCValAssign &VA = ArgLocs[i];
607193323Sed
608210299Sed    SDValue Arg = OutVals[i];
609193323Sed
610193323Sed    // Promote the value if needed.
611193323Sed    switch (VA.getLocInfo()) {
612198090Srdivacky      default: llvm_unreachable("Unknown loc info!");
613193323Sed      case CCValAssign::Full: break;
614193323Sed      case CCValAssign::SExt:
615193323Sed        Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
616193323Sed        break;
617193323Sed      case CCValAssign::ZExt:
618193323Sed        Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
619193323Sed        break;
620193323Sed      case CCValAssign::AExt:
621193323Sed        Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
622193323Sed        break;
623193323Sed    }
624193323Sed
625193323Sed    // Arguments that can be passed on register must be kept at RegsToPass
626193323Sed    // vector
627193323Sed    if (VA.isRegLoc()) {
628193323Sed      RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
629193323Sed    } else {
630193323Sed      assert(VA.isMemLoc());
631193323Sed
632193323Sed      if (StackPtr.getNode() == 0)
633193323Sed        StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SPW, getPointerTy());
634193323Sed
635193323Sed      SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(),
636193323Sed                                   StackPtr,
637193323Sed                                   DAG.getIntPtrConstant(VA.getLocMemOffset()));
638193323Sed
639249423Sdim      SDValue MemOp;
640249423Sdim      ISD::ArgFlagsTy Flags = Outs[i].Flags;
641193323Sed
642249423Sdim      if (Flags.isByVal()) {
643249423Sdim        SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), MVT::i16);
644249423Sdim        MemOp = DAG.getMemcpy(Chain, dl, PtrOff, Arg, SizeNode,
645249423Sdim                              Flags.getByValAlign(),
646249423Sdim                              /*isVolatile*/false,
647249423Sdim                              /*AlwaysInline=*/true,
648249423Sdim                              MachinePointerInfo(),
649249423Sdim                              MachinePointerInfo());
650249423Sdim      } else {
651249423Sdim        MemOp = DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo(),
652249423Sdim                             false, false, 0);
653249423Sdim      }
654249423Sdim
655249423Sdim      MemOpChains.push_back(MemOp);
656193323Sed    }
657193323Sed  }
658193323Sed
659193323Sed  // Transform all store nodes into one single node because all store nodes are
660193323Sed  // independent of each other.
661193323Sed  if (!MemOpChains.empty())
662193323Sed    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
663193323Sed                        &MemOpChains[0], MemOpChains.size());
664193323Sed
665193323Sed  // Build a sequence of copy-to-reg nodes chained together with token chain and
666193323Sed  // flag operands which copy the outgoing args into registers.  The InFlag in
667221345Sdim  // necessary since all emitted instructions must be stuck together.
668193323Sed  SDValue InFlag;
669193323Sed  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
670193323Sed    Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
671193323Sed                             RegsToPass[i].second, InFlag);
672193323Sed    InFlag = Chain.getValue(1);
673193323Sed  }
674193323Sed
675193323Sed  // If the callee is a GlobalAddress node (quite common, every direct call is)
676193323Sed  // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
677193323Sed  // Likewise ExternalSymbol -> TargetExternalSymbol.
678193323Sed  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
679210299Sed    Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i16);
680193323Sed  else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
681193323Sed    Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i16);
682193323Sed
683193323Sed  // Returns a chain & a flag for retval copy to use.
684218893Sdim  SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
685193323Sed  SmallVector<SDValue, 8> Ops;
686193323Sed  Ops.push_back(Chain);
687193323Sed  Ops.push_back(Callee);
688193323Sed
689193323Sed  // Add argument registers to the end of the list so that they are
690193323Sed  // known live into the call.
691193323Sed  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
692193323Sed    Ops.push_back(DAG.getRegister(RegsToPass[i].first,
693193323Sed                                  RegsToPass[i].second.getValueType()));
694193323Sed
695193323Sed  if (InFlag.getNode())
696193323Sed    Ops.push_back(InFlag);
697193323Sed
698193323Sed  Chain = DAG.getNode(MSP430ISD::CALL, dl, NodeTys, &Ops[0], Ops.size());
699193323Sed  InFlag = Chain.getValue(1);
700193323Sed
701193323Sed  // Create the CALLSEQ_END node.
702193323Sed  Chain = DAG.getCALLSEQ_END(Chain,
703193323Sed                             DAG.getConstant(NumBytes, getPointerTy(), true),
704193323Sed                             DAG.getConstant(0, getPointerTy(), true),
705263508Sdim                             InFlag, dl);
706193323Sed  InFlag = Chain.getValue(1);
707193323Sed
708193323Sed  // Handle result values, copying them out of physregs into vregs that we
709193323Sed  // return.
710198090Srdivacky  return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl,
711198090Srdivacky                         DAG, InVals);
712193323Sed}
713193323Sed
714198090Srdivacky/// LowerCallResult - Lower the result values of a call into the
715198090Srdivacky/// appropriate copies out of appropriate physical registers.
716198090Srdivacky///
717198090SrdivackySDValue
718193323SedMSP430TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag,
719198090Srdivacky                                      CallingConv::ID CallConv, bool isVarArg,
720198090Srdivacky                                      const SmallVectorImpl<ISD::InputArg> &Ins,
721263508Sdim                                      SDLoc dl, SelectionDAG &DAG,
722207618Srdivacky                                      SmallVectorImpl<SDValue> &InVals) const {
723193323Sed
724193323Sed  // Assign locations to each value returned by this call.
725193323Sed  SmallVector<CCValAssign, 16> RVLocs;
726223017Sdim  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
727239462Sdim                 getTargetMachine(), RVLocs, *DAG.getContext());
728193323Sed
729263508Sdim  AnalyzeReturnValues(CCInfo, RVLocs, Ins);
730193323Sed
731193323Sed  // Copy all of the result registers out of their specified physreg.
732193323Sed  for (unsigned i = 0; i != RVLocs.size(); ++i) {
733193323Sed    Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(),
734193323Sed                               RVLocs[i].getValVT(), InFlag).getValue(1);
735193323Sed    InFlag = Chain.getValue(2);
736198090Srdivacky    InVals.push_back(Chain.getValue(0));
737193323Sed  }
738193323Sed
739198090Srdivacky  return Chain;
740193323Sed}
741193323Sed
742193323SedSDValue MSP430TargetLowering::LowerShifts(SDValue Op,
743207618Srdivacky                                          SelectionDAG &DAG) const {
744193323Sed  unsigned Opc = Op.getOpcode();
745193323Sed  SDNode* N = Op.getNode();
746198090Srdivacky  EVT VT = Op.getValueType();
747263508Sdim  SDLoc dl(N);
748193323Sed
749200581Srdivacky  // Expand non-constant shifts to loops:
750193323Sed  if (!isa<ConstantSDNode>(N->getOperand(1)))
751200581Srdivacky    switch (Opc) {
752234353Sdim    default: llvm_unreachable("Invalid shift opcode!");
753200581Srdivacky    case ISD::SHL:
754200581Srdivacky      return DAG.getNode(MSP430ISD::SHL, dl,
755200581Srdivacky                         VT, N->getOperand(0), N->getOperand(1));
756200581Srdivacky    case ISD::SRA:
757200581Srdivacky      return DAG.getNode(MSP430ISD::SRA, dl,
758200581Srdivacky                         VT, N->getOperand(0), N->getOperand(1));
759200581Srdivacky    case ISD::SRL:
760200581Srdivacky      return DAG.getNode(MSP430ISD::SRL, dl,
761200581Srdivacky                         VT, N->getOperand(0), N->getOperand(1));
762200581Srdivacky    }
763193323Sed
764193323Sed  uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
765193323Sed
766193323Sed  // Expand the stuff into sequence of shifts.
767193323Sed  // FIXME: for some shift amounts this might be done better!
768193323Sed  // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N
769193323Sed  SDValue Victim = N->getOperand(0);
770193323Sed
771193323Sed  if (Opc == ISD::SRL && ShiftAmount) {
772193323Sed    // Emit a special goodness here:
773193323Sed    // srl A, 1 => clrc; rrc A
774193323Sed    Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim);
775193323Sed    ShiftAmount -= 1;
776193323Sed  }
777193323Sed
778193323Sed  while (ShiftAmount--)
779193323Sed    Victim = DAG.getNode((Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA),
780193323Sed                         dl, VT, Victim);
781193323Sed
782193323Sed  return Victim;
783193323Sed}
784193323Sed
785207618SrdivackySDValue MSP430TargetLowering::LowerGlobalAddress(SDValue Op,
786207618Srdivacky                                                 SelectionDAG &DAG) const {
787193323Sed  const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
788193323Sed  int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();
789193323Sed
790193323Sed  // Create the TargetGlobalAddress node, folding in the constant offset.
791263508Sdim  SDValue Result = DAG.getTargetGlobalAddress(GV, SDLoc(Op),
792210299Sed                                              getPointerTy(), Offset);
793263508Sdim  return DAG.getNode(MSP430ISD::Wrapper, SDLoc(Op),
794193323Sed                     getPointerTy(), Result);
795193323Sed}
796193323Sed
797193323SedSDValue MSP430TargetLowering::LowerExternalSymbol(SDValue Op,
798207618Srdivacky                                                  SelectionDAG &DAG) const {
799263508Sdim  SDLoc dl(Op);
800193323Sed  const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol();
801193323Sed  SDValue Result = DAG.getTargetExternalSymbol(Sym, getPointerTy());
802193323Sed
803234353Sdim  return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result);
804193323Sed}
805193323Sed
806207618SrdivackySDValue MSP430TargetLowering::LowerBlockAddress(SDValue Op,
807207618Srdivacky                                                SelectionDAG &DAG) const {
808263508Sdim  SDLoc dl(Op);
809207618Srdivacky  const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
810243830Sdim  SDValue Result = DAG.getTargetBlockAddress(BA, getPointerTy());
811207618Srdivacky
812234353Sdim  return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result);
813207618Srdivacky}
814207618Srdivacky
815198396Srdivackystatic SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC,
816193323Sed                       ISD::CondCode CC,
817263508Sdim                       SDLoc dl, SelectionDAG &DAG) {
818193323Sed  // FIXME: Handle bittests someday
819193323Sed  assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet");
820193323Sed
821193323Sed  // FIXME: Handle jump negative someday
822198396Srdivacky  MSP430CC::CondCodes TCC = MSP430CC::COND_INVALID;
823193323Sed  switch (CC) {
824198090Srdivacky  default: llvm_unreachable("Invalid integer condition!");
825193323Sed  case ISD::SETEQ:
826198396Srdivacky    TCC = MSP430CC::COND_E;     // aka COND_Z
827202375Srdivacky    // Minor optimization: if LHS is a constant, swap operands, then the
828199989Srdivacky    // constant can be folded into comparison.
829202375Srdivacky    if (LHS.getOpcode() == ISD::Constant)
830199989Srdivacky      std::swap(LHS, RHS);
831193323Sed    break;
832193323Sed  case ISD::SETNE:
833198396Srdivacky    TCC = MSP430CC::COND_NE;    // aka COND_NZ
834202375Srdivacky    // Minor optimization: if LHS is a constant, swap operands, then the
835199989Srdivacky    // constant can be folded into comparison.
836202375Srdivacky    if (LHS.getOpcode() == ISD::Constant)
837199989Srdivacky      std::swap(LHS, RHS);
838193323Sed    break;
839193323Sed  case ISD::SETULE:
840193323Sed    std::swap(LHS, RHS);        // FALLTHROUGH
841193323Sed  case ISD::SETUGE:
842202878Srdivacky    // Turn lhs u>= rhs with lhs constant into rhs u< lhs+1, this allows us to
843202878Srdivacky    // fold constant into instruction.
844202878Srdivacky    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
845202878Srdivacky      LHS = RHS;
846202878Srdivacky      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
847202878Srdivacky      TCC = MSP430CC::COND_LO;
848202878Srdivacky      break;
849202878Srdivacky    }
850198396Srdivacky    TCC = MSP430CC::COND_HS;    // aka COND_C
851193323Sed    break;
852193323Sed  case ISD::SETUGT:
853193323Sed    std::swap(LHS, RHS);        // FALLTHROUGH
854193323Sed  case ISD::SETULT:
855202878Srdivacky    // Turn lhs u< rhs with lhs constant into rhs u>= lhs+1, this allows us to
856202878Srdivacky    // fold constant into instruction.
857202878Srdivacky    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
858202878Srdivacky      LHS = RHS;
859202878Srdivacky      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
860202878Srdivacky      TCC = MSP430CC::COND_HS;
861202878Srdivacky      break;
862202878Srdivacky    }
863198396Srdivacky    TCC = MSP430CC::COND_LO;    // aka COND_NC
864193323Sed    break;
865193323Sed  case ISD::SETLE:
866193323Sed    std::swap(LHS, RHS);        // FALLTHROUGH
867193323Sed  case ISD::SETGE:
868202878Srdivacky    // Turn lhs >= rhs with lhs constant into rhs < lhs+1, this allows us to
869202878Srdivacky    // fold constant into instruction.
870202878Srdivacky    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
871202878Srdivacky      LHS = RHS;
872202878Srdivacky      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
873202878Srdivacky      TCC = MSP430CC::COND_L;
874202878Srdivacky      break;
875202878Srdivacky    }
876198396Srdivacky    TCC = MSP430CC::COND_GE;
877193323Sed    break;
878193323Sed  case ISD::SETGT:
879193323Sed    std::swap(LHS, RHS);        // FALLTHROUGH
880193323Sed  case ISD::SETLT:
881202878Srdivacky    // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to
882202878Srdivacky    // fold constant into instruction.
883202878Srdivacky    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
884202878Srdivacky      LHS = RHS;
885202878Srdivacky      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
886202878Srdivacky      TCC = MSP430CC::COND_GE;
887202878Srdivacky      break;
888202878Srdivacky    }
889198396Srdivacky    TCC = MSP430CC::COND_L;
890193323Sed    break;
891193323Sed  }
892193323Sed
893198396Srdivacky  TargetCC = DAG.getConstant(TCC, MVT::i8);
894218893Sdim  return DAG.getNode(MSP430ISD::CMP, dl, MVT::Glue, LHS, RHS);
895193323Sed}
896193323Sed
897193323Sed
898207618SrdivackySDValue MSP430TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
899193323Sed  SDValue Chain = Op.getOperand(0);
900193323Sed  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
901193323Sed  SDValue LHS   = Op.getOperand(2);
902193323Sed  SDValue RHS   = Op.getOperand(3);
903193323Sed  SDValue Dest  = Op.getOperand(4);
904263508Sdim  SDLoc dl  (Op);
905193323Sed
906198396Srdivacky  SDValue TargetCC;
907193323Sed  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
908193323Sed
909193323Sed  return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(),
910198396Srdivacky                     Chain, Dest, TargetCC, Flag);
911193323Sed}
912193323Sed
913207618SrdivackySDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
914200581Srdivacky  SDValue LHS   = Op.getOperand(0);
915200581Srdivacky  SDValue RHS   = Op.getOperand(1);
916263508Sdim  SDLoc dl  (Op);
917200581Srdivacky
918200581Srdivacky  // If we are doing an AND and testing against zero, then the CMP
919200581Srdivacky  // will not be generated.  The AND (or BIT) will generate the condition codes,
920200581Srdivacky  // but they are different from CMP.
921202878Srdivacky  // FIXME: since we're doing a post-processing, use a pseudoinstr here, so
922202878Srdivacky  // lowering & isel wouldn't diverge.
923200581Srdivacky  bool andCC = false;
924200581Srdivacky  if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) {
925200581Srdivacky    if (RHSC->isNullValue() && LHS.hasOneUse() &&
926200581Srdivacky        (LHS.getOpcode() == ISD::AND ||
927200581Srdivacky         (LHS.getOpcode() == ISD::TRUNCATE &&
928200581Srdivacky          LHS.getOperand(0).getOpcode() == ISD::AND))) {
929200581Srdivacky      andCC = true;
930200581Srdivacky    }
931200581Srdivacky  }
932200581Srdivacky  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
933200581Srdivacky  SDValue TargetCC;
934200581Srdivacky  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
935200581Srdivacky
936200581Srdivacky  // Get the condition codes directly from the status register, if its easy.
937200581Srdivacky  // Otherwise a branch will be generated.  Note that the AND and BIT
938200581Srdivacky  // instructions generate different flags than CMP, the carry bit can be used
939200581Srdivacky  // for NE/EQ.
940200581Srdivacky  bool Invert = false;
941200581Srdivacky  bool Shift = false;
942200581Srdivacky  bool Convert = true;
943200581Srdivacky  switch (cast<ConstantSDNode>(TargetCC)->getZExtValue()) {
944200581Srdivacky   default:
945200581Srdivacky    Convert = false;
946200581Srdivacky    break;
947200581Srdivacky   case MSP430CC::COND_HS:
948200581Srdivacky     // Res = SRW & 1, no processing is required
949200581Srdivacky     break;
950202878Srdivacky   case MSP430CC::COND_LO:
951200581Srdivacky     // Res = ~(SRW & 1)
952200581Srdivacky     Invert = true;
953200581Srdivacky     break;
954202878Srdivacky   case MSP430CC::COND_NE:
955200581Srdivacky     if (andCC) {
956200581Srdivacky       // C = ~Z, thus Res = SRW & 1, no processing is required
957200581Srdivacky     } else {
958204642Srdivacky       // Res = ~((SRW >> 1) & 1)
959200581Srdivacky       Shift = true;
960204642Srdivacky       Invert = true;
961200581Srdivacky     }
962200581Srdivacky     break;
963202878Srdivacky   case MSP430CC::COND_E:
964204642Srdivacky     Shift = true;
965204642Srdivacky     // C = ~Z for AND instruction, thus we can put Res = ~(SRW & 1), however,
966204642Srdivacky     // Res = (SRW >> 1) & 1 is 1 word shorter.
967200581Srdivacky     break;
968200581Srdivacky  }
969200581Srdivacky  EVT VT = Op.getValueType();
970200581Srdivacky  SDValue One  = DAG.getConstant(1, VT);
971200581Srdivacky  if (Convert) {
972200581Srdivacky    SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SRW,
973202878Srdivacky                                    MVT::i16, Flag);
974200581Srdivacky    if (Shift)
975200581Srdivacky      // FIXME: somewhere this is turned into a SRL, lower it MSP specific?
976200581Srdivacky      SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One);
977200581Srdivacky    SR = DAG.getNode(ISD::AND, dl, MVT::i16, SR, One);
978200581Srdivacky    if (Invert)
979200581Srdivacky      SR = DAG.getNode(ISD::XOR, dl, MVT::i16, SR, One);
980200581Srdivacky    return SR;
981200581Srdivacky  } else {
982200581Srdivacky    SDValue Zero = DAG.getConstant(0, VT);
983218893Sdim    SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
984200581Srdivacky    SmallVector<SDValue, 4> Ops;
985200581Srdivacky    Ops.push_back(One);
986200581Srdivacky    Ops.push_back(Zero);
987200581Srdivacky    Ops.push_back(TargetCC);
988200581Srdivacky    Ops.push_back(Flag);
989200581Srdivacky    return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size());
990200581Srdivacky  }
991200581Srdivacky}
992200581Srdivacky
993207618SrdivackySDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op,
994207618Srdivacky                                             SelectionDAG &DAG) const {
995193323Sed  SDValue LHS    = Op.getOperand(0);
996193323Sed  SDValue RHS    = Op.getOperand(1);
997193323Sed  SDValue TrueV  = Op.getOperand(2);
998193323Sed  SDValue FalseV = Op.getOperand(3);
999193323Sed  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
1000263508Sdim  SDLoc dl   (Op);
1001193323Sed
1002198396Srdivacky  SDValue TargetCC;
1003193323Sed  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
1004193323Sed
1005218893Sdim  SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
1006193323Sed  SmallVector<SDValue, 4> Ops;
1007193323Sed  Ops.push_back(TrueV);
1008193323Sed  Ops.push_back(FalseV);
1009198396Srdivacky  Ops.push_back(TargetCC);
1010193323Sed  Ops.push_back(Flag);
1011193323Sed
1012193323Sed  return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size());
1013193323Sed}
1014193323Sed
1015193323SedSDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op,
1016207618Srdivacky                                               SelectionDAG &DAG) const {
1017193323Sed  SDValue Val = Op.getOperand(0);
1018198090Srdivacky  EVT VT      = Op.getValueType();
1019263508Sdim  SDLoc dl(Op);
1020193323Sed
1021193323Sed  assert(VT == MVT::i16 && "Only support i16 for now!");
1022193323Sed
1023193323Sed  return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT,
1024193323Sed                     DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val),
1025193323Sed                     DAG.getValueType(Val.getValueType()));
1026193323Sed}
1027193323Sed
1028207618SrdivackySDValue
1029207618SrdivackyMSP430TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) const {
1030200581Srdivacky  MachineFunction &MF = DAG.getMachineFunction();
1031200581Srdivacky  MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
1032200581Srdivacky  int ReturnAddrIndex = FuncInfo->getRAIndex();
1033200581Srdivacky
1034200581Srdivacky  if (ReturnAddrIndex == 0) {
1035200581Srdivacky    // Set up a frame object for the return address.
1036200581Srdivacky    uint64_t SlotSize = TD->getPointerSize();
1037200581Srdivacky    ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(SlotSize, -SlotSize,
1038210299Sed                                                           true);
1039200581Srdivacky    FuncInfo->setRAIndex(ReturnAddrIndex);
1040200581Srdivacky  }
1041200581Srdivacky
1042200581Srdivacky  return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy());
1043200581Srdivacky}
1044200581Srdivacky
1045207618SrdivackySDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op,
1046207618Srdivacky                                              SelectionDAG &DAG) const {
1047208599Srdivacky  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
1048208599Srdivacky  MFI->setReturnAddressIsTaken(true);
1049208599Srdivacky
1050200581Srdivacky  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
1051263508Sdim  SDLoc dl(Op);
1052200581Srdivacky
1053200581Srdivacky  if (Depth > 0) {
1054200581Srdivacky    SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
1055200581Srdivacky    SDValue Offset =
1056200581Srdivacky      DAG.getConstant(TD->getPointerSize(), MVT::i16);
1057200581Srdivacky    return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
1058200581Srdivacky                       DAG.getNode(ISD::ADD, dl, getPointerTy(),
1059200581Srdivacky                                   FrameAddr, Offset),
1060234353Sdim                       MachinePointerInfo(), false, false, false, 0);
1061200581Srdivacky  }
1062200581Srdivacky
1063200581Srdivacky  // Just load the return address.
1064200581Srdivacky  SDValue RetAddrFI = getReturnAddressFrameIndex(DAG);
1065200581Srdivacky  return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
1066234353Sdim                     RetAddrFI, MachinePointerInfo(), false, false, false, 0);
1067200581Srdivacky}
1068200581Srdivacky
1069207618SrdivackySDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op,
1070207618Srdivacky                                             SelectionDAG &DAG) const {
1071200581Srdivacky  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
1072200581Srdivacky  MFI->setFrameAddressIsTaken(true);
1073208599Srdivacky
1074200581Srdivacky  EVT VT = Op.getValueType();
1075263508Sdim  SDLoc dl(Op);  // FIXME probably not meaningful
1076200581Srdivacky  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
1077200581Srdivacky  SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl,
1078200581Srdivacky                                         MSP430::FPW, VT);
1079200581Srdivacky  while (Depth--)
1080218893Sdim    FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
1081218893Sdim                            MachinePointerInfo(),
1082234353Sdim                            false, false, false, 0);
1083200581Srdivacky  return FrameAddr;
1084200581Srdivacky}
1085200581Srdivacky
1086249423SdimSDValue MSP430TargetLowering::LowerVASTART(SDValue Op,
1087249423Sdim                                           SelectionDAG &DAG) const {
1088249423Sdim  MachineFunction &MF = DAG.getMachineFunction();
1089249423Sdim  MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
1090249423Sdim
1091249423Sdim  // Frame index of first vararg argument
1092249423Sdim  SDValue FrameIndex = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),
1093249423Sdim                                         getPointerTy());
1094249423Sdim  const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
1095249423Sdim
1096249423Sdim  // Create a store of the frame index to the location operand
1097263508Sdim  return DAG.getStore(Op.getOperand(0), SDLoc(Op), FrameIndex,
1098249423Sdim                      Op.getOperand(1), MachinePointerInfo(SV),
1099249423Sdim                      false, false, 0);
1100249423Sdim}
1101249423Sdim
1102263508SdimSDValue MSP430TargetLowering::LowerJumpTable(SDValue Op,
1103263508Sdim                                             SelectionDAG &DAG) const {
1104263508Sdim    JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
1105263508Sdim    SDValue Result = DAG.getTargetJumpTable(JT->getIndex(), getPointerTy());
1106263508Sdim    return DAG.getNode(MSP430ISD::Wrapper, SDLoc(JT),
1107263508Sdim                       getPointerTy(), Result);
1108263508Sdim}
1109263508Sdim
1110199481Srdivacky/// getPostIndexedAddressParts - returns true by value, base pointer and
1111199481Srdivacky/// offset pointer and addressing mode by reference if this node can be
1112199481Srdivacky/// combined with a load / store to form a post-indexed load / store.
1113199481Srdivackybool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
1114199481Srdivacky                                                      SDValue &Base,
1115199481Srdivacky                                                      SDValue &Offset,
1116199481Srdivacky                                                      ISD::MemIndexedMode &AM,
1117199481Srdivacky                                                      SelectionDAG &DAG) const {
1118199481Srdivacky
1119199481Srdivacky  LoadSDNode *LD = cast<LoadSDNode>(N);
1120199481Srdivacky  if (LD->getExtensionType() != ISD::NON_EXTLOAD)
1121199481Srdivacky    return false;
1122199481Srdivacky
1123199481Srdivacky  EVT VT = LD->getMemoryVT();
1124199481Srdivacky  if (VT != MVT::i8 && VT != MVT::i16)
1125199481Srdivacky    return false;
1126199481Srdivacky
1127199481Srdivacky  if (Op->getOpcode() != ISD::ADD)
1128199481Srdivacky    return false;
1129199481Srdivacky
1130199481Srdivacky  if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) {
1131199481Srdivacky    uint64_t RHSC = RHS->getZExtValue();
1132199481Srdivacky    if ((VT == MVT::i16 && RHSC != 2) ||
1133199481Srdivacky        (VT == MVT::i8 && RHSC != 1))
1134199481Srdivacky      return false;
1135199481Srdivacky
1136199481Srdivacky    Base = Op->getOperand(0);
1137199481Srdivacky    Offset = DAG.getConstant(RHSC, VT);
1138199481Srdivacky    AM = ISD::POST_INC;
1139199481Srdivacky    return true;
1140199481Srdivacky  }
1141199481Srdivacky
1142199481Srdivacky  return false;
1143199481Srdivacky}
1144199481Srdivacky
1145199481Srdivacky
1146193323Sedconst char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
1147193323Sed  switch (Opcode) {
1148193323Sed  default: return NULL;
1149193323Sed  case MSP430ISD::RET_FLAG:           return "MSP430ISD::RET_FLAG";
1150200581Srdivacky  case MSP430ISD::RETI_FLAG:          return "MSP430ISD::RETI_FLAG";
1151193323Sed  case MSP430ISD::RRA:                return "MSP430ISD::RRA";
1152193323Sed  case MSP430ISD::RLA:                return "MSP430ISD::RLA";
1153193323Sed  case MSP430ISD::RRC:                return "MSP430ISD::RRC";
1154193323Sed  case MSP430ISD::CALL:               return "MSP430ISD::CALL";
1155193323Sed  case MSP430ISD::Wrapper:            return "MSP430ISD::Wrapper";
1156193323Sed  case MSP430ISD::BR_CC:              return "MSP430ISD::BR_CC";
1157193323Sed  case MSP430ISD::CMP:                return "MSP430ISD::CMP";
1158193323Sed  case MSP430ISD::SELECT_CC:          return "MSP430ISD::SELECT_CC";
1159200581Srdivacky  case MSP430ISD::SHL:                return "MSP430ISD::SHL";
1160200581Srdivacky  case MSP430ISD::SRA:                return "MSP430ISD::SRA";
1161193323Sed  }
1162193323Sed}
1163193323Sed
1164226633Sdimbool MSP430TargetLowering::isTruncateFree(Type *Ty1,
1165226633Sdim                                          Type *Ty2) const {
1166203954Srdivacky  if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
1167202878Srdivacky    return false;
1168202878Srdivacky
1169202878Srdivacky  return (Ty1->getPrimitiveSizeInBits() > Ty2->getPrimitiveSizeInBits());
1170202878Srdivacky}
1171202878Srdivacky
1172202878Srdivackybool MSP430TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
1173202878Srdivacky  if (!VT1.isInteger() || !VT2.isInteger())
1174202878Srdivacky    return false;
1175202878Srdivacky
1176202878Srdivacky  return (VT1.getSizeInBits() > VT2.getSizeInBits());
1177202878Srdivacky}
1178202878Srdivacky
1179226633Sdimbool MSP430TargetLowering::isZExtFree(Type *Ty1, Type *Ty2) const {
1180202878Srdivacky  // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
1181203954Srdivacky  return 0 && Ty1->isIntegerTy(8) && Ty2->isIntegerTy(16);
1182202878Srdivacky}
1183202878Srdivacky
1184202878Srdivackybool MSP430TargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
1185202878Srdivacky  // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
1186202878Srdivacky  return 0 && VT1 == MVT::i8 && VT2 == MVT::i16;
1187202878Srdivacky}
1188202878Srdivacky
1189249423Sdimbool MSP430TargetLowering::isZExtFree(SDValue Val, EVT VT2) const {
1190249423Sdim  return isZExtFree(Val.getValueType(), VT2);
1191249423Sdim}
1192249423Sdim
1193193323Sed//===----------------------------------------------------------------------===//
1194193323Sed//  Other Lowering Code
1195193323Sed//===----------------------------------------------------------------------===//
1196193323Sed
1197193323SedMachineBasicBlock*
1198200581SrdivackyMSP430TargetLowering::EmitShiftInstr(MachineInstr *MI,
1199207618Srdivacky                                     MachineBasicBlock *BB) const {
1200200581Srdivacky  MachineFunction *F = BB->getParent();
1201200581Srdivacky  MachineRegisterInfo &RI = F->getRegInfo();
1202200581Srdivacky  DebugLoc dl = MI->getDebugLoc();
1203200581Srdivacky  const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
1204200581Srdivacky
1205200581Srdivacky  unsigned Opc;
1206200581Srdivacky  const TargetRegisterClass * RC;
1207200581Srdivacky  switch (MI->getOpcode()) {
1208234353Sdim  default: llvm_unreachable("Invalid shift opcode!");
1209200581Srdivacky  case MSP430::Shl8:
1210200581Srdivacky   Opc = MSP430::SHL8r1;
1211239462Sdim   RC = &MSP430::GR8RegClass;
1212200581Srdivacky   break;
1213200581Srdivacky  case MSP430::Shl16:
1214200581Srdivacky   Opc = MSP430::SHL16r1;
1215239462Sdim   RC = &MSP430::GR16RegClass;
1216200581Srdivacky   break;
1217200581Srdivacky  case MSP430::Sra8:
1218200581Srdivacky   Opc = MSP430::SAR8r1;
1219239462Sdim   RC = &MSP430::GR8RegClass;
1220200581Srdivacky   break;
1221200581Srdivacky  case MSP430::Sra16:
1222200581Srdivacky   Opc = MSP430::SAR16r1;
1223239462Sdim   RC = &MSP430::GR16RegClass;
1224200581Srdivacky   break;
1225200581Srdivacky  case MSP430::Srl8:
1226200581Srdivacky   Opc = MSP430::SAR8r1c;
1227239462Sdim   RC = &MSP430::GR8RegClass;
1228200581Srdivacky   break;
1229200581Srdivacky  case MSP430::Srl16:
1230200581Srdivacky   Opc = MSP430::SAR16r1c;
1231239462Sdim   RC = &MSP430::GR16RegClass;
1232200581Srdivacky   break;
1233200581Srdivacky  }
1234200581Srdivacky
1235200581Srdivacky  const BasicBlock *LLVM_BB = BB->getBasicBlock();
1236200581Srdivacky  MachineFunction::iterator I = BB;
1237200581Srdivacky  ++I;
1238200581Srdivacky
1239200581Srdivacky  // Create loop block
1240200581Srdivacky  MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB);
1241200581Srdivacky  MachineBasicBlock *RemBB  = F->CreateMachineBasicBlock(LLVM_BB);
1242200581Srdivacky
1243200581Srdivacky  F->insert(I, LoopBB);
1244200581Srdivacky  F->insert(I, RemBB);
1245200581Srdivacky
1246200581Srdivacky  // Update machine-CFG edges by transferring all successors of the current
1247200581Srdivacky  // block to the block containing instructions after shift.
1248210299Sed  RemBB->splice(RemBB->begin(), BB,
1249210299Sed                llvm::next(MachineBasicBlock::iterator(MI)),
1250210299Sed                BB->end());
1251210299Sed  RemBB->transferSuccessorsAndUpdatePHIs(BB);
1252200581Srdivacky
1253200581Srdivacky  // Add adges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB
1254200581Srdivacky  BB->addSuccessor(LoopBB);
1255200581Srdivacky  BB->addSuccessor(RemBB);
1256200581Srdivacky  LoopBB->addSuccessor(RemBB);
1257200581Srdivacky  LoopBB->addSuccessor(LoopBB);
1258200581Srdivacky
1259239462Sdim  unsigned ShiftAmtReg = RI.createVirtualRegister(&MSP430::GR8RegClass);
1260239462Sdim  unsigned ShiftAmtReg2 = RI.createVirtualRegister(&MSP430::GR8RegClass);
1261200581Srdivacky  unsigned ShiftReg = RI.createVirtualRegister(RC);
1262200581Srdivacky  unsigned ShiftReg2 = RI.createVirtualRegister(RC);
1263200581Srdivacky  unsigned ShiftAmtSrcReg = MI->getOperand(2).getReg();
1264200581Srdivacky  unsigned SrcReg = MI->getOperand(1).getReg();
1265200581Srdivacky  unsigned DstReg = MI->getOperand(0).getReg();
1266200581Srdivacky
1267200581Srdivacky  // BB:
1268200581Srdivacky  // cmp 0, N
1269200581Srdivacky  // je RemBB
1270202375Srdivacky  BuildMI(BB, dl, TII.get(MSP430::CMP8ri))
1271202375Srdivacky    .addReg(ShiftAmtSrcReg).addImm(0);
1272200581Srdivacky  BuildMI(BB, dl, TII.get(MSP430::JCC))
1273200581Srdivacky    .addMBB(RemBB)
1274200581Srdivacky    .addImm(MSP430CC::COND_E);
1275200581Srdivacky
1276200581Srdivacky  // LoopBB:
1277200581Srdivacky  // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB]
1278200581Srdivacky  // ShiftAmt = phi [%N, BB],      [%ShiftAmt2, LoopBB]
1279200581Srdivacky  // ShiftReg2 = shift ShiftReg
1280200581Srdivacky  // ShiftAmt2 = ShiftAmt - 1;
1281200581Srdivacky  BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftReg)
1282200581Srdivacky    .addReg(SrcReg).addMBB(BB)
1283200581Srdivacky    .addReg(ShiftReg2).addMBB(LoopBB);
1284200581Srdivacky  BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg)
1285200581Srdivacky    .addReg(ShiftAmtSrcReg).addMBB(BB)
1286200581Srdivacky    .addReg(ShiftAmtReg2).addMBB(LoopBB);
1287200581Srdivacky  BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2)
1288200581Srdivacky    .addReg(ShiftReg);
1289200581Srdivacky  BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2)
1290200581Srdivacky    .addReg(ShiftAmtReg).addImm(1);
1291200581Srdivacky  BuildMI(LoopBB, dl, TII.get(MSP430::JCC))
1292200581Srdivacky    .addMBB(LoopBB)
1293200581Srdivacky    .addImm(MSP430CC::COND_NE);
1294200581Srdivacky
1295200581Srdivacky  // RemBB:
1296200581Srdivacky  // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB]
1297210299Sed  BuildMI(*RemBB, RemBB->begin(), dl, TII.get(MSP430::PHI), DstReg)
1298200581Srdivacky    .addReg(SrcReg).addMBB(BB)
1299200581Srdivacky    .addReg(ShiftReg2).addMBB(LoopBB);
1300200581Srdivacky
1301210299Sed  MI->eraseFromParent();   // The pseudo instruction is gone now.
1302200581Srdivacky  return RemBB;
1303200581Srdivacky}
1304200581Srdivacky
1305200581SrdivackyMachineBasicBlock*
1306193323SedMSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
1307207618Srdivacky                                                  MachineBasicBlock *BB) const {
1308200581Srdivacky  unsigned Opc = MI->getOpcode();
1309200581Srdivacky
1310200581Srdivacky  if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 ||
1311200581Srdivacky      Opc == MSP430::Sra8 || Opc == MSP430::Sra16 ||
1312200581Srdivacky      Opc == MSP430::Srl8 || Opc == MSP430::Srl16)
1313207618Srdivacky    return EmitShiftInstr(MI, BB);
1314200581Srdivacky
1315193323Sed  const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
1316193323Sed  DebugLoc dl = MI->getDebugLoc();
1317200581Srdivacky
1318200581Srdivacky  assert((Opc == MSP430::Select16 || Opc == MSP430::Select8) &&
1319193323Sed         "Unexpected instr type to insert");
1320193323Sed
1321193323Sed  // To "insert" a SELECT instruction, we actually have to insert the diamond
1322193323Sed  // control-flow pattern.  The incoming instruction knows the destination vreg
1323193323Sed  // to set, the condition code register to branch on, the true/false values to
1324193323Sed  // select between, and a branch opcode to use.
1325193323Sed  const BasicBlock *LLVM_BB = BB->getBasicBlock();
1326193323Sed  MachineFunction::iterator I = BB;
1327193323Sed  ++I;
1328193323Sed
1329193323Sed  //  thisMBB:
1330193323Sed  //  ...
1331193323Sed  //   TrueVal = ...
1332193323Sed  //   cmpTY ccX, r1, r2
1333193323Sed  //   jCC copy1MBB
1334193323Sed  //   fallthrough --> copy0MBB
1335193323Sed  MachineBasicBlock *thisMBB = BB;
1336193323Sed  MachineFunction *F = BB->getParent();
1337193323Sed  MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
1338193323Sed  MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB);
1339193323Sed  F->insert(I, copy0MBB);
1340193323Sed  F->insert(I, copy1MBB);
1341193323Sed  // Update machine-CFG edges by transferring all successors of the current
1342193323Sed  // block to the new block which will contain the Phi node for the select.
1343210299Sed  copy1MBB->splice(copy1MBB->begin(), BB,
1344210299Sed                   llvm::next(MachineBasicBlock::iterator(MI)),
1345210299Sed                   BB->end());
1346210299Sed  copy1MBB->transferSuccessorsAndUpdatePHIs(BB);
1347193323Sed  // Next, add the true and fallthrough blocks as its successors.
1348193323Sed  BB->addSuccessor(copy0MBB);
1349193323Sed  BB->addSuccessor(copy1MBB);
1350193323Sed
1351210299Sed  BuildMI(BB, dl, TII.get(MSP430::JCC))
1352210299Sed    .addMBB(copy1MBB)
1353210299Sed    .addImm(MI->getOperand(3).getImm());
1354210299Sed
1355193323Sed  //  copy0MBB:
1356193323Sed  //   %FalseValue = ...
1357193323Sed  //   # fallthrough to copy1MBB
1358193323Sed  BB = copy0MBB;
1359193323Sed
1360193323Sed  // Update machine-CFG edges
1361193323Sed  BB->addSuccessor(copy1MBB);
1362193323Sed
1363193323Sed  //  copy1MBB:
1364193323Sed  //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
1365193323Sed  //  ...
1366193323Sed  BB = copy1MBB;
1367210299Sed  BuildMI(*BB, BB->begin(), dl, TII.get(MSP430::PHI),
1368193323Sed          MI->getOperand(0).getReg())
1369193323Sed    .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB)
1370193323Sed    .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB);
1371193323Sed
1372210299Sed  MI->eraseFromParent();   // The pseudo instruction is gone now.
1373193323Sed  return BB;
1374193323Sed}
1375