MSP430ISelLowering.cpp revision 0c1ba91a54e7088fab3a3b9820f8b8366be0e11b
1f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//===-- MSP430ISelLowering.cpp - MSP430 DAG Lowering Implementation  ------===//
2f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//
3f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//                     The LLVM Compiler Infrastructure
4f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//
5f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// This file is distributed under the University of Illinois Open Source
6f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// License. See LICENSE.TXT for details.
7f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//
8f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//===----------------------------------------------------------------------===//
9f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//
10f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// This file implements the MSP430TargetLowering class.
11f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//
12f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//===----------------------------------------------------------------------===//
13f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
14f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#define DEBUG_TYPE "msp430-lower"
15f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
16f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430ISelLowering.h"
17f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430.h"
1806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov#include "MSP430MachineFunctionInfo.h"
19f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430TargetMachine.h"
20f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430Subtarget.h"
21f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/DerivedTypes.h"
22f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/Function.h"
23f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/Intrinsics.h"
24f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CallingConv.h"
25f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/GlobalVariable.h"
26f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/GlobalAlias.h"
27f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/CallingConvLower.h"
28f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h"
29f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineFunction.h"
30f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h"
31f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineRegisterInfo.h"
32c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov#include "llvm/CodeGen/PseudoSourceValue.h"
33f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/SelectionDAGISel.h"
34f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/ValueTypes.h"
35f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner#include "llvm/Target/TargetLoweringObjectFile.h"
36b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov#include "llvm/Support/CommandLine.h"
37f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/Support/Debug.h"
38804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin#include "llvm/Support/ErrorHandling.h"
394437ae213d5435390f0750213b53ec807c047f22Chris Lattner#include "llvm/Support/raw_ostream.h"
40f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/ADT/VectorExtras.h"
41f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovusing namespace llvm;
42f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
43b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikovtypedef enum {
44b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  NoHWMult,
45b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  HWMultIntr,
46b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  HWMultNoIntr
47b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov} HWMultUseMode;
48b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov
49b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikovstatic cl::opt<HWMultUseMode>
50b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton KorobeynikovHWMultMode("msp430-hwmult-mode",
51b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov           cl::desc("Hardware multiplier use mode"),
52b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov           cl::init(HWMultNoIntr),
53b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov           cl::values(
54b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov             clEnumValN(NoHWMult, "no",
55b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov                "Do not use hardware multiplier"),
56b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov             clEnumValN(HWMultIntr, "interrupts",
57b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov                "Assume hardware multiplier can be used inside interrupts"),
58b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov             clEnumValN(HWMultNoIntr, "use",
59b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov                "Assume hardware multiplier cannot be used inside interrupts"),
60b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov             clEnumValEnd));
61b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov
62f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovMSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) :
63f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner  TargetLowering(tm, new TargetLoweringObjectFileELF()),
64f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner  Subtarget(*tm.getSubtargetImpl()), TM(tm) {
65f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
6606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  TD = getTargetData();
6706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
68f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  // Set up the register classes.
69825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  addRegisterClass(MVT::i8,  MSP430::GR8RegisterClass);
70825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  addRegisterClass(MVT::i16, MSP430::GR16RegisterClass);
71f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
72f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  // Compute derived properties from the register classes
73f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  computeRegisterProperties();
74fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
751476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov  // Provide all sorts of operation actions
761476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov
771476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov  // Division is expensive
781476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov  setIntDivIsCheap(false);
791476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov
80d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  // Even if we have only 1 bit shift here, we can perform
81d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  // shifts of the whole bitwidth 1 bit per step.
82825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setShiftAmountType(MVT::i8);
83d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
84c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov  setStackPointerRegisterToSaveRestore(MSP430::SPW);
85c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov  setBooleanContents(ZeroOrOneBooleanContent);
86c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov  setSchedulingPreference(SchedulingForLatency);
87c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov
8806ac0820a6cefa6896000054d8e4906326c0cce6Anton Korobeynikov  // We have post-incremented loads / stores.
896534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  setIndexedLoadAction(ISD::POST_INC, MVT::i8, Legal);
906534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  setIndexedLoadAction(ISD::POST_INC, MVT::i16, Legal);
916534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
926534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  setLoadExtAction(ISD::EXTLOAD,  MVT::i1,  Promote);
936534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  setLoadExtAction(ISD::SEXTLOAD, MVT::i1,  Promote);
946534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  setLoadExtAction(ISD::ZEXTLOAD, MVT::i1,  Promote);
956534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  setLoadExtAction(ISD::SEXTLOAD, MVT::i8,  Expand);
96825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Expand);
9736b6e533c1aac85452438161f7034a9f54bd1830Anton Korobeynikov
9854f30d3fc94e055f13e6744378323d05c5c050baAnton Korobeynikov  // We don't have any truncstores
99825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setTruncStoreAction(MVT::i16, MVT::i8, Expand);
100825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
101825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRA,              MVT::i8,    Custom);
102825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SHL,              MVT::i8,    Custom);
103825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRL,              MVT::i8,    Custom);
104825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRA,              MVT::i16,   Custom);
105825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SHL,              MVT::i16,   Custom);
106825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRL,              MVT::i16,   Custom);
107825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ROTL,             MVT::i8,    Expand);
108825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ROTR,             MVT::i8,    Expand);
109825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ROTL,             MVT::i16,   Expand);
110825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ROTR,             MVT::i16,   Expand);
111825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::GlobalAddress,    MVT::i16,   Custom);
112825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ExternalSymbol,   MVT::i16,   Custom);
113825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BR_JT,            MVT::Other, Expand);
114825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BRIND,            MVT::Other, Expand);
115825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BR_CC,            MVT::i8,    Custom);
116825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BR_CC,            MVT::i16,   Custom);
117825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BRCOND,           MVT::Other, Expand);
1188d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  setOperationAction(ISD::SETCC,            MVT::i8,    Custom);
1198d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  setOperationAction(ISD::SETCC,            MVT::i16,   Custom);
120825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT,           MVT::i8,    Expand);
121825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT,           MVT::i16,   Expand);
122825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT_CC,        MVT::i8,    Custom);
123825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT_CC,        MVT::i16,   Custom);
124825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SIGN_EXTEND,      MVT::i16,   Custom);
125379a087cc7175532ff0c24c60069da5eec596879Anton Korobeynikov  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i8, Expand);
126379a087cc7175532ff0c24c60069da5eec596879Anton Korobeynikov  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i16, Expand);
127825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
128825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTTZ,             MVT::i8,    Expand);
129825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTTZ,             MVT::i16,   Expand);
130825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTLZ,             MVT::i8,    Expand);
131825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTLZ,             MVT::i16,   Expand);
132825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTPOP,            MVT::i8,    Expand);
133825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTPOP,            MVT::i16,   Expand);
134825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
135825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SHL_PARTS,        MVT::i8,    Expand);
136825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SHL_PARTS,        MVT::i16,   Expand);
137825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRL_PARTS,        MVT::i8,    Expand);
138825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRL_PARTS,        MVT::i16,   Expand);
139825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRA_PARTS,        MVT::i8,    Expand);
140825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRA_PARTS,        MVT::i16,   Expand);
141825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
142825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1,   Expand);
143e4ce880dfa340bf45ddce10bb1dbe856553677b6Eli Friedman
1448725bd22bf91c29e2351a127295c19fea996e2c7Anton Korobeynikov  // FIXME: Implement efficiently multiplication by a constant
1458983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::MUL,              MVT::i8,    Expand);
1468983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::MULHS,            MVT::i8,    Expand);
1478983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::MULHU,            MVT::i8,    Expand);
1488983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::SMUL_LOHI,        MVT::i8,    Expand);
1498983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::UMUL_LOHI,        MVT::i8,    Expand);
150825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::MUL,              MVT::i16,   Expand);
151825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::MULHS,            MVT::i16,   Expand);
152825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::MULHU,            MVT::i16,   Expand);
153825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SMUL_LOHI,        MVT::i16,   Expand);
154825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::UMUL_LOHI,        MVT::i16,   Expand);
155825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
1568983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::UDIV,             MVT::i8,    Expand);
1578983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::UDIVREM,          MVT::i8,    Expand);
1588983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::UREM,             MVT::i8,    Expand);
1598983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::SDIV,             MVT::i8,    Expand);
1608983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::SDIVREM,          MVT::i8,    Expand);
1618983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::SREM,             MVT::i8,    Expand);
162825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::UDIV,             MVT::i16,   Expand);
163825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::UDIVREM,          MVT::i16,   Expand);
164825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::UREM,             MVT::i16,   Expand);
165825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SDIV,             MVT::i16,   Expand);
166825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SDIVREM,          MVT::i16,   Expand);
167825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SREM,             MVT::i16,   Expand);
168b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov
169b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  // Libcalls names.
170b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  if (HWMultMode == HWMultIntr) {
171b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I8,  "__mulqi3hw");
172b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I16, "__mulhi3hw");
173b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  } else if (HWMultMode == HWMultNoIntr) {
174b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I8,  "__mulqi3hw_noint");
175b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I16, "__mulhi3hw_noint");
176b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  }
177f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
178f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
179b8639f52143c99a3902b83555db4c54766c783caAnton KorobeynikovSDValue MSP430TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
180f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  switch (Op.getOpcode()) {
181ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov  case ISD::SHL: // FALLTHROUGH
182e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  case ISD::SRL:
1834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  case ISD::SRA:              return LowerShifts(Op, DAG);
1843513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  case ISD::GlobalAddress:    return LowerGlobalAddress(Op, DAG);
1855d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  case ISD::ExternalSymbol:   return LowerExternalSymbol(Op, DAG);
1868d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  case ISD::SETCC:            return LowerSETCC(Op, DAG);
1871bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case ISD::BR_CC:            return LowerBR_CC(Op, DAG);
1881bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case ISD::SELECT_CC:        return LowerSELECT_CC(Op, DAG);
189b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  case ISD::SIGN_EXTEND:      return LowerSIGN_EXTEND(Op, DAG);
19006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  case ISD::RETURNADDR:       return LowerRETURNADDR(Op, DAG);
19106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  case ISD::FRAMEADDR:        return LowerFRAMEADDR(Op, DAG);
192f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  default:
193c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("unimplemented operand");
194f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov    return SDValue();
195f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  }
196f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
197f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
198b4202b84d7e54efe5e144885c7da63e6cc465f80Bill Wendling/// getFunctionAlignment - Return the Log2 alignment of this function.
19920c568f366be211323eeaf0e45ef053278ec9ddcBill Wendlingunsigned MSP430TargetLowering::getFunctionAlignment(const Function *F) const {
2003741be39f98795a841a4d8c35bf54928769ac3cdAnton Korobeynikov  return F->hasFnAttr(Attribute::OptimizeForSize) ? 1 : 2;
20120c568f366be211323eeaf0e45ef053278ec9ddcBill Wendling}
20220c568f366be211323eeaf0e45ef053278ec9ddcBill Wendling
203c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===//
204cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//                       MSP430 Inline Assembly Support
205cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===//
206cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
207cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// getConstraintType - Given a constraint letter, return the type of
208cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// constraint it is for this target.
209cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovTargetLowering::ConstraintType
210cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering::getConstraintType(const std::string &Constraint) const {
211cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  if (Constraint.size() == 1) {
212cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    switch (Constraint[0]) {
213cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    case 'r':
214cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      return C_RegisterClass;
215cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    default:
216cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      break;
217cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    }
218cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  }
219cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  return TargetLowering::getConstraintType(Constraint);
220cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov}
221cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
222cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikovstd::pair<unsigned, const TargetRegisterClass*>
223cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering::
224cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovgetRegForInlineAsmConstraint(const std::string &Constraint,
225cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov                             EVT VT) const {
226cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  if (Constraint.size() == 1) {
227cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    // GCC Constraint Letters
228cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    switch (Constraint[0]) {
229cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    default: break;
230cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    case 'r':   // GENERAL_REGS
231cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      if (VT == MVT::i8)
232cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov        return std::make_pair(0U, MSP430::GR8RegisterClass);
233cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
234cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      return std::make_pair(0U, MSP430::GR16RegisterClass);
235cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    }
236cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  }
237cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
238cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
239cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov}
240cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
241cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===//
242c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//                      Calling Convention Implementation
243c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===//
244c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
245f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430GenCallingConv.inc"
246c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
24798ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
24898ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerFormalArguments(SDValue Chain,
24965c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                           CallingConv::ID CallConv,
25098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           bool isVarArg,
25198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           const SmallVectorImpl<ISD::InputArg>
25298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                             &Ins,
25398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           DebugLoc dl,
25498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           SelectionDAG &DAG,
25598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           SmallVectorImpl<SDValue> &InVals) {
25698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
25798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  switch (CallConv) {
258c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  default:
259c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Unsupported calling convention");
260c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  case CallingConv::C:
261c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  case CallingConv::Fast:
26298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman    return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals);
263e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  case CallingConv::MSP430_INTR:
264e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov   if (Ins.empty())
265e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov     return Chain;
266e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov   else {
267e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    llvm_report_error("ISRs cannot have arguments");
268e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    return SDValue();
269e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov   }
270c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  }
271c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov}
272c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
27398ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
27498ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
27565c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                CallingConv::ID CallConv, bool isVarArg,
27698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                bool isTailCall,
27798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                const SmallVectorImpl<ISD::OutputArg> &Outs,
27898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                const SmallVectorImpl<ISD::InputArg> &Ins,
27998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                DebugLoc dl, SelectionDAG &DAG,
28098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                SmallVectorImpl<SDValue> &InVals) {
28198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
28298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  switch (CallConv) {
2834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  default:
284c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Unsupported calling convention");
2854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  case CallingConv::Fast:
2864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  case CallingConv::C:
28798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman    return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
28898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                          Outs, Ins, dl, DAG, InVals);
289e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  case CallingConv::MSP430_INTR:
290e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    llvm_report_error("ISRs cannot be called directly");
291e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    return SDValue();
2924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
2934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov}
2944428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
295c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// LowerCCCArguments - transform physical registers into virtual registers and
296c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// generate load operations for arguments places on the stack.
297c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// FIXME: struct return stuff
298c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// FIXME: varargs
29998ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
30098ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCArguments(SDValue Chain,
30165c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                        CallingConv::ID CallConv,
30298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        bool isVarArg,
30398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        const SmallVectorImpl<ISD::InputArg>
30498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                          &Ins,
30598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        DebugLoc dl,
30698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        SelectionDAG &DAG,
30798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        SmallVectorImpl<SDValue> &InVals) {
308c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  MachineFunction &MF = DAG.getMachineFunction();
309c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  MachineFrameInfo *MFI = MF.getFrameInfo();
310c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  MachineRegisterInfo &RegInfo = MF.getRegInfo();
311c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
312c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  // Assign locations to all of the incoming arguments.
313c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  SmallVector<CCValAssign, 16> ArgLocs;
31498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCState CCInfo(CallConv, isVarArg, getTargetMachine(),
31598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                 ArgLocs, *DAG.getContext());
31698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCInfo.AnalyzeFormalArguments(Ins, CC_MSP430);
317c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
318c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  assert(!isVarArg && "Varargs not supported yet");
319c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
320c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
321c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    CCValAssign &VA = ArgLocs[i];
322c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    if (VA.isRegLoc()) {
323c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      // Arguments passed in registers
324e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson      EVT RegVT = VA.getLocVT();
325825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      switch (RegVT.getSimpleVT().SimpleTy) {
326804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin      default:
327804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin        {
328dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#ifndef NDEBUG
3294437ae213d5435390f0750213b53ec807c047f22Chris Lattner          errs() << "LowerFormalArguments Unhandled argument type: "
330825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson               << RegVT.getSimpleVT().SimpleTy << "\n";
331dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#endif
332c23197a26f34f559ea9797de51e187087c039c42Torok Edwin          llvm_unreachable(0);
333804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin        }
334825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      case MVT::i16:
335c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        unsigned VReg =
3361df221f2bb8e8380e255d1bec73ab07b388d01a2Anton Korobeynikov          RegInfo.createVirtualRegister(MSP430::GR16RegisterClass);
337c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        RegInfo.addLiveIn(VA.getLocReg(), VReg);
33898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman        SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, RegVT);
339c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
340c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        // If this is an 8-bit value, it is really passed promoted to 16
341c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        // bits. Insert an assert[sz]ext to capture this, then truncate to the
342c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        // right size.
343c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        if (VA.getLocInfo() == CCValAssign::SExt)
344c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov          ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue,
345c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov                                 DAG.getValueType(VA.getValVT()));
346c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        else if (VA.getLocInfo() == CCValAssign::ZExt)
347c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov          ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue,
348c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov                                 DAG.getValueType(VA.getValVT()));
349c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
350c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        if (VA.getLocInfo() != CCValAssign::Full)
351c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov          ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
352c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
35398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman        InVals.push_back(ArgValue);
354c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      }
355c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    } else {
356c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      // Sanity check
357c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      assert(VA.isMemLoc());
358c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      // Load the argument to a virtual register
359c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      unsigned ObjSize = VA.getLocVT().getSizeInBits()/8;
360c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      if (ObjSize > 2) {
3614437ae213d5435390f0750213b53ec807c047f22Chris Lattner        errs() << "LowerFormalArguments Unhandled argument type: "
362825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson             << VA.getLocVT().getSimpleVT().SimpleTy
363c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov             << "\n";
364c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      }
365c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      // Create the frame index object for this incoming parameter...
3663f2bf85d14759cc4b28a86805f566ac805a54d00David Greene      int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true, false);
367c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
368c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      // Create the SelectionDAG nodes corresponding to a load
369c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      //from this parameter
370825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      SDValue FIN = DAG.getFrameIndex(FI, MVT::i16);
37198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman      InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN,
3726553155172a2e74feff1253837daa608123de54aEvan Cheng                                   PseudoSourceValue::getFixedStack(FI), 0));
373c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    }
374c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  }
375c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
37698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return Chain;
377c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov}
378fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
37998ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
38098ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerReturn(SDValue Chain,
38165c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                  CallingConv::ID CallConv, bool isVarArg,
38298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                  const SmallVectorImpl<ISD::OutputArg> &Outs,
38398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                  DebugLoc dl, SelectionDAG &DAG) {
38498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
385fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // CCValAssign - represent the assignment of the return value to a location
386fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  SmallVector<CCValAssign, 16> RVLocs;
387fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
388e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  // ISRs cannot return any value.
389e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  if (CallConv == CallingConv::MSP430_INTR && !Outs.empty()) {
390e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    llvm_report_error("ISRs cannot return any value");
391e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    return SDValue();
392e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  }
393e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov
394fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // CCState - Info about the registers and stack slot.
39598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCState CCInfo(CallConv, isVarArg, getTargetMachine(),
39698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                 RVLocs, *DAG.getContext());
397fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
39898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  // Analize return values.
39998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCInfo.AnalyzeReturn(Outs, RetCC_MSP430);
400fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
401fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // If this is the first return lowered for this function, add the regs to the
402fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // liveout set for the function.
403fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
404fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    for (unsigned i = 0; i != RVLocs.size(); ++i)
405fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov      if (RVLocs[i].isRegLoc())
406fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov        DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
407fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  }
408fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
409fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  SDValue Flag;
410fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
411fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // Copy the result values into the output registers.
412fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  for (unsigned i = 0; i != RVLocs.size(); ++i) {
413fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    CCValAssign &VA = RVLocs[i];
414fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    assert(VA.isRegLoc() && "Can only return in registers!");
415fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
416fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
41798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                             Outs[i].Val, Flag);
418fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
419dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov    // Guarantee that all emitted copies are stuck together,
420dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov    // avoiding something bad.
421fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    Flag = Chain.getValue(1);
422fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  }
423fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
424e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  unsigned Opc = (CallConv == CallingConv::MSP430_INTR ?
425e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov                  MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG);
426e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov
427fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  if (Flag.getNode())
428e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    return DAG.getNode(Opc, dl, MVT::Other, Chain, Flag);
429fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
430fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // Return Void
431e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  return DAG.getNode(Opc, dl, MVT::Other, Chain);
432fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov}
433fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
4344428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// LowerCCCCallTo - functions arguments are copied from virtual regs to
4354428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
4364428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// TODO: sret.
43798ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
43898ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee,
43965c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                     CallingConv::ID CallConv, bool isVarArg,
44098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     bool isTailCall,
44198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     const SmallVectorImpl<ISD::OutputArg>
44298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                       &Outs,
44398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     const SmallVectorImpl<ISD::InputArg> &Ins,
44498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     DebugLoc dl, SelectionDAG &DAG,
44598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     SmallVectorImpl<SDValue> &InVals) {
4464428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Analyze operands of the call, assigning locations to each operand.
4474428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<CCValAssign, 16> ArgLocs;
44898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCState CCInfo(CallConv, isVarArg, getTargetMachine(),
44998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                 ArgLocs, *DAG.getContext());
4504428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
45198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCInfo.AnalyzeCallOperands(Outs, CC_MSP430);
4524428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4534428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Get a count of how many bytes are to be pushed on the stack.
4544428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  unsigned NumBytes = CCInfo.getNextStackOffset();
4554428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4564428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Chain = DAG.getCALLSEQ_START(Chain ,DAG.getConstant(NumBytes,
4574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                                      getPointerTy(), true));
4584428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4594428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass;
4604428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<SDValue, 12> MemOpChains;
4614428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SDValue StackPtr;
4624428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4634428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Walk the register/memloc assignments, inserting copies/loads.
4644428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
4654428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    CCValAssign &VA = ArgLocs[i];
4664428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
46798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman    SDValue Arg = Outs[i].Val;
4684428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4694428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    // Promote the value if needed.
4704428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    switch (VA.getLocInfo()) {
471c23197a26f34f559ea9797de51e187087c039c42Torok Edwin      default: llvm_unreachable("Unknown loc info!");
4724428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::Full: break;
4734428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::SExt:
4744428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
4754428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        break;
4764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::ZExt:
4774428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
4784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        break;
4794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::AExt:
4804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
4814428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        break;
4824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    }
4834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    // Arguments that can be passed on register must be kept at RegsToPass
4854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    // vector
4864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    if (VA.isRegLoc()) {
4874428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
4884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    } else {
4894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      assert(VA.isMemLoc());
4904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      if (StackPtr.getNode() == 0)
4924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SPW, getPointerTy());
4934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4944428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(),
4954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                   StackPtr,
4964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                   DAG.getIntPtrConstant(VA.getLocMemOffset()));
4974428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4994428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
5004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                         PseudoSourceValue::getStack(),
5014428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                         VA.getLocMemOffset()));
5024428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    }
5034428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
5044428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5054428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Transform all store nodes into one single node because all store nodes are
5064428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // independent of each other.
5074428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  if (!MemOpChains.empty())
508825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
5094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                        &MemOpChains[0], MemOpChains.size());
5104428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5114428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Build a sequence of copy-to-reg nodes chained together with token chain and
5124428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // flag operands which copy the outgoing args into registers.  The InFlag in
5134428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // necessary since all emited instructions must be stuck together.
5144428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SDValue InFlag;
5154428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
5164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
5174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             RegsToPass[i].second, InFlag);
5184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    InFlag = Chain.getValue(1);
5194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
5204428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5214428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // If the callee is a GlobalAddress node (quite common, every direct call is)
5224428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
5234428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Likewise ExternalSymbol -> TargetExternalSymbol.
5244428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
525825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    Callee = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i16);
5264428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
527825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i16);
5284428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5294428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Returns a chain & a flag for retval copy to use.
530825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
5314428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<SDValue, 8> Ops;
5324428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Ops.push_back(Chain);
5334428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Ops.push_back(Callee);
5344428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5354428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Add argument registers to the end of the list so that they are
5364428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // known live into the call.
5374428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
5384428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Ops.push_back(DAG.getRegister(RegsToPass[i].first,
5394428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                  RegsToPass[i].second.getValueType()));
5404428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5414428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  if (InFlag.getNode())
5424428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Ops.push_back(InFlag);
5434428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5444428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Chain = DAG.getNode(MSP430ISD::CALL, dl, NodeTys, &Ops[0], Ops.size());
5454428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  InFlag = Chain.getValue(1);
5464428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5474428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Create the CALLSEQ_END node.
5484428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Chain = DAG.getCALLSEQ_END(Chain,
5494428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             DAG.getConstant(NumBytes, getPointerTy(), true),
5504428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             DAG.getConstant(0, getPointerTy(), true),
5514428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             InFlag);
5524428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  InFlag = Chain.getValue(1);
5534428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5544428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Handle result values, copying them out of physregs into vregs that we
5554428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // return.
55698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl,
55798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                         DAG, InVals);
5584428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov}
5594428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
56098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// LowerCallResult - Lower the result values of a call into the
56198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// appropriate copies out of appropriate physical registers.
56298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman///
56398ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
5644428885c5acfffbbdd03ad2aab23960531c47753Anton KorobeynikovMSP430TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag,
56565c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                      CallingConv::ID CallConv, bool isVarArg,
56698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                      const SmallVectorImpl<ISD::InputArg> &Ins,
56798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                      DebugLoc dl, SelectionDAG &DAG,
56898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                      SmallVectorImpl<SDValue> &InVals) {
5694428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5704428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Assign locations to each value returned by this call.
5714428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<CCValAssign, 16> RVLocs;
57298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCState CCInfo(CallConv, isVarArg, getTargetMachine(),
573e922c0201916e0b980ab3cfe91e1413e68d55647Owen Anderson                 RVLocs, *DAG.getContext());
5744428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
57598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCInfo.AnalyzeCallResult(Ins, RetCC_MSP430);
5764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5774428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Copy all of the result registers out of their specified physreg.
5784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0; i != RVLocs.size(); ++i) {
5794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(),
5804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                               RVLocs[i].getValVT(), InFlag).getValue(1);
5814428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    InFlag = Chain.getValue(2);
58298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman    InVals.push_back(Chain.getValue(0));
5834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
5844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
58598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return Chain;
5864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov}
5874428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
588d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton KorobeynikovSDValue MSP430TargetLowering::LowerShifts(SDValue Op,
589d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov                                          SelectionDAG &DAG) {
590ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov  unsigned Opc = Op.getOpcode();
591d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  SDNode* N = Op.getNode();
592e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = Op.getValueType();
593d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  DebugLoc dl = N->getDebugLoc();
594d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
5952625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Expand non-constant shifts to loops:
596d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  if (!isa<ConstantSDNode>(N->getOperand(1)))
5972625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    switch (Opc) {
5982625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    default:
5992625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      assert(0 && "Invalid shift opcode!");
6002625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    case ISD::SHL:
6012625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      return DAG.getNode(MSP430ISD::SHL, dl,
6022625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                         VT, N->getOperand(0), N->getOperand(1));
6032625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    case ISD::SRA:
6042625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      return DAG.getNode(MSP430ISD::SRA, dl,
6052625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                         VT, N->getOperand(0), N->getOperand(1));
6062625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    case ISD::SRL:
6072625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      return DAG.getNode(MSP430ISD::SRL, dl,
6082625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                         VT, N->getOperand(0), N->getOperand(1));
6092625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    }
610d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
611d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
612d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
613d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  // Expand the stuff into sequence of shifts.
614d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  // FIXME: for some shift amounts this might be done better!
615d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N
616d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  SDValue Victim = N->getOperand(0);
617e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov
618e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  if (Opc == ISD::SRL && ShiftAmount) {
619e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov    // Emit a special goodness here:
620e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov    // srl A, 1 => clrc; rrc A
621bf8ef3f29de28529b5d65970af9015c41f7c809bAnton Korobeynikov    Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim);
622e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov    ShiftAmount -= 1;
623e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  }
624e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov
625d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  while (ShiftAmount--)
626aceb620de855485a4fb2eed343d880d76f6c701cAnton Korobeynikov    Victim = DAG.getNode((Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA),
627ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov                         dl, VT, Victim);
628d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
629d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  return Victim;
630d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov}
631d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
6323513ca81c6beda087a281a66f1b0e612879c0aadAnton KorobeynikovSDValue MSP430TargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) {
6333513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
6343513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();
6353513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov
6363513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  // Create the TargetGlobalAddress node, folding in the constant offset.
6373513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  SDValue Result = DAG.getTargetGlobalAddress(GV, getPointerTy(), Offset);
6383513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  return DAG.getNode(MSP430ISD::Wrapper, Op.getDebugLoc(),
6393513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov                     getPointerTy(), Result);
6403513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov}
6413513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov
6425d59f68ade7573175f1ace09061a94286e59076bAnton KorobeynikovSDValue MSP430TargetLowering::LowerExternalSymbol(SDValue Op,
6435d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov                                                  SelectionDAG &DAG) {
6445d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  DebugLoc dl = Op.getDebugLoc();
6455d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol();
6465d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  SDValue Result = DAG.getTargetExternalSymbol(Sym, getPointerTy());
6475d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov
6485d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result);;
6495d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov}
6505d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov
6513926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikovstatic SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC,
6521bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov                       ISD::CondCode CC,
6531bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov                       DebugLoc dl, SelectionDAG &DAG) {
654ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  // FIXME: Handle bittests someday
655ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet");
656ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
657ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  // FIXME: Handle jump negative someday
6583926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  MSP430CC::CondCodes TCC = MSP430CC::COND_INVALID;
659ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  switch (CC) {
660c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Invalid integer condition!");
661ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETEQ:
6623926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_E;     // aka COND_Z
663f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    // Minor optimization: if LHS is a constant, swap operands, then the
6641722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov    // constant can be folded into comparison.
665f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    if (LHS.getOpcode() == ISD::Constant)
6661722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov      std::swap(LHS, RHS);
667ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
668ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETNE:
6693926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_NE;    // aka COND_NZ
670f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    // Minor optimization: if LHS is a constant, swap operands, then the
6711722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov    // constant can be folded into comparison.
672f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    if (LHS.getOpcode() == ISD::Constant)
6731722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov      std::swap(LHS, RHS);
674ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
675ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETULE:
676ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
677ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETUGE:
6780c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // Turn lhs u>= rhs with lhs constant into rhs u< lhs+1, this allows us to
6790c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
6800c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
6810c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
6820c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
6830c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_LO;
6840c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
6850c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
6863926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_HS;    // aka COND_C
687ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
688ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETUGT:
689ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
690ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETULT:
6910c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // Turn lhs u< rhs with lhs constant into rhs u>= lhs+1, this allows us to
6920c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
6930c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
6940c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
6950c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
6960c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_HS;
6970c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
6980c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
6993926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_LO;    // aka COND_NC
700ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
701ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETLE:
702ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
703ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETGE:
7040c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // Turn lhs >= rhs with lhs constant into rhs < lhs+1, this allows us to
7050c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
7060c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
7070c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
7080c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
7090c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_L;
7100c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
7110c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
7123926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_GE;
713ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
714ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETGT:
715ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
716ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETLT:
7170c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to
7180c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
7190c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
7200c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
7210c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
7220c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_GE;
7230c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
7240c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
7253926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_L;
726ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
727ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  }
728ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
7293926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  TargetCC = DAG.getConstant(TCC, MVT::i8);
730825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  return DAG.getNode(MSP430ISD::CMP, dl, MVT::Flag, LHS, RHS);
731ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov}
732ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
7331bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
7341bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton KorobeynikovSDValue MSP430TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) {
735ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  SDValue Chain = Op.getOperand(0);
7361bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
7371bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue LHS   = Op.getOperand(2);
7381bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue RHS   = Op.getOperand(3);
7391bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue Dest  = Op.getOperand(4);
7401bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  DebugLoc dl   = Op.getDebugLoc();
7411bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
7423926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  SDValue TargetCC;
7431bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
7441bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
7451bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(),
7463926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov                     Chain, Dest, TargetCC, Flag);
747ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov}
748ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
7498d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov
7508d1ffbd1adad453fe330be4951400bfd25fab666Anton KorobeynikovSDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
7518d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue LHS   = Op.getOperand(0);
7528d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue RHS   = Op.getOperand(1);
7538d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  DebugLoc dl   = Op.getDebugLoc();
7548d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov
7558d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // If we are doing an AND and testing against zero, then the CMP
7568d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // will not be generated.  The AND (or BIT) will generate the condition codes,
7578d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // but they are different from CMP.
7588d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool andCC = false;
7598d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) {
7608d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    if (RHSC->isNullValue() && LHS.hasOneUse() &&
7618d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov        (LHS.getOpcode() == ISD::AND ||
7628d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov         (LHS.getOpcode() == ISD::TRUNCATE &&
7638d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov          LHS.getOperand(0).getOpcode() == ISD::AND))) {
7648d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov      andCC = true;
7658d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    }
7668d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  }
7678d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
7688d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue TargetCC;
7698d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
7708d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov
7718d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // Get the condition codes directly from the status register, if its easy.
7728d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // Otherwise a branch will be generated.  Note that the AND and BIT
7738d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // instructions generate different flags than CMP, the carry bit can be used
7748d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // for NE/EQ.
7758d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool Invert = false;
7768d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool Shift = false;
7778d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool Convert = true;
7788d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  switch (cast<ConstantSDNode>(TargetCC)->getZExtValue()) {
7798d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov   default:
7808d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Convert = false;
7818d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    break;
7828d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov   case MSP430CC::COND_HS:
7838d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     // Res = SRW & 1, no processing is required
7848d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
7858d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    case MSP430CC::COND_LO:
7868d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     // Res = ~(SRW & 1)
7878d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     Invert = true;
7888d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
7898d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    case MSP430CC::COND_NE:
7908d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     if (andCC) {
7918d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov       // C = ~Z, thus Res = SRW & 1, no processing is required
7928d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     } else {
7938d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov       // Res = (SRW >> 1) & 1
7948d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov       Shift = true;
7958d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     }
7968d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
7978d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    case MSP430CC::COND_E:
7988d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     if (andCC) {
7998d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov       // C = ~Z, thus Res = ~(SRW & 1)
8008d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     } else {
8018d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov       // Res = ~((SRW >> 1) & 1)
8028d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov       Shift = true;
8038d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     }
8048d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     Invert = true;
8058d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
8068d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  }
8078d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  EVT VT = Op.getValueType();
8088d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue One  = DAG.getConstant(1, VT);
8098d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  if (Convert) {
8108d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SRW,
8118d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov                                     MVT::i16, Flag);
8128d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    if (Shift)
8138d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov      // FIXME: somewhere this is turned into a SRL, lower it MSP specific?
8148d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov      SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One);
8158d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    SR = DAG.getNode(ISD::AND, dl, MVT::i16, SR, One);
8168d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    if (Invert)
8178d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov      SR = DAG.getNode(ISD::XOR, dl, MVT::i16, SR, One);
8188d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    return SR;
8198d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  } else {
8208d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    SDValue Zero = DAG.getConstant(0, VT);
8218d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Flag);
8228d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    SmallVector<SDValue, 4> Ops;
8238d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Ops.push_back(One);
8248d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Ops.push_back(Zero);
8258d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Ops.push_back(TargetCC);
8268d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Ops.push_back(Flag);
8278d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size());
8288d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  }
8298d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov}
8308d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov
8311bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton KorobeynikovSDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) {
8321bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue LHS    = Op.getOperand(0);
8331bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue RHS    = Op.getOperand(1);
8341bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue TrueV  = Op.getOperand(2);
8351bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue FalseV = Op.getOperand(3);
8361bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
8378b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  DebugLoc dl    = Op.getDebugLoc();
8381bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
8393926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  SDValue TargetCC;
8401bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
8418b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
842825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Flag);
8438b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  SmallVector<SDValue, 4> Ops;
8448b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  Ops.push_back(TrueV);
8458b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  Ops.push_back(FalseV);
8463926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  Ops.push_back(TargetCC);
8471bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  Ops.push_back(Flag);
8488b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
8491bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size());
8508b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov}
8518b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
852b78e214274d397407b6167a293b7cd7c3b526ddeAnton KorobeynikovSDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op,
853b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov                                               SelectionDAG &DAG) {
854b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  SDValue Val = Op.getOperand(0);
855e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT      = Op.getValueType();
856b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  DebugLoc dl = Op.getDebugLoc();
857b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov
858825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  assert(VT == MVT::i16 && "Only support i16 for now!");
859b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov
860b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT,
861b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov                     DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val),
862b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov                     DAG.getValueType(Val.getValueType()));
863b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov}
864b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov
86506ccca5f70ef5f9c3e4add60b6fc842916705029Anton KorobeynikovSDValue MSP430TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) {
86606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MachineFunction &MF = DAG.getMachineFunction();
86706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
86806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  int ReturnAddrIndex = FuncInfo->getRAIndex();
86906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
87006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  if (ReturnAddrIndex == 0) {
87106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    // Set up a frame object for the return address.
87206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    uint64_t SlotSize = TD->getPointerSize();
87306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(SlotSize, -SlotSize,
87406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                                                           true, false);
87506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    FuncInfo->setRAIndex(ReturnAddrIndex);
87606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  }
87706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
87806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy());
87906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov}
88006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
88106ccca5f70ef5f9c3e4add60b6fc842916705029Anton KorobeynikovSDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) {
88206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
88306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  DebugLoc dl = Op.getDebugLoc();
88406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
88506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  if (Depth > 0) {
88606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
88706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    SDValue Offset =
88806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov      DAG.getConstant(TD->getPointerSize(), MVT::i16);
88906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
89006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                       DAG.getNode(ISD::ADD, dl, getPointerTy(),
89106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                                   FrameAddr, Offset),
89206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                       NULL, 0);
89306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  }
89406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
89506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  // Just load the return address.
89606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  SDValue RetAddrFI = getReturnAddressFrameIndex(DAG);
89706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
89806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                     RetAddrFI, NULL, 0);
89906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov}
90006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
90106ccca5f70ef5f9c3e4add60b6fc842916705029Anton KorobeynikovSDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
90206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
90306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MFI->setFrameAddressIsTaken(true);
90406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  EVT VT = Op.getValueType();
90506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  DebugLoc dl = Op.getDebugLoc();  // FIXME probably not meaningful
90606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
90706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl,
90806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                                         MSP430::FPW, VT);
90906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  while (Depth--)
91006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr, NULL, 0);
91106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  return FrameAddr;
91206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov}
91306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
9146534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// getPostIndexedAddressParts - returns true by value, base pointer and
9156534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// offset pointer and addressing mode by reference if this node can be
9166534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// combined with a load / store to form a post-indexed load / store.
9176534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikovbool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
9186534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      SDValue &Base,
9196534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      SDValue &Offset,
9206534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      ISD::MemIndexedMode &AM,
9216534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      SelectionDAG &DAG) const {
9226534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
9236534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  LoadSDNode *LD = cast<LoadSDNode>(N);
9246534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (LD->getExtensionType() != ISD::NON_EXTLOAD)
9256534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return false;
9266534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
9276534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  EVT VT = LD->getMemoryVT();
9286534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (VT != MVT::i8 && VT != MVT::i16)
9296534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return false;
9306534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
9316534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (Op->getOpcode() != ISD::ADD)
9326534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return false;
9336534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
9346534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) {
9356534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    uint64_t RHSC = RHS->getZExtValue();
9366534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    if ((VT == MVT::i16 && RHSC != 2) ||
9376534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov        (VT == MVT::i8 && RHSC != 1))
9386534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov      return false;
9396534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
9406534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    Base = Op->getOperand(0);
9416534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    Offset = DAG.getConstant(RHSC, VT);
9426534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    AM = ISD::POST_INC;
9436534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return true;
9446534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  }
9456534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
9466534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  return false;
9476534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov}
9486534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
9496534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
950fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikovconst char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
951fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  switch (Opcode) {
952fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  default: return NULL;
953fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  case MSP430ISD::RET_FLAG:           return "MSP430ISD::RET_FLAG";
9546bfcba7e137113e5f38cc4f937ad61cc7253ec74Anton Korobeynikov  case MSP430ISD::RETI_FLAG:          return "MSP430ISD::RETI_FLAG";
955d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  case MSP430ISD::RRA:                return "MSP430ISD::RRA";
956e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  case MSP430ISD::RLA:                return "MSP430ISD::RLA";
957e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  case MSP430ISD::RRC:                return "MSP430ISD::RRC";
958b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov  case MSP430ISD::CALL:               return "MSP430ISD::CALL";
9593513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  case MSP430ISD::Wrapper:            return "MSP430ISD::Wrapper";
9601bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case MSP430ISD::BR_CC:              return "MSP430ISD::BR_CC";
961ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case MSP430ISD::CMP:                return "MSP430ISD::CMP";
9621bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case MSP430ISD::SELECT_CC:          return "MSP430ISD::SELECT_CC";
9632625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430ISD::SHL:                return "MSP430ISD::SHL";
9642625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430ISD::SRA:                return "MSP430ISD::SRA";
965fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  }
966fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov}
9678b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
9688b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===//
9698b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//  Other Lowering Code
9708b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===//
9718b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
9728b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMachineBasicBlock*
9732625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMSP430TargetLowering::EmitShiftInstr(MachineInstr *MI,
9742625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                                     MachineBasicBlock *BB,
9752625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                   DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const {
9762625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineFunction *F = BB->getParent();
9772625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineRegisterInfo &RI = F->getRegInfo();
9782625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  DebugLoc dl = MI->getDebugLoc();
9792625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
9802625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
9812625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned Opc;
9822625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  const TargetRegisterClass * RC;
9832625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  switch (MI->getOpcode()) {
9842625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  default:
9852625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    assert(0 && "Invalid shift opcode!");
9862625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Shl8:
9872625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SHL8r1;
9882625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   RC = MSP430::GR8RegisterClass;
9892625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
9902625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Shl16:
9912625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SHL16r1;
9922625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   RC = MSP430::GR16RegisterClass;
9932625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
9942625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Sra8:
9952625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR8r1;
9962625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   RC = MSP430::GR8RegisterClass;
9972625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
9982625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Sra16:
9992625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR16r1;
10002625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   RC = MSP430::GR16RegisterClass;
10012625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
10022625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Srl8:
10032625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR8r1c;
10042625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   RC = MSP430::GR8RegisterClass;
10052625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
10062625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Srl16:
10072625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR16r1c;
10082625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   RC = MSP430::GR16RegisterClass;
10092625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
10102625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  }
10112625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10122625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  const BasicBlock *LLVM_BB = BB->getBasicBlock();
10132625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineFunction::iterator I = BB;
10142625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  ++I;
10152625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10162625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Create loop block
10172625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB);
10182625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineBasicBlock *RemBB  = F->CreateMachineBasicBlock(LLVM_BB);
10192625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10202625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  F->insert(I, LoopBB);
10212625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  F->insert(I, RemBB);
10222625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10232625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Update machine-CFG edges by transferring all successors of the current
10242625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // block to the block containing instructions after shift.
10252625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  RemBB->transferSuccessors(BB);
10262625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10272625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Inform sdisel of the edge changes.
10282625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(),
10292625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov         SE = BB->succ_end(); SI != SE; ++SI)
10302625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    EM->insert(std::make_pair(*SI, RemBB));
10312625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10322625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Add adges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB
10332625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BB->addSuccessor(LoopBB);
10342625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BB->addSuccessor(RemBB);
10352625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  LoopBB->addSuccessor(RemBB);
10362625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  LoopBB->addSuccessor(LoopBB);
10372625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10382625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned ShiftAmtReg = RI.createVirtualRegister(MSP430::GR8RegisterClass);
10392625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned ShiftAmtReg2 = RI.createVirtualRegister(MSP430::GR8RegisterClass);
10402625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned ShiftReg = RI.createVirtualRegister(RC);
10412625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned ShiftReg2 = RI.createVirtualRegister(RC);
10422625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned ShiftAmtSrcReg = MI->getOperand(2).getReg();
10432625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned SrcReg = MI->getOperand(1).getReg();
10442625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned DstReg = MI->getOperand(0).getReg();
10452625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10462625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // BB:
10472625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // cmp 0, N
10482625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // je RemBB
1049f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov  BuildMI(BB, dl, TII.get(MSP430::CMP8ri))
1050f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    .addReg(ShiftAmtSrcReg).addImm(0);
10512625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(BB, dl, TII.get(MSP430::JCC))
10522625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addMBB(RemBB)
10532625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addImm(MSP430CC::COND_E);
10542625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10552625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // LoopBB:
10562625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB]
10572625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // ShiftAmt = phi [%N, BB],      [%ShiftAmt2, LoopBB]
10582625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // ShiftReg2 = shift ShiftReg
10592625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // ShiftAmt2 = ShiftAmt - 1;
10602625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftReg)
10612625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(SrcReg).addMBB(BB)
10622625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftReg2).addMBB(LoopBB);
10632625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg)
10642625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftAmtSrcReg).addMBB(BB)
10652625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftAmtReg2).addMBB(LoopBB);
10662625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2)
10672625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftReg);
10682625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2)
10692625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftAmtReg).addImm(1);
10702625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::JCC))
10712625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addMBB(LoopBB)
10722625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addImm(MSP430CC::COND_NE);
10732625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10742625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // RemBB:
10752625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB]
10762625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(RemBB, dl, TII.get(MSP430::PHI), DstReg)
10772625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(SrcReg).addMBB(BB)
10782625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftReg2).addMBB(LoopBB);
10792625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10805fcf52ccf34d6cb56e0bd6314aaa9a847f3a0939Anton Korobeynikov  F->DeleteMachineInstr(MI);   // The pseudo instruction is gone now.
10812625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  return RemBB;
10822625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov}
10832625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10842625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMachineBasicBlock*
10858b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
1086fb2e752e4175920d0531f2afc93a23d0cdf4db14Evan Cheng                                                  MachineBasicBlock *BB,
1087fb2e752e4175920d0531f2afc93a23d0cdf4db14Evan Cheng                   DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const {
10882625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned Opc = MI->getOpcode();
10892625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10902625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 ||
10912625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      Opc == MSP430::Sra8 || Opc == MSP430::Sra16 ||
10922625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      Opc == MSP430::Srl8 || Opc == MSP430::Srl16)
10932625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    return EmitShiftInstr(MI, BB, EM);
10942625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10958b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
10968b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  DebugLoc dl = MI->getDebugLoc();
10972625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10982625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  assert((Opc == MSP430::Select16 || Opc == MSP430::Select8) &&
10998b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov         "Unexpected instr type to insert");
11008b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
11018b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // To "insert" a SELECT instruction, we actually have to insert the diamond
11028b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // control-flow pattern.  The incoming instruction knows the destination vreg
11038b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // to set, the condition code register to branch on, the true/false values to
11048b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // select between, and a branch opcode to use.
11058b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  const BasicBlock *LLVM_BB = BB->getBasicBlock();
11068b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineFunction::iterator I = BB;
11078b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  ++I;
11088b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
11098b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  thisMBB:
11108b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  ...
11118b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   TrueVal = ...
11128b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   cmpTY ccX, r1, r2
11138b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   jCC copy1MBB
11148b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   fallthrough --> copy0MBB
11158b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineBasicBlock *thisMBB = BB;
11168b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineFunction *F = BB->getParent();
11178b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
11188b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB);
11198b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BuildMI(BB, dl, TII.get(MSP430::JCC))
11208b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addMBB(copy1MBB)
11218b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addImm(MI->getOperand(3).getImm());
11228b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  F->insert(I, copy0MBB);
11238b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  F->insert(I, copy1MBB);
1124ce31910eae5bd4896fa6c27798e7b26885691d3bEvan Cheng  // Inform sdisel of the edge changes.
1125ce31910eae5bd4896fa6c27798e7b26885691d3bEvan Cheng  for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(),
1126ce31910eae5bd4896fa6c27798e7b26885691d3bEvan Cheng         SE = BB->succ_end(); SI != SE; ++SI)
1127ce31910eae5bd4896fa6c27798e7b26885691d3bEvan Cheng    EM->insert(std::make_pair(*SI, copy1MBB));
11288b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // Update machine-CFG edges by transferring all successors of the current
11298b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // block to the new block which will contain the Phi node for the select.
11308b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  copy1MBB->transferSuccessors(BB);
11318b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // Next, add the true and fallthrough blocks as its successors.
11328b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB->addSuccessor(copy0MBB);
11338b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB->addSuccessor(copy1MBB);
11348b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
11358b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  copy0MBB:
11368b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   %FalseValue = ...
11378b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   # fallthrough to copy1MBB
11388b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB = copy0MBB;
11398b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
11408b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // Update machine-CFG edges
11418b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB->addSuccessor(copy1MBB);
11428b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
11438b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  copy1MBB:
11448b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
11458b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  ...
11468b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB = copy1MBB;
11478b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BuildMI(BB, dl, TII.get(MSP430::PHI),
11488b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov          MI->getOperand(0).getReg())
11498b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB)
11508b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB);
11518b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
11528b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  F->DeleteMachineInstr(MI);   // The pseudo instruction is gone now.
11538b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  return BB;
11548b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov}
1155