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>
48200581SrdivackyHWMultMode("msp430-hwmult-mode",
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);
172249423Sdim
173200581Srdivacky  // Libcalls names.
174200581Srdivacky  if (HWMultMode == HWMultIntr) {
175200581Srdivacky    setLibcallName(RTLIB::MUL_I8,  "__mulqi3hw");
176200581Srdivacky    setLibcallName(RTLIB::MUL_I16, "__mulhi3hw");
177200581Srdivacky  } else if (HWMultMode == HWMultNoIntr) {
178200581Srdivacky    setLibcallName(RTLIB::MUL_I8,  "__mulqi3hw_noint");
179200581Srdivacky    setLibcallName(RTLIB::MUL_I16, "__mulhi3hw_noint");
180200581Srdivacky  }
181223017Sdim
182223017Sdim  setMinFunctionAlignment(1);
183223017Sdim  setPrefFunctionAlignment(2);
184193323Sed}
185193323Sed
186207618SrdivackySDValue MSP430TargetLowering::LowerOperation(SDValue Op,
187207618Srdivacky                                             SelectionDAG &DAG) const {
188193323Sed  switch (Op.getOpcode()) {
189193323Sed  case ISD::SHL: // FALLTHROUGH
190193323Sed  case ISD::SRL:
191193323Sed  case ISD::SRA:              return LowerShifts(Op, DAG);
192193323Sed  case ISD::GlobalAddress:    return LowerGlobalAddress(Op, DAG);
193207618Srdivacky  case ISD::BlockAddress:     return LowerBlockAddress(Op, DAG);
194193323Sed  case ISD::ExternalSymbol:   return LowerExternalSymbol(Op, DAG);
195200581Srdivacky  case ISD::SETCC:            return LowerSETCC(Op, DAG);
196193323Sed  case ISD::BR_CC:            return LowerBR_CC(Op, DAG);
197193323Sed  case ISD::SELECT_CC:        return LowerSELECT_CC(Op, DAG);
198193323Sed  case ISD::SIGN_EXTEND:      return LowerSIGN_EXTEND(Op, DAG);
199200581Srdivacky  case ISD::RETURNADDR:       return LowerRETURNADDR(Op, DAG);
200200581Srdivacky  case ISD::FRAMEADDR:        return LowerFRAMEADDR(Op, DAG);
201249423Sdim  case ISD::VASTART:          return LowerVASTART(Op, DAG);
202193323Sed  default:
203198090Srdivacky    llvm_unreachable("unimplemented operand");
204193323Sed  }
205193323Sed}
206193323Sed
207193323Sed//===----------------------------------------------------------------------===//
208198090Srdivacky//                       MSP430 Inline Assembly Support
209198090Srdivacky//===----------------------------------------------------------------------===//
210198090Srdivacky
211198090Srdivacky/// getConstraintType - Given a constraint letter, return the type of
212198090Srdivacky/// constraint it is for this target.
213198090SrdivackyTargetLowering::ConstraintType
214198090SrdivackyMSP430TargetLowering::getConstraintType(const std::string &Constraint) const {
215198090Srdivacky  if (Constraint.size() == 1) {
216198090Srdivacky    switch (Constraint[0]) {
217198090Srdivacky    case 'r':
218198090Srdivacky      return C_RegisterClass;
219198090Srdivacky    default:
220198090Srdivacky      break;
221198090Srdivacky    }
222198090Srdivacky  }
223198090Srdivacky  return TargetLowering::getConstraintType(Constraint);
224198090Srdivacky}
225198090Srdivacky
226198090Srdivackystd::pair<unsigned, const TargetRegisterClass*>
227198090SrdivackyMSP430TargetLowering::
228198090SrdivackygetRegForInlineAsmConstraint(const std::string &Constraint,
229198090Srdivacky                             EVT VT) const {
230198090Srdivacky  if (Constraint.size() == 1) {
231198090Srdivacky    // GCC Constraint Letters
232198090Srdivacky    switch (Constraint[0]) {
233198090Srdivacky    default: break;
234198090Srdivacky    case 'r':   // GENERAL_REGS
235198090Srdivacky      if (VT == MVT::i8)
236239462Sdim        return std::make_pair(0U, &MSP430::GR8RegClass);
237198090Srdivacky
238239462Sdim      return std::make_pair(0U, &MSP430::GR16RegClass);
239198090Srdivacky    }
240198090Srdivacky  }
241198090Srdivacky
242198090Srdivacky  return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
243198090Srdivacky}
244198090Srdivacky
245198090Srdivacky//===----------------------------------------------------------------------===//
246193323Sed//                      Calling Convention Implementation
247193323Sed//===----------------------------------------------------------------------===//
248193323Sed
249193323Sed#include "MSP430GenCallingConv.inc"
250193323Sed
251198090SrdivackySDValue
252198090SrdivackyMSP430TargetLowering::LowerFormalArguments(SDValue Chain,
253198090Srdivacky                                           CallingConv::ID CallConv,
254198090Srdivacky                                           bool isVarArg,
255198090Srdivacky                                           const SmallVectorImpl<ISD::InputArg>
256198090Srdivacky                                             &Ins,
257198090Srdivacky                                           DebugLoc dl,
258198090Srdivacky                                           SelectionDAG &DAG,
259207618Srdivacky                                           SmallVectorImpl<SDValue> &InVals)
260207618Srdivacky                                             const {
261198090Srdivacky
262198090Srdivacky  switch (CallConv) {
263193323Sed  default:
264198090Srdivacky    llvm_unreachable("Unsupported calling convention");
265193323Sed  case CallingConv::C:
266193323Sed  case CallingConv::Fast:
267198090Srdivacky    return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals);
268200581Srdivacky  case CallingConv::MSP430_INTR:
269234353Sdim    if (Ins.empty())
270234353Sdim      return Chain;
271207618Srdivacky    report_fatal_error("ISRs cannot have arguments");
272193323Sed  }
273193323Sed}
274193323Sed
275198090SrdivackySDValue
276239462SdimMSP430TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
277207618Srdivacky                                SmallVectorImpl<SDValue> &InVals) const {
278239462Sdim  SelectionDAG &DAG                     = CLI.DAG;
279239462Sdim  DebugLoc &dl                          = CLI.DL;
280239462Sdim  SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs;
281239462Sdim  SmallVector<SDValue, 32> &OutVals     = CLI.OutVals;
282239462Sdim  SmallVector<ISD::InputArg, 32> &Ins   = CLI.Ins;
283239462Sdim  SDValue Chain                         = CLI.Chain;
284239462Sdim  SDValue Callee                        = CLI.Callee;
285239462Sdim  bool &isTailCall                      = CLI.IsTailCall;
286239462Sdim  CallingConv::ID CallConv              = CLI.CallConv;
287239462Sdim  bool isVarArg                         = CLI.IsVarArg;
288239462Sdim
289203954Srdivacky  // MSP430 target does not yet support tail call optimization.
290203954Srdivacky  isTailCall = false;
291198090Srdivacky
292198090Srdivacky  switch (CallConv) {
293193323Sed  default:
294198090Srdivacky    llvm_unreachable("Unsupported calling convention");
295193323Sed  case CallingConv::Fast:
296193323Sed  case CallingConv::C:
297198090Srdivacky    return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
298210299Sed                          Outs, OutVals, Ins, dl, DAG, InVals);
299200581Srdivacky  case CallingConv::MSP430_INTR:
300207618Srdivacky    report_fatal_error("ISRs cannot be called directly");
301193323Sed  }
302193323Sed}
303193323Sed
304193323Sed/// LowerCCCArguments - transform physical registers into virtual registers and
305193323Sed/// generate load operations for arguments places on the stack.
306193323Sed// FIXME: struct return stuff
307198090SrdivackySDValue
308198090SrdivackyMSP430TargetLowering::LowerCCCArguments(SDValue Chain,
309198090Srdivacky                                        CallingConv::ID CallConv,
310198090Srdivacky                                        bool isVarArg,
311198090Srdivacky                                        const SmallVectorImpl<ISD::InputArg>
312198090Srdivacky                                          &Ins,
313198090Srdivacky                                        DebugLoc dl,
314198090Srdivacky                                        SelectionDAG &DAG,
315207618Srdivacky                                        SmallVectorImpl<SDValue> &InVals)
316207618Srdivacky                                          const {
317193323Sed  MachineFunction &MF = DAG.getMachineFunction();
318193323Sed  MachineFrameInfo *MFI = MF.getFrameInfo();
319193323Sed  MachineRegisterInfo &RegInfo = MF.getRegInfo();
320249423Sdim  MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
321193323Sed
322193323Sed  // Assign locations to all of the incoming arguments.
323193323Sed  SmallVector<CCValAssign, 16> ArgLocs;
324223017Sdim  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
325239462Sdim                 getTargetMachine(), ArgLocs, *DAG.getContext());
326198090Srdivacky  CCInfo.AnalyzeFormalArguments(Ins, CC_MSP430);
327193323Sed
328249423Sdim  // Create frame index for the start of the first vararg value
329249423Sdim  if (isVarArg) {
330249423Sdim    unsigned Offset = CCInfo.getNextStackOffset();
331249423Sdim    FuncInfo->setVarArgsFrameIndex(MFI->CreateFixedObject(1, Offset, true));
332249423Sdim  }
333193323Sed
334193323Sed  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
335193323Sed    CCValAssign &VA = ArgLocs[i];
336193323Sed    if (VA.isRegLoc()) {
337193323Sed      // Arguments passed in registers
338198090Srdivacky      EVT RegVT = VA.getLocVT();
339198090Srdivacky      switch (RegVT.getSimpleVT().SimpleTy) {
340219077Sdim      default:
341198090Srdivacky        {
342198090Srdivacky#ifndef NDEBUG
343198090Srdivacky          errs() << "LowerFormalArguments Unhandled argument type: "
344198090Srdivacky               << RegVT.getSimpleVT().SimpleTy << "\n";
345198090Srdivacky#endif
346198090Srdivacky          llvm_unreachable(0);
347198090Srdivacky        }
348193323Sed      case MVT::i16:
349239462Sdim        unsigned VReg = RegInfo.createVirtualRegister(&MSP430::GR16RegClass);
350193323Sed        RegInfo.addLiveIn(VA.getLocReg(), VReg);
351198090Srdivacky        SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, RegVT);
352193323Sed
353193323Sed        // If this is an 8-bit value, it is really passed promoted to 16
354193323Sed        // bits. Insert an assert[sz]ext to capture this, then truncate to the
355193323Sed        // right size.
356193323Sed        if (VA.getLocInfo() == CCValAssign::SExt)
357193323Sed          ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue,
358193323Sed                                 DAG.getValueType(VA.getValVT()));
359193323Sed        else if (VA.getLocInfo() == CCValAssign::ZExt)
360193323Sed          ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue,
361193323Sed                                 DAG.getValueType(VA.getValVT()));
362193323Sed
363193323Sed        if (VA.getLocInfo() != CCValAssign::Full)
364193323Sed          ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
365193323Sed
366198090Srdivacky        InVals.push_back(ArgValue);
367193323Sed      }
368193323Sed    } else {
369193323Sed      // Sanity check
370193323Sed      assert(VA.isMemLoc());
371249423Sdim
372249423Sdim      SDValue InVal;
373249423Sdim      ISD::ArgFlagsTy Flags = Ins[i].Flags;
374249423Sdim
375249423Sdim      if (Flags.isByVal()) {
376249423Sdim        int FI = MFI->CreateFixedObject(Flags.getByValSize(),
377249423Sdim                                        VA.getLocMemOffset(), true);
378249423Sdim        InVal = DAG.getFrameIndex(FI, getPointerTy());
379249423Sdim      } else {
380249423Sdim        // Load the argument to a virtual register
381249423Sdim        unsigned ObjSize = VA.getLocVT().getSizeInBits()/8;
382249423Sdim        if (ObjSize > 2) {
383249423Sdim            errs() << "LowerFormalArguments Unhandled argument type: "
384249423Sdim                << EVT(VA.getLocVT()).getEVTString()
385249423Sdim                << "\n";
386249423Sdim        }
387249423Sdim        // Create the frame index object for this incoming parameter...
388249423Sdim        int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);
389249423Sdim
390249423Sdim        // Create the SelectionDAG nodes corresponding to a load
391249423Sdim        //from this parameter
392249423Sdim        SDValue FIN = DAG.getFrameIndex(FI, MVT::i16);
393249423Sdim        InVal = DAG.getLoad(VA.getLocVT(), dl, Chain, FIN,
394249423Sdim                            MachinePointerInfo::getFixedStack(FI),
395249423Sdim                            false, false, false, 0);
396193323Sed      }
397193323Sed
398249423Sdim      InVals.push_back(InVal);
399193323Sed    }
400193323Sed  }
401193323Sed
402198090Srdivacky  return Chain;
403193323Sed}
404193323Sed
405198090SrdivackySDValue
406198090SrdivackyMSP430TargetLowering::LowerReturn(SDValue Chain,
407198090Srdivacky                                  CallingConv::ID CallConv, bool isVarArg,
408198090Srdivacky                                  const SmallVectorImpl<ISD::OutputArg> &Outs,
409210299Sed                                  const SmallVectorImpl<SDValue> &OutVals,
410207618Srdivacky                                  DebugLoc dl, SelectionDAG &DAG) const {
411198090Srdivacky
412193323Sed  // CCValAssign - represent the assignment of the return value to a location
413193323Sed  SmallVector<CCValAssign, 16> RVLocs;
414193323Sed
415200581Srdivacky  // ISRs cannot return any value.
416234353Sdim  if (CallConv == CallingConv::MSP430_INTR && !Outs.empty())
417207618Srdivacky    report_fatal_error("ISRs cannot return any value");
418200581Srdivacky
419193323Sed  // CCState - Info about the registers and stack slot.
420223017Sdim  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
421239462Sdim                 getTargetMachine(), RVLocs, *DAG.getContext());
422193323Sed
423198090Srdivacky  // Analize return values.
424198090Srdivacky  CCInfo.AnalyzeReturn(Outs, RetCC_MSP430);
425193323Sed
426193323Sed  SDValue Flag;
427249423Sdim  SmallVector<SDValue, 4> RetOps(1, Chain);
428193323Sed
429193323Sed  // Copy the result values into the output registers.
430193323Sed  for (unsigned i = 0; i != RVLocs.size(); ++i) {
431193323Sed    CCValAssign &VA = RVLocs[i];
432193323Sed    assert(VA.isRegLoc() && "Can only return in registers!");
433193323Sed
434193323Sed    Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
435210299Sed                             OutVals[i], Flag);
436193323Sed
437193323Sed    // Guarantee that all emitted copies are stuck together,
438193323Sed    // avoiding something bad.
439193323Sed    Flag = Chain.getValue(1);
440249423Sdim    RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
441193323Sed  }
442193323Sed
443200581Srdivacky  unsigned Opc = (CallConv == CallingConv::MSP430_INTR ?
444200581Srdivacky                  MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG);
445200581Srdivacky
446249423Sdim  RetOps[0] = Chain;  // Update chain.
447249423Sdim
448249423Sdim  // Add the flag if we have it.
449193323Sed  if (Flag.getNode())
450249423Sdim    RetOps.push_back(Flag);
451193323Sed
452249423Sdim  return DAG.getNode(Opc, dl, MVT::Other, &RetOps[0], RetOps.size());
453193323Sed}
454193323Sed
455193323Sed/// LowerCCCCallTo - functions arguments are copied from virtual regs to
456193323Sed/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
457193323Sed/// TODO: sret.
458198090SrdivackySDValue
459198090SrdivackyMSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee,
460198090Srdivacky                                     CallingConv::ID CallConv, bool isVarArg,
461198090Srdivacky                                     bool isTailCall,
462198090Srdivacky                                     const SmallVectorImpl<ISD::OutputArg>
463198090Srdivacky                                       &Outs,
464210299Sed                                     const SmallVectorImpl<SDValue> &OutVals,
465198090Srdivacky                                     const SmallVectorImpl<ISD::InputArg> &Ins,
466198090Srdivacky                                     DebugLoc dl, SelectionDAG &DAG,
467207618Srdivacky                                     SmallVectorImpl<SDValue> &InVals) const {
468193323Sed  // Analyze operands of the call, assigning locations to each operand.
469193323Sed  SmallVector<CCValAssign, 16> ArgLocs;
470223017Sdim  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
471239462Sdim                 getTargetMachine(), ArgLocs, *DAG.getContext());
472193323Sed
473198090Srdivacky  CCInfo.AnalyzeCallOperands(Outs, CC_MSP430);
474193323Sed
475193323Sed  // Get a count of how many bytes are to be pushed on the stack.
476193323Sed  unsigned NumBytes = CCInfo.getNextStackOffset();
477193323Sed
478193323Sed  Chain = DAG.getCALLSEQ_START(Chain ,DAG.getConstant(NumBytes,
479193323Sed                                                      getPointerTy(), true));
480193323Sed
481193323Sed  SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass;
482193323Sed  SmallVector<SDValue, 12> MemOpChains;
483193323Sed  SDValue StackPtr;
484193323Sed
485193323Sed  // Walk the register/memloc assignments, inserting copies/loads.
486193323Sed  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
487193323Sed    CCValAssign &VA = ArgLocs[i];
488193323Sed
489210299Sed    SDValue Arg = OutVals[i];
490193323Sed
491193323Sed    // Promote the value if needed.
492193323Sed    switch (VA.getLocInfo()) {
493198090Srdivacky      default: llvm_unreachable("Unknown loc info!");
494193323Sed      case CCValAssign::Full: break;
495193323Sed      case CCValAssign::SExt:
496193323Sed        Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
497193323Sed        break;
498193323Sed      case CCValAssign::ZExt:
499193323Sed        Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
500193323Sed        break;
501193323Sed      case CCValAssign::AExt:
502193323Sed        Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
503193323Sed        break;
504193323Sed    }
505193323Sed
506193323Sed    // Arguments that can be passed on register must be kept at RegsToPass
507193323Sed    // vector
508193323Sed    if (VA.isRegLoc()) {
509193323Sed      RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
510193323Sed    } else {
511193323Sed      assert(VA.isMemLoc());
512193323Sed
513193323Sed      if (StackPtr.getNode() == 0)
514193323Sed        StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SPW, getPointerTy());
515193323Sed
516193323Sed      SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(),
517193323Sed                                   StackPtr,
518193323Sed                                   DAG.getIntPtrConstant(VA.getLocMemOffset()));
519193323Sed
520249423Sdim      SDValue MemOp;
521249423Sdim      ISD::ArgFlagsTy Flags = Outs[i].Flags;
522193323Sed
523249423Sdim      if (Flags.isByVal()) {
524249423Sdim        SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), MVT::i16);
525249423Sdim        MemOp = DAG.getMemcpy(Chain, dl, PtrOff, Arg, SizeNode,
526249423Sdim                              Flags.getByValAlign(),
527249423Sdim                              /*isVolatile*/false,
528249423Sdim                              /*AlwaysInline=*/true,
529249423Sdim                              MachinePointerInfo(),
530249423Sdim                              MachinePointerInfo());
531249423Sdim      } else {
532249423Sdim        MemOp = DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo(),
533249423Sdim                             false, false, 0);
534249423Sdim      }
535249423Sdim
536249423Sdim      MemOpChains.push_back(MemOp);
537193323Sed    }
538193323Sed  }
539193323Sed
540193323Sed  // Transform all store nodes into one single node because all store nodes are
541193323Sed  // independent of each other.
542193323Sed  if (!MemOpChains.empty())
543193323Sed    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
544193323Sed                        &MemOpChains[0], MemOpChains.size());
545193323Sed
546193323Sed  // Build a sequence of copy-to-reg nodes chained together with token chain and
547193323Sed  // flag operands which copy the outgoing args into registers.  The InFlag in
548221345Sdim  // necessary since all emitted instructions must be stuck together.
549193323Sed  SDValue InFlag;
550193323Sed  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
551193323Sed    Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
552193323Sed                             RegsToPass[i].second, InFlag);
553193323Sed    InFlag = Chain.getValue(1);
554193323Sed  }
555193323Sed
556193323Sed  // If the callee is a GlobalAddress node (quite common, every direct call is)
557193323Sed  // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
558193323Sed  // Likewise ExternalSymbol -> TargetExternalSymbol.
559193323Sed  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
560210299Sed    Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i16);
561193323Sed  else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
562193323Sed    Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i16);
563193323Sed
564193323Sed  // Returns a chain & a flag for retval copy to use.
565218893Sdim  SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
566193323Sed  SmallVector<SDValue, 8> Ops;
567193323Sed  Ops.push_back(Chain);
568193323Sed  Ops.push_back(Callee);
569193323Sed
570193323Sed  // Add argument registers to the end of the list so that they are
571193323Sed  // known live into the call.
572193323Sed  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
573193323Sed    Ops.push_back(DAG.getRegister(RegsToPass[i].first,
574193323Sed                                  RegsToPass[i].second.getValueType()));
575193323Sed
576193323Sed  if (InFlag.getNode())
577193323Sed    Ops.push_back(InFlag);
578193323Sed
579193323Sed  Chain = DAG.getNode(MSP430ISD::CALL, dl, NodeTys, &Ops[0], Ops.size());
580193323Sed  InFlag = Chain.getValue(1);
581193323Sed
582193323Sed  // Create the CALLSEQ_END node.
583193323Sed  Chain = DAG.getCALLSEQ_END(Chain,
584193323Sed                             DAG.getConstant(NumBytes, getPointerTy(), true),
585193323Sed                             DAG.getConstant(0, getPointerTy(), true),
586193323Sed                             InFlag);
587193323Sed  InFlag = Chain.getValue(1);
588193323Sed
589193323Sed  // Handle result values, copying them out of physregs into vregs that we
590193323Sed  // return.
591198090Srdivacky  return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl,
592198090Srdivacky                         DAG, InVals);
593193323Sed}
594193323Sed
595198090Srdivacky/// LowerCallResult - Lower the result values of a call into the
596198090Srdivacky/// appropriate copies out of appropriate physical registers.
597198090Srdivacky///
598198090SrdivackySDValue
599193323SedMSP430TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag,
600198090Srdivacky                                      CallingConv::ID CallConv, bool isVarArg,
601198090Srdivacky                                      const SmallVectorImpl<ISD::InputArg> &Ins,
602198090Srdivacky                                      DebugLoc dl, SelectionDAG &DAG,
603207618Srdivacky                                      SmallVectorImpl<SDValue> &InVals) const {
604193323Sed
605193323Sed  // Assign locations to each value returned by this call.
606193323Sed  SmallVector<CCValAssign, 16> RVLocs;
607223017Sdim  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
608239462Sdim                 getTargetMachine(), RVLocs, *DAG.getContext());
609193323Sed
610198090Srdivacky  CCInfo.AnalyzeCallResult(Ins, RetCC_MSP430);
611193323Sed
612193323Sed  // Copy all of the result registers out of their specified physreg.
613193323Sed  for (unsigned i = 0; i != RVLocs.size(); ++i) {
614193323Sed    Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(),
615193323Sed                               RVLocs[i].getValVT(), InFlag).getValue(1);
616193323Sed    InFlag = Chain.getValue(2);
617198090Srdivacky    InVals.push_back(Chain.getValue(0));
618193323Sed  }
619193323Sed
620198090Srdivacky  return Chain;
621193323Sed}
622193323Sed
623193323SedSDValue MSP430TargetLowering::LowerShifts(SDValue Op,
624207618Srdivacky                                          SelectionDAG &DAG) const {
625193323Sed  unsigned Opc = Op.getOpcode();
626193323Sed  SDNode* N = Op.getNode();
627198090Srdivacky  EVT VT = Op.getValueType();
628193323Sed  DebugLoc dl = N->getDebugLoc();
629193323Sed
630200581Srdivacky  // Expand non-constant shifts to loops:
631193323Sed  if (!isa<ConstantSDNode>(N->getOperand(1)))
632200581Srdivacky    switch (Opc) {
633234353Sdim    default: llvm_unreachable("Invalid shift opcode!");
634200581Srdivacky    case ISD::SHL:
635200581Srdivacky      return DAG.getNode(MSP430ISD::SHL, dl,
636200581Srdivacky                         VT, N->getOperand(0), N->getOperand(1));
637200581Srdivacky    case ISD::SRA:
638200581Srdivacky      return DAG.getNode(MSP430ISD::SRA, dl,
639200581Srdivacky                         VT, N->getOperand(0), N->getOperand(1));
640200581Srdivacky    case ISD::SRL:
641200581Srdivacky      return DAG.getNode(MSP430ISD::SRL, dl,
642200581Srdivacky                         VT, N->getOperand(0), N->getOperand(1));
643200581Srdivacky    }
644193323Sed
645193323Sed  uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
646193323Sed
647193323Sed  // Expand the stuff into sequence of shifts.
648193323Sed  // FIXME: for some shift amounts this might be done better!
649193323Sed  // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N
650193323Sed  SDValue Victim = N->getOperand(0);
651193323Sed
652193323Sed  if (Opc == ISD::SRL && ShiftAmount) {
653193323Sed    // Emit a special goodness here:
654193323Sed    // srl A, 1 => clrc; rrc A
655193323Sed    Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim);
656193323Sed    ShiftAmount -= 1;
657193323Sed  }
658193323Sed
659193323Sed  while (ShiftAmount--)
660193323Sed    Victim = DAG.getNode((Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA),
661193323Sed                         dl, VT, Victim);
662193323Sed
663193323Sed  return Victim;
664193323Sed}
665193323Sed
666207618SrdivackySDValue MSP430TargetLowering::LowerGlobalAddress(SDValue Op,
667207618Srdivacky                                                 SelectionDAG &DAG) const {
668193323Sed  const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
669193323Sed  int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();
670193323Sed
671193323Sed  // Create the TargetGlobalAddress node, folding in the constant offset.
672210299Sed  SDValue Result = DAG.getTargetGlobalAddress(GV, Op.getDebugLoc(),
673210299Sed                                              getPointerTy(), Offset);
674193323Sed  return DAG.getNode(MSP430ISD::Wrapper, Op.getDebugLoc(),
675193323Sed                     getPointerTy(), Result);
676193323Sed}
677193323Sed
678193323SedSDValue MSP430TargetLowering::LowerExternalSymbol(SDValue Op,
679207618Srdivacky                                                  SelectionDAG &DAG) const {
680193323Sed  DebugLoc dl = Op.getDebugLoc();
681193323Sed  const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol();
682193323Sed  SDValue Result = DAG.getTargetExternalSymbol(Sym, getPointerTy());
683193323Sed
684234353Sdim  return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result);
685193323Sed}
686193323Sed
687207618SrdivackySDValue MSP430TargetLowering::LowerBlockAddress(SDValue Op,
688207618Srdivacky                                                SelectionDAG &DAG) const {
689207618Srdivacky  DebugLoc dl = Op.getDebugLoc();
690207618Srdivacky  const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
691243830Sdim  SDValue Result = DAG.getTargetBlockAddress(BA, getPointerTy());
692207618Srdivacky
693234353Sdim  return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result);
694207618Srdivacky}
695207618Srdivacky
696198396Srdivackystatic SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC,
697193323Sed                       ISD::CondCode CC,
698193323Sed                       DebugLoc dl, SelectionDAG &DAG) {
699193323Sed  // FIXME: Handle bittests someday
700193323Sed  assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet");
701193323Sed
702193323Sed  // FIXME: Handle jump negative someday
703198396Srdivacky  MSP430CC::CondCodes TCC = MSP430CC::COND_INVALID;
704193323Sed  switch (CC) {
705198090Srdivacky  default: llvm_unreachable("Invalid integer condition!");
706193323Sed  case ISD::SETEQ:
707198396Srdivacky    TCC = MSP430CC::COND_E;     // aka COND_Z
708202375Srdivacky    // Minor optimization: if LHS is a constant, swap operands, then the
709199989Srdivacky    // constant can be folded into comparison.
710202375Srdivacky    if (LHS.getOpcode() == ISD::Constant)
711199989Srdivacky      std::swap(LHS, RHS);
712193323Sed    break;
713193323Sed  case ISD::SETNE:
714198396Srdivacky    TCC = MSP430CC::COND_NE;    // aka COND_NZ
715202375Srdivacky    // Minor optimization: if LHS is a constant, swap operands, then the
716199989Srdivacky    // constant can be folded into comparison.
717202375Srdivacky    if (LHS.getOpcode() == ISD::Constant)
718199989Srdivacky      std::swap(LHS, RHS);
719193323Sed    break;
720193323Sed  case ISD::SETULE:
721193323Sed    std::swap(LHS, RHS);        // FALLTHROUGH
722193323Sed  case ISD::SETUGE:
723202878Srdivacky    // Turn lhs u>= rhs with lhs constant into rhs u< lhs+1, this allows us to
724202878Srdivacky    // fold constant into instruction.
725202878Srdivacky    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
726202878Srdivacky      LHS = RHS;
727202878Srdivacky      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
728202878Srdivacky      TCC = MSP430CC::COND_LO;
729202878Srdivacky      break;
730202878Srdivacky    }
731198396Srdivacky    TCC = MSP430CC::COND_HS;    // aka COND_C
732193323Sed    break;
733193323Sed  case ISD::SETUGT:
734193323Sed    std::swap(LHS, RHS);        // FALLTHROUGH
735193323Sed  case ISD::SETULT:
736202878Srdivacky    // Turn lhs u< rhs with lhs constant into rhs u>= lhs+1, this allows us to
737202878Srdivacky    // fold constant into instruction.
738202878Srdivacky    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
739202878Srdivacky      LHS = RHS;
740202878Srdivacky      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
741202878Srdivacky      TCC = MSP430CC::COND_HS;
742202878Srdivacky      break;
743202878Srdivacky    }
744198396Srdivacky    TCC = MSP430CC::COND_LO;    // aka COND_NC
745193323Sed    break;
746193323Sed  case ISD::SETLE:
747193323Sed    std::swap(LHS, RHS);        // FALLTHROUGH
748193323Sed  case ISD::SETGE:
749202878Srdivacky    // Turn lhs >= rhs with lhs constant into rhs < lhs+1, this allows us to
750202878Srdivacky    // fold constant into instruction.
751202878Srdivacky    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
752202878Srdivacky      LHS = RHS;
753202878Srdivacky      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
754202878Srdivacky      TCC = MSP430CC::COND_L;
755202878Srdivacky      break;
756202878Srdivacky    }
757198396Srdivacky    TCC = MSP430CC::COND_GE;
758193323Sed    break;
759193323Sed  case ISD::SETGT:
760193323Sed    std::swap(LHS, RHS);        // FALLTHROUGH
761193323Sed  case ISD::SETLT:
762202878Srdivacky    // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to
763202878Srdivacky    // fold constant into instruction.
764202878Srdivacky    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
765202878Srdivacky      LHS = RHS;
766202878Srdivacky      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
767202878Srdivacky      TCC = MSP430CC::COND_GE;
768202878Srdivacky      break;
769202878Srdivacky    }
770198396Srdivacky    TCC = MSP430CC::COND_L;
771193323Sed    break;
772193323Sed  }
773193323Sed
774198396Srdivacky  TargetCC = DAG.getConstant(TCC, MVT::i8);
775218893Sdim  return DAG.getNode(MSP430ISD::CMP, dl, MVT::Glue, LHS, RHS);
776193323Sed}
777193323Sed
778193323Sed
779207618SrdivackySDValue MSP430TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
780193323Sed  SDValue Chain = Op.getOperand(0);
781193323Sed  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
782193323Sed  SDValue LHS   = Op.getOperand(2);
783193323Sed  SDValue RHS   = Op.getOperand(3);
784193323Sed  SDValue Dest  = Op.getOperand(4);
785193323Sed  DebugLoc dl   = Op.getDebugLoc();
786193323Sed
787198396Srdivacky  SDValue TargetCC;
788193323Sed  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
789193323Sed
790193323Sed  return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(),
791198396Srdivacky                     Chain, Dest, TargetCC, Flag);
792193323Sed}
793193323Sed
794207618SrdivackySDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
795200581Srdivacky  SDValue LHS   = Op.getOperand(0);
796200581Srdivacky  SDValue RHS   = Op.getOperand(1);
797200581Srdivacky  DebugLoc dl   = Op.getDebugLoc();
798200581Srdivacky
799200581Srdivacky  // If we are doing an AND and testing against zero, then the CMP
800200581Srdivacky  // will not be generated.  The AND (or BIT) will generate the condition codes,
801200581Srdivacky  // but they are different from CMP.
802202878Srdivacky  // FIXME: since we're doing a post-processing, use a pseudoinstr here, so
803202878Srdivacky  // lowering & isel wouldn't diverge.
804200581Srdivacky  bool andCC = false;
805200581Srdivacky  if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) {
806200581Srdivacky    if (RHSC->isNullValue() && LHS.hasOneUse() &&
807200581Srdivacky        (LHS.getOpcode() == ISD::AND ||
808200581Srdivacky         (LHS.getOpcode() == ISD::TRUNCATE &&
809200581Srdivacky          LHS.getOperand(0).getOpcode() == ISD::AND))) {
810200581Srdivacky      andCC = true;
811200581Srdivacky    }
812200581Srdivacky  }
813200581Srdivacky  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
814200581Srdivacky  SDValue TargetCC;
815200581Srdivacky  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
816200581Srdivacky
817200581Srdivacky  // Get the condition codes directly from the status register, if its easy.
818200581Srdivacky  // Otherwise a branch will be generated.  Note that the AND and BIT
819200581Srdivacky  // instructions generate different flags than CMP, the carry bit can be used
820200581Srdivacky  // for NE/EQ.
821200581Srdivacky  bool Invert = false;
822200581Srdivacky  bool Shift = false;
823200581Srdivacky  bool Convert = true;
824200581Srdivacky  switch (cast<ConstantSDNode>(TargetCC)->getZExtValue()) {
825200581Srdivacky   default:
826200581Srdivacky    Convert = false;
827200581Srdivacky    break;
828200581Srdivacky   case MSP430CC::COND_HS:
829200581Srdivacky     // Res = SRW & 1, no processing is required
830200581Srdivacky     break;
831202878Srdivacky   case MSP430CC::COND_LO:
832200581Srdivacky     // Res = ~(SRW & 1)
833200581Srdivacky     Invert = true;
834200581Srdivacky     break;
835202878Srdivacky   case MSP430CC::COND_NE:
836200581Srdivacky     if (andCC) {
837200581Srdivacky       // C = ~Z, thus Res = SRW & 1, no processing is required
838200581Srdivacky     } else {
839204642Srdivacky       // Res = ~((SRW >> 1) & 1)
840200581Srdivacky       Shift = true;
841204642Srdivacky       Invert = true;
842200581Srdivacky     }
843200581Srdivacky     break;
844202878Srdivacky   case MSP430CC::COND_E:
845204642Srdivacky     Shift = true;
846204642Srdivacky     // C = ~Z for AND instruction, thus we can put Res = ~(SRW & 1), however,
847204642Srdivacky     // Res = (SRW >> 1) & 1 is 1 word shorter.
848200581Srdivacky     break;
849200581Srdivacky  }
850200581Srdivacky  EVT VT = Op.getValueType();
851200581Srdivacky  SDValue One  = DAG.getConstant(1, VT);
852200581Srdivacky  if (Convert) {
853200581Srdivacky    SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SRW,
854202878Srdivacky                                    MVT::i16, Flag);
855200581Srdivacky    if (Shift)
856200581Srdivacky      // FIXME: somewhere this is turned into a SRL, lower it MSP specific?
857200581Srdivacky      SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One);
858200581Srdivacky    SR = DAG.getNode(ISD::AND, dl, MVT::i16, SR, One);
859200581Srdivacky    if (Invert)
860200581Srdivacky      SR = DAG.getNode(ISD::XOR, dl, MVT::i16, SR, One);
861200581Srdivacky    return SR;
862200581Srdivacky  } else {
863200581Srdivacky    SDValue Zero = DAG.getConstant(0, VT);
864218893Sdim    SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
865200581Srdivacky    SmallVector<SDValue, 4> Ops;
866200581Srdivacky    Ops.push_back(One);
867200581Srdivacky    Ops.push_back(Zero);
868200581Srdivacky    Ops.push_back(TargetCC);
869200581Srdivacky    Ops.push_back(Flag);
870200581Srdivacky    return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size());
871200581Srdivacky  }
872200581Srdivacky}
873200581Srdivacky
874207618SrdivackySDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op,
875207618Srdivacky                                             SelectionDAG &DAG) const {
876193323Sed  SDValue LHS    = Op.getOperand(0);
877193323Sed  SDValue RHS    = Op.getOperand(1);
878193323Sed  SDValue TrueV  = Op.getOperand(2);
879193323Sed  SDValue FalseV = Op.getOperand(3);
880193323Sed  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
881193323Sed  DebugLoc dl    = Op.getDebugLoc();
882193323Sed
883198396Srdivacky  SDValue TargetCC;
884193323Sed  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
885193323Sed
886218893Sdim  SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
887193323Sed  SmallVector<SDValue, 4> Ops;
888193323Sed  Ops.push_back(TrueV);
889193323Sed  Ops.push_back(FalseV);
890198396Srdivacky  Ops.push_back(TargetCC);
891193323Sed  Ops.push_back(Flag);
892193323Sed
893193323Sed  return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size());
894193323Sed}
895193323Sed
896193323SedSDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op,
897207618Srdivacky                                               SelectionDAG &DAG) const {
898193323Sed  SDValue Val = Op.getOperand(0);
899198090Srdivacky  EVT VT      = Op.getValueType();
900193323Sed  DebugLoc dl = Op.getDebugLoc();
901193323Sed
902193323Sed  assert(VT == MVT::i16 && "Only support i16 for now!");
903193323Sed
904193323Sed  return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT,
905193323Sed                     DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val),
906193323Sed                     DAG.getValueType(Val.getValueType()));
907193323Sed}
908193323Sed
909207618SrdivackySDValue
910207618SrdivackyMSP430TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) const {
911200581Srdivacky  MachineFunction &MF = DAG.getMachineFunction();
912200581Srdivacky  MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
913200581Srdivacky  int ReturnAddrIndex = FuncInfo->getRAIndex();
914200581Srdivacky
915200581Srdivacky  if (ReturnAddrIndex == 0) {
916200581Srdivacky    // Set up a frame object for the return address.
917200581Srdivacky    uint64_t SlotSize = TD->getPointerSize();
918200581Srdivacky    ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(SlotSize, -SlotSize,
919210299Sed                                                           true);
920200581Srdivacky    FuncInfo->setRAIndex(ReturnAddrIndex);
921200581Srdivacky  }
922200581Srdivacky
923200581Srdivacky  return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy());
924200581Srdivacky}
925200581Srdivacky
926207618SrdivackySDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op,
927207618Srdivacky                                              SelectionDAG &DAG) const {
928208599Srdivacky  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
929208599Srdivacky  MFI->setReturnAddressIsTaken(true);
930208599Srdivacky
931200581Srdivacky  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
932200581Srdivacky  DebugLoc dl = Op.getDebugLoc();
933200581Srdivacky
934200581Srdivacky  if (Depth > 0) {
935200581Srdivacky    SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
936200581Srdivacky    SDValue Offset =
937200581Srdivacky      DAG.getConstant(TD->getPointerSize(), MVT::i16);
938200581Srdivacky    return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
939200581Srdivacky                       DAG.getNode(ISD::ADD, dl, getPointerTy(),
940200581Srdivacky                                   FrameAddr, Offset),
941234353Sdim                       MachinePointerInfo(), false, false, false, 0);
942200581Srdivacky  }
943200581Srdivacky
944200581Srdivacky  // Just load the return address.
945200581Srdivacky  SDValue RetAddrFI = getReturnAddressFrameIndex(DAG);
946200581Srdivacky  return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
947234353Sdim                     RetAddrFI, MachinePointerInfo(), false, false, false, 0);
948200581Srdivacky}
949200581Srdivacky
950207618SrdivackySDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op,
951207618Srdivacky                                             SelectionDAG &DAG) const {
952200581Srdivacky  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
953200581Srdivacky  MFI->setFrameAddressIsTaken(true);
954208599Srdivacky
955200581Srdivacky  EVT VT = Op.getValueType();
956200581Srdivacky  DebugLoc dl = Op.getDebugLoc();  // FIXME probably not meaningful
957200581Srdivacky  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
958200581Srdivacky  SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl,
959200581Srdivacky                                         MSP430::FPW, VT);
960200581Srdivacky  while (Depth--)
961218893Sdim    FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
962218893Sdim                            MachinePointerInfo(),
963234353Sdim                            false, false, false, 0);
964200581Srdivacky  return FrameAddr;
965200581Srdivacky}
966200581Srdivacky
967249423SdimSDValue MSP430TargetLowering::LowerVASTART(SDValue Op,
968249423Sdim                                           SelectionDAG &DAG) const {
969249423Sdim  MachineFunction &MF = DAG.getMachineFunction();
970249423Sdim  MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
971249423Sdim
972249423Sdim  // Frame index of first vararg argument
973249423Sdim  SDValue FrameIndex = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),
974249423Sdim                                         getPointerTy());
975249423Sdim  const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
976249423Sdim
977249423Sdim  // Create a store of the frame index to the location operand
978249423Sdim  return DAG.getStore(Op.getOperand(0), Op.getDebugLoc(), FrameIndex,
979249423Sdim                      Op.getOperand(1), MachinePointerInfo(SV),
980249423Sdim                      false, false, 0);
981249423Sdim}
982249423Sdim
983199481Srdivacky/// getPostIndexedAddressParts - returns true by value, base pointer and
984199481Srdivacky/// offset pointer and addressing mode by reference if this node can be
985199481Srdivacky/// combined with a load / store to form a post-indexed load / store.
986199481Srdivackybool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
987199481Srdivacky                                                      SDValue &Base,
988199481Srdivacky                                                      SDValue &Offset,
989199481Srdivacky                                                      ISD::MemIndexedMode &AM,
990199481Srdivacky                                                      SelectionDAG &DAG) const {
991199481Srdivacky
992199481Srdivacky  LoadSDNode *LD = cast<LoadSDNode>(N);
993199481Srdivacky  if (LD->getExtensionType() != ISD::NON_EXTLOAD)
994199481Srdivacky    return false;
995199481Srdivacky
996199481Srdivacky  EVT VT = LD->getMemoryVT();
997199481Srdivacky  if (VT != MVT::i8 && VT != MVT::i16)
998199481Srdivacky    return false;
999199481Srdivacky
1000199481Srdivacky  if (Op->getOpcode() != ISD::ADD)
1001199481Srdivacky    return false;
1002199481Srdivacky
1003199481Srdivacky  if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) {
1004199481Srdivacky    uint64_t RHSC = RHS->getZExtValue();
1005199481Srdivacky    if ((VT == MVT::i16 && RHSC != 2) ||
1006199481Srdivacky        (VT == MVT::i8 && RHSC != 1))
1007199481Srdivacky      return false;
1008199481Srdivacky
1009199481Srdivacky    Base = Op->getOperand(0);
1010199481Srdivacky    Offset = DAG.getConstant(RHSC, VT);
1011199481Srdivacky    AM = ISD::POST_INC;
1012199481Srdivacky    return true;
1013199481Srdivacky  }
1014199481Srdivacky
1015199481Srdivacky  return false;
1016199481Srdivacky}
1017199481Srdivacky
1018199481Srdivacky
1019193323Sedconst char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
1020193323Sed  switch (Opcode) {
1021193323Sed  default: return NULL;
1022193323Sed  case MSP430ISD::RET_FLAG:           return "MSP430ISD::RET_FLAG";
1023200581Srdivacky  case MSP430ISD::RETI_FLAG:          return "MSP430ISD::RETI_FLAG";
1024193323Sed  case MSP430ISD::RRA:                return "MSP430ISD::RRA";
1025193323Sed  case MSP430ISD::RLA:                return "MSP430ISD::RLA";
1026193323Sed  case MSP430ISD::RRC:                return "MSP430ISD::RRC";
1027193323Sed  case MSP430ISD::CALL:               return "MSP430ISD::CALL";
1028193323Sed  case MSP430ISD::Wrapper:            return "MSP430ISD::Wrapper";
1029193323Sed  case MSP430ISD::BR_CC:              return "MSP430ISD::BR_CC";
1030193323Sed  case MSP430ISD::CMP:                return "MSP430ISD::CMP";
1031193323Sed  case MSP430ISD::SELECT_CC:          return "MSP430ISD::SELECT_CC";
1032200581Srdivacky  case MSP430ISD::SHL:                return "MSP430ISD::SHL";
1033200581Srdivacky  case MSP430ISD::SRA:                return "MSP430ISD::SRA";
1034193323Sed  }
1035193323Sed}
1036193323Sed
1037226633Sdimbool MSP430TargetLowering::isTruncateFree(Type *Ty1,
1038226633Sdim                                          Type *Ty2) const {
1039203954Srdivacky  if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
1040202878Srdivacky    return false;
1041202878Srdivacky
1042202878Srdivacky  return (Ty1->getPrimitiveSizeInBits() > Ty2->getPrimitiveSizeInBits());
1043202878Srdivacky}
1044202878Srdivacky
1045202878Srdivackybool MSP430TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
1046202878Srdivacky  if (!VT1.isInteger() || !VT2.isInteger())
1047202878Srdivacky    return false;
1048202878Srdivacky
1049202878Srdivacky  return (VT1.getSizeInBits() > VT2.getSizeInBits());
1050202878Srdivacky}
1051202878Srdivacky
1052226633Sdimbool MSP430TargetLowering::isZExtFree(Type *Ty1, Type *Ty2) const {
1053202878Srdivacky  // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
1054203954Srdivacky  return 0 && Ty1->isIntegerTy(8) && Ty2->isIntegerTy(16);
1055202878Srdivacky}
1056202878Srdivacky
1057202878Srdivackybool MSP430TargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
1058202878Srdivacky  // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
1059202878Srdivacky  return 0 && VT1 == MVT::i8 && VT2 == MVT::i16;
1060202878Srdivacky}
1061202878Srdivacky
1062249423Sdimbool MSP430TargetLowering::isZExtFree(SDValue Val, EVT VT2) const {
1063249423Sdim  return isZExtFree(Val.getValueType(), VT2);
1064249423Sdim}
1065249423Sdim
1066193323Sed//===----------------------------------------------------------------------===//
1067193323Sed//  Other Lowering Code
1068193323Sed//===----------------------------------------------------------------------===//
1069193323Sed
1070193323SedMachineBasicBlock*
1071200581SrdivackyMSP430TargetLowering::EmitShiftInstr(MachineInstr *MI,
1072207618Srdivacky                                     MachineBasicBlock *BB) const {
1073200581Srdivacky  MachineFunction *F = BB->getParent();
1074200581Srdivacky  MachineRegisterInfo &RI = F->getRegInfo();
1075200581Srdivacky  DebugLoc dl = MI->getDebugLoc();
1076200581Srdivacky  const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
1077200581Srdivacky
1078200581Srdivacky  unsigned Opc;
1079200581Srdivacky  const TargetRegisterClass * RC;
1080200581Srdivacky  switch (MI->getOpcode()) {
1081234353Sdim  default: llvm_unreachable("Invalid shift opcode!");
1082200581Srdivacky  case MSP430::Shl8:
1083200581Srdivacky   Opc = MSP430::SHL8r1;
1084239462Sdim   RC = &MSP430::GR8RegClass;
1085200581Srdivacky   break;
1086200581Srdivacky  case MSP430::Shl16:
1087200581Srdivacky   Opc = MSP430::SHL16r1;
1088239462Sdim   RC = &MSP430::GR16RegClass;
1089200581Srdivacky   break;
1090200581Srdivacky  case MSP430::Sra8:
1091200581Srdivacky   Opc = MSP430::SAR8r1;
1092239462Sdim   RC = &MSP430::GR8RegClass;
1093200581Srdivacky   break;
1094200581Srdivacky  case MSP430::Sra16:
1095200581Srdivacky   Opc = MSP430::SAR16r1;
1096239462Sdim   RC = &MSP430::GR16RegClass;
1097200581Srdivacky   break;
1098200581Srdivacky  case MSP430::Srl8:
1099200581Srdivacky   Opc = MSP430::SAR8r1c;
1100239462Sdim   RC = &MSP430::GR8RegClass;
1101200581Srdivacky   break;
1102200581Srdivacky  case MSP430::Srl16:
1103200581Srdivacky   Opc = MSP430::SAR16r1c;
1104239462Sdim   RC = &MSP430::GR16RegClass;
1105200581Srdivacky   break;
1106200581Srdivacky  }
1107200581Srdivacky
1108200581Srdivacky  const BasicBlock *LLVM_BB = BB->getBasicBlock();
1109200581Srdivacky  MachineFunction::iterator I = BB;
1110200581Srdivacky  ++I;
1111200581Srdivacky
1112200581Srdivacky  // Create loop block
1113200581Srdivacky  MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB);
1114200581Srdivacky  MachineBasicBlock *RemBB  = F->CreateMachineBasicBlock(LLVM_BB);
1115200581Srdivacky
1116200581Srdivacky  F->insert(I, LoopBB);
1117200581Srdivacky  F->insert(I, RemBB);
1118200581Srdivacky
1119200581Srdivacky  // Update machine-CFG edges by transferring all successors of the current
1120200581Srdivacky  // block to the block containing instructions after shift.
1121210299Sed  RemBB->splice(RemBB->begin(), BB,
1122210299Sed                llvm::next(MachineBasicBlock::iterator(MI)),
1123210299Sed                BB->end());
1124210299Sed  RemBB->transferSuccessorsAndUpdatePHIs(BB);
1125200581Srdivacky
1126200581Srdivacky  // Add adges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB
1127200581Srdivacky  BB->addSuccessor(LoopBB);
1128200581Srdivacky  BB->addSuccessor(RemBB);
1129200581Srdivacky  LoopBB->addSuccessor(RemBB);
1130200581Srdivacky  LoopBB->addSuccessor(LoopBB);
1131200581Srdivacky
1132239462Sdim  unsigned ShiftAmtReg = RI.createVirtualRegister(&MSP430::GR8RegClass);
1133239462Sdim  unsigned ShiftAmtReg2 = RI.createVirtualRegister(&MSP430::GR8RegClass);
1134200581Srdivacky  unsigned ShiftReg = RI.createVirtualRegister(RC);
1135200581Srdivacky  unsigned ShiftReg2 = RI.createVirtualRegister(RC);
1136200581Srdivacky  unsigned ShiftAmtSrcReg = MI->getOperand(2).getReg();
1137200581Srdivacky  unsigned SrcReg = MI->getOperand(1).getReg();
1138200581Srdivacky  unsigned DstReg = MI->getOperand(0).getReg();
1139200581Srdivacky
1140200581Srdivacky  // BB:
1141200581Srdivacky  // cmp 0, N
1142200581Srdivacky  // je RemBB
1143202375Srdivacky  BuildMI(BB, dl, TII.get(MSP430::CMP8ri))
1144202375Srdivacky    .addReg(ShiftAmtSrcReg).addImm(0);
1145200581Srdivacky  BuildMI(BB, dl, TII.get(MSP430::JCC))
1146200581Srdivacky    .addMBB(RemBB)
1147200581Srdivacky    .addImm(MSP430CC::COND_E);
1148200581Srdivacky
1149200581Srdivacky  // LoopBB:
1150200581Srdivacky  // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB]
1151200581Srdivacky  // ShiftAmt = phi [%N, BB],      [%ShiftAmt2, LoopBB]
1152200581Srdivacky  // ShiftReg2 = shift ShiftReg
1153200581Srdivacky  // ShiftAmt2 = ShiftAmt - 1;
1154200581Srdivacky  BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftReg)
1155200581Srdivacky    .addReg(SrcReg).addMBB(BB)
1156200581Srdivacky    .addReg(ShiftReg2).addMBB(LoopBB);
1157200581Srdivacky  BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg)
1158200581Srdivacky    .addReg(ShiftAmtSrcReg).addMBB(BB)
1159200581Srdivacky    .addReg(ShiftAmtReg2).addMBB(LoopBB);
1160200581Srdivacky  BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2)
1161200581Srdivacky    .addReg(ShiftReg);
1162200581Srdivacky  BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2)
1163200581Srdivacky    .addReg(ShiftAmtReg).addImm(1);
1164200581Srdivacky  BuildMI(LoopBB, dl, TII.get(MSP430::JCC))
1165200581Srdivacky    .addMBB(LoopBB)
1166200581Srdivacky    .addImm(MSP430CC::COND_NE);
1167200581Srdivacky
1168200581Srdivacky  // RemBB:
1169200581Srdivacky  // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB]
1170210299Sed  BuildMI(*RemBB, RemBB->begin(), dl, TII.get(MSP430::PHI), DstReg)
1171200581Srdivacky    .addReg(SrcReg).addMBB(BB)
1172200581Srdivacky    .addReg(ShiftReg2).addMBB(LoopBB);
1173200581Srdivacky
1174210299Sed  MI->eraseFromParent();   // The pseudo instruction is gone now.
1175200581Srdivacky  return RemBB;
1176200581Srdivacky}
1177200581Srdivacky
1178200581SrdivackyMachineBasicBlock*
1179193323SedMSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
1180207618Srdivacky                                                  MachineBasicBlock *BB) const {
1181200581Srdivacky  unsigned Opc = MI->getOpcode();
1182200581Srdivacky
1183200581Srdivacky  if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 ||
1184200581Srdivacky      Opc == MSP430::Sra8 || Opc == MSP430::Sra16 ||
1185200581Srdivacky      Opc == MSP430::Srl8 || Opc == MSP430::Srl16)
1186207618Srdivacky    return EmitShiftInstr(MI, BB);
1187200581Srdivacky
1188193323Sed  const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
1189193323Sed  DebugLoc dl = MI->getDebugLoc();
1190200581Srdivacky
1191200581Srdivacky  assert((Opc == MSP430::Select16 || Opc == MSP430::Select8) &&
1192193323Sed         "Unexpected instr type to insert");
1193193323Sed
1194193323Sed  // To "insert" a SELECT instruction, we actually have to insert the diamond
1195193323Sed  // control-flow pattern.  The incoming instruction knows the destination vreg
1196193323Sed  // to set, the condition code register to branch on, the true/false values to
1197193323Sed  // select between, and a branch opcode to use.
1198193323Sed  const BasicBlock *LLVM_BB = BB->getBasicBlock();
1199193323Sed  MachineFunction::iterator I = BB;
1200193323Sed  ++I;
1201193323Sed
1202193323Sed  //  thisMBB:
1203193323Sed  //  ...
1204193323Sed  //   TrueVal = ...
1205193323Sed  //   cmpTY ccX, r1, r2
1206193323Sed  //   jCC copy1MBB
1207193323Sed  //   fallthrough --> copy0MBB
1208193323Sed  MachineBasicBlock *thisMBB = BB;
1209193323Sed  MachineFunction *F = BB->getParent();
1210193323Sed  MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
1211193323Sed  MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB);
1212193323Sed  F->insert(I, copy0MBB);
1213193323Sed  F->insert(I, copy1MBB);
1214193323Sed  // Update machine-CFG edges by transferring all successors of the current
1215193323Sed  // block to the new block which will contain the Phi node for the select.
1216210299Sed  copy1MBB->splice(copy1MBB->begin(), BB,
1217210299Sed                   llvm::next(MachineBasicBlock::iterator(MI)),
1218210299Sed                   BB->end());
1219210299Sed  copy1MBB->transferSuccessorsAndUpdatePHIs(BB);
1220193323Sed  // Next, add the true and fallthrough blocks as its successors.
1221193323Sed  BB->addSuccessor(copy0MBB);
1222193323Sed  BB->addSuccessor(copy1MBB);
1223193323Sed
1224210299Sed  BuildMI(BB, dl, TII.get(MSP430::JCC))
1225210299Sed    .addMBB(copy1MBB)
1226210299Sed    .addImm(MI->getOperand(3).getImm());
1227210299Sed
1228193323Sed  //  copy0MBB:
1229193323Sed  //   %FalseValue = ...
1230193323Sed  //   # fallthrough to copy1MBB
1231193323Sed  BB = copy0MBB;
1232193323Sed
1233193323Sed  // Update machine-CFG edges
1234193323Sed  BB->addSuccessor(copy1MBB);
1235193323Sed
1236193323Sed  //  copy1MBB:
1237193323Sed  //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
1238193323Sed  //  ...
1239193323Sed  BB = copy1MBB;
1240210299Sed  BuildMI(*BB, BB->begin(), dl, TII.get(MSP430::PHI),
1241193323Sed          MI->getOperand(0).getReg())
1242193323Sed    .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB)
1243193323Sed    .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB);
1244193323Sed
1245210299Sed  MI->eraseFromParent();   // The pseudo instruction is gone now.
1246193323Sed  return BB;
1247193323Sed}
1248