MSP430ISelLowering.cpp revision 06ccca5f70ef5f9c3e4add60b6fc842916705029
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);
118825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SETCC,            MVT::i8,    Expand);
119825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SETCC,            MVT::i16,   Expand);
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);
1861bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case ISD::BR_CC:            return LowerBR_CC(Op, DAG);
1871bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case ISD::SELECT_CC:        return LowerSELECT_CC(Op, DAG);
188b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  case ISD::SIGN_EXTEND:      return LowerSIGN_EXTEND(Op, DAG);
18906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  case ISD::RETURNADDR:       return LowerRETURNADDR(Op, DAG);
19006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  case ISD::FRAMEADDR:        return LowerFRAMEADDR(Op, DAG);
191f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  default:
192c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("unimplemented operand");
193f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov    return SDValue();
194f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  }
195f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
196f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
197b4202b84d7e54efe5e144885c7da63e6cc465f80Bill Wendling/// getFunctionAlignment - Return the Log2 alignment of this function.
19820c568f366be211323eeaf0e45ef053278ec9ddcBill Wendlingunsigned MSP430TargetLowering::getFunctionAlignment(const Function *F) const {
1993741be39f98795a841a4d8c35bf54928769ac3cdAnton Korobeynikov  return F->hasFnAttr(Attribute::OptimizeForSize) ? 1 : 2;
20020c568f366be211323eeaf0e45ef053278ec9ddcBill Wendling}
20120c568f366be211323eeaf0e45ef053278ec9ddcBill Wendling
202c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===//
203cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//                       MSP430 Inline Assembly Support
204cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===//
205cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
206cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// getConstraintType - Given a constraint letter, return the type of
207cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// constraint it is for this target.
208cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovTargetLowering::ConstraintType
209cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering::getConstraintType(const std::string &Constraint) const {
210cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  if (Constraint.size() == 1) {
211cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    switch (Constraint[0]) {
212cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    case 'r':
213cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      return C_RegisterClass;
214cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    default:
215cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      break;
216cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    }
217cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  }
218cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  return TargetLowering::getConstraintType(Constraint);
219cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov}
220cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
221cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikovstd::pair<unsigned, const TargetRegisterClass*>
222cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering::
223cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovgetRegForInlineAsmConstraint(const std::string &Constraint,
224cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov                             EVT VT) const {
225cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  if (Constraint.size() == 1) {
226cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    // GCC Constraint Letters
227cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    switch (Constraint[0]) {
228cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    default: break;
229cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    case 'r':   // GENERAL_REGS
230cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      if (VT == MVT::i8)
231cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov        return std::make_pair(0U, MSP430::GR8RegisterClass);
232cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
233cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      return std::make_pair(0U, MSP430::GR16RegisterClass);
234cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    }
235cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  }
236cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
237cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
238cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov}
239cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
240cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===//
241c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//                      Calling Convention Implementation
242c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===//
243c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
244f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430GenCallingConv.inc"
245c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
24698ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
24798ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerFormalArguments(SDValue Chain,
24865c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                           CallingConv::ID CallConv,
24998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           bool isVarArg,
25098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           const SmallVectorImpl<ISD::InputArg>
25198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                             &Ins,
25298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           DebugLoc dl,
25398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           SelectionDAG &DAG,
25498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           SmallVectorImpl<SDValue> &InVals) {
25598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
25698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  switch (CallConv) {
257c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  default:
258c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Unsupported calling convention");
259c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  case CallingConv::C:
260c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  case CallingConv::Fast:
26198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman    return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals);
262e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  case CallingConv::MSP430_INTR:
263e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov   if (Ins.empty())
264e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov     return Chain;
265e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov   else {
266e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    llvm_report_error("ISRs cannot have arguments");
267e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    return SDValue();
268e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov   }
269c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  }
270c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov}
271c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
27298ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
27398ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
27465c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                CallingConv::ID CallConv, bool isVarArg,
27598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                bool isTailCall,
27698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                const SmallVectorImpl<ISD::OutputArg> &Outs,
27798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                const SmallVectorImpl<ISD::InputArg> &Ins,
27898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                DebugLoc dl, SelectionDAG &DAG,
27998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                SmallVectorImpl<SDValue> &InVals) {
28098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
28198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  switch (CallConv) {
2824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  default:
283c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Unsupported calling convention");
2844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  case CallingConv::Fast:
2854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  case CallingConv::C:
28698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman    return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
28798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                          Outs, Ins, dl, DAG, InVals);
288e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  case CallingConv::MSP430_INTR:
289e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    llvm_report_error("ISRs cannot be called directly");
290e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    return SDValue();
2914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
2924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov}
2934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
294c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// LowerCCCArguments - transform physical registers into virtual registers and
295c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// generate load operations for arguments places on the stack.
296c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// FIXME: struct return stuff
297c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// FIXME: varargs
29898ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
29998ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCArguments(SDValue Chain,
30065c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                        CallingConv::ID CallConv,
30198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        bool isVarArg,
30298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        const SmallVectorImpl<ISD::InputArg>
30398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                          &Ins,
30498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        DebugLoc dl,
30598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        SelectionDAG &DAG,
30698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        SmallVectorImpl<SDValue> &InVals) {
307c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  MachineFunction &MF = DAG.getMachineFunction();
308c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  MachineFrameInfo *MFI = MF.getFrameInfo();
309c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  MachineRegisterInfo &RegInfo = MF.getRegInfo();
310c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
311c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  // Assign locations to all of the incoming arguments.
312c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  SmallVector<CCValAssign, 16> ArgLocs;
31398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCState CCInfo(CallConv, isVarArg, getTargetMachine(),
31498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                 ArgLocs, *DAG.getContext());
31598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCInfo.AnalyzeFormalArguments(Ins, CC_MSP430);
316c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
317c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  assert(!isVarArg && "Varargs not supported yet");
318c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
319c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
320c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    CCValAssign &VA = ArgLocs[i];
321c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    if (VA.isRegLoc()) {
322c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      // Arguments passed in registers
323e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson      EVT RegVT = VA.getLocVT();
324825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      switch (RegVT.getSimpleVT().SimpleTy) {
325804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin      default:
326804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin        {
327dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#ifndef NDEBUG
3284437ae213d5435390f0750213b53ec807c047f22Chris Lattner          errs() << "LowerFormalArguments Unhandled argument type: "
329825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson               << RegVT.getSimpleVT().SimpleTy << "\n";
330dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#endif
331c23197a26f34f559ea9797de51e187087c039c42Torok Edwin          llvm_unreachable(0);
332804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin        }
333825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      case MVT::i16:
334c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        unsigned VReg =
3351df221f2bb8e8380e255d1bec73ab07b388d01a2Anton Korobeynikov          RegInfo.createVirtualRegister(MSP430::GR16RegisterClass);
336c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        RegInfo.addLiveIn(VA.getLocReg(), VReg);
33798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman        SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, RegVT);
338c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
339c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        // If this is an 8-bit value, it is really passed promoted to 16
340c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        // bits. Insert an assert[sz]ext to capture this, then truncate to the
341c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        // right size.
342c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        if (VA.getLocInfo() == CCValAssign::SExt)
343c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov          ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue,
344c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov                                 DAG.getValueType(VA.getValVT()));
345c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        else if (VA.getLocInfo() == CCValAssign::ZExt)
346c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov          ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue,
347c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov                                 DAG.getValueType(VA.getValVT()));
348c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
349c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        if (VA.getLocInfo() != CCValAssign::Full)
350c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov          ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
351c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
35298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman        InVals.push_back(ArgValue);
353c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      }
354c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    } else {
355c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      // Sanity check
356c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      assert(VA.isMemLoc());
357c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      // Load the argument to a virtual register
358c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      unsigned ObjSize = VA.getLocVT().getSizeInBits()/8;
359c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      if (ObjSize > 2) {
3604437ae213d5435390f0750213b53ec807c047f22Chris Lattner        errs() << "LowerFormalArguments Unhandled argument type: "
361825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson             << VA.getLocVT().getSimpleVT().SimpleTy
362c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov             << "\n";
363c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      }
364c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      // Create the frame index object for this incoming parameter...
3653f2bf85d14759cc4b28a86805f566ac805a54d00David Greene      int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true, false);
366c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
367c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      // Create the SelectionDAG nodes corresponding to a load
368c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      //from this parameter
369825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      SDValue FIN = DAG.getFrameIndex(FI, MVT::i16);
37098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman      InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN,
3716553155172a2e74feff1253837daa608123de54aEvan Cheng                                   PseudoSourceValue::getFixedStack(FI), 0));
372c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    }
373c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  }
374c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
37598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return Chain;
376c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov}
377fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
37898ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
37998ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerReturn(SDValue Chain,
38065c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                  CallingConv::ID CallConv, bool isVarArg,
38198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                  const SmallVectorImpl<ISD::OutputArg> &Outs,
38298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                  DebugLoc dl, SelectionDAG &DAG) {
38398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
384fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // CCValAssign - represent the assignment of the return value to a location
385fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  SmallVector<CCValAssign, 16> RVLocs;
386fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
387e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  // ISRs cannot return any value.
388e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  if (CallConv == CallingConv::MSP430_INTR && !Outs.empty()) {
389e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    llvm_report_error("ISRs cannot return any value");
390e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    return SDValue();
391e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  }
392e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov
393fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // CCState - Info about the registers and stack slot.
39498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCState CCInfo(CallConv, isVarArg, getTargetMachine(),
39598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                 RVLocs, *DAG.getContext());
396fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
39798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  // Analize return values.
39898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCInfo.AnalyzeReturn(Outs, RetCC_MSP430);
399fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
400fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // If this is the first return lowered for this function, add the regs to the
401fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // liveout set for the function.
402fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
403fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    for (unsigned i = 0; i != RVLocs.size(); ++i)
404fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov      if (RVLocs[i].isRegLoc())
405fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov        DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
406fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  }
407fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
408fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  SDValue Flag;
409fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
410fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // Copy the result values into the output registers.
411fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  for (unsigned i = 0; i != RVLocs.size(); ++i) {
412fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    CCValAssign &VA = RVLocs[i];
413fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    assert(VA.isRegLoc() && "Can only return in registers!");
414fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
415fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
41698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                             Outs[i].Val, Flag);
417fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
418dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov    // Guarantee that all emitted copies are stuck together,
419dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov    // avoiding something bad.
420fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    Flag = Chain.getValue(1);
421fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  }
422fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
423e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  unsigned Opc = (CallConv == CallingConv::MSP430_INTR ?
424e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov                  MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG);
425e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov
426fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  if (Flag.getNode())
427e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    return DAG.getNode(Opc, dl, MVT::Other, Chain, Flag);
428fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
429fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // Return Void
430e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  return DAG.getNode(Opc, dl, MVT::Other, Chain);
431fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov}
432fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
4334428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// LowerCCCCallTo - functions arguments are copied from virtual regs to
4344428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
4354428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// TODO: sret.
43698ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
43798ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee,
43865c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                     CallingConv::ID CallConv, bool isVarArg,
43998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     bool isTailCall,
44098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     const SmallVectorImpl<ISD::OutputArg>
44198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                       &Outs,
44298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     const SmallVectorImpl<ISD::InputArg> &Ins,
44398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     DebugLoc dl, SelectionDAG &DAG,
44498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     SmallVectorImpl<SDValue> &InVals) {
4454428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Analyze operands of the call, assigning locations to each operand.
4464428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<CCValAssign, 16> ArgLocs;
44798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCState CCInfo(CallConv, isVarArg, getTargetMachine(),
44898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                 ArgLocs, *DAG.getContext());
4494428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
45098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCInfo.AnalyzeCallOperands(Outs, CC_MSP430);
4514428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4524428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Get a count of how many bytes are to be pushed on the stack.
4534428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  unsigned NumBytes = CCInfo.getNextStackOffset();
4544428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4554428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Chain = DAG.getCALLSEQ_START(Chain ,DAG.getConstant(NumBytes,
4564428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                                      getPointerTy(), true));
4574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4584428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass;
4594428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<SDValue, 12> MemOpChains;
4604428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SDValue StackPtr;
4614428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4624428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Walk the register/memloc assignments, inserting copies/loads.
4634428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
4644428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    CCValAssign &VA = ArgLocs[i];
4654428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
46698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman    SDValue Arg = Outs[i].Val;
4674428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4684428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    // Promote the value if needed.
4694428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    switch (VA.getLocInfo()) {
470c23197a26f34f559ea9797de51e187087c039c42Torok Edwin      default: llvm_unreachable("Unknown loc info!");
4714428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::Full: break;
4724428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::SExt:
4734428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
4744428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        break;
4754428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::ZExt:
4764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
4774428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        break;
4784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::AExt:
4794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
4804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        break;
4814428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    }
4824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    // Arguments that can be passed on register must be kept at RegsToPass
4844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    // vector
4854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    if (VA.isRegLoc()) {
4864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
4874428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    } else {
4884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      assert(VA.isMemLoc());
4894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      if (StackPtr.getNode() == 0)
4914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SPW, getPointerTy());
4924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(),
4944428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                   StackPtr,
4954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                   DAG.getIntPtrConstant(VA.getLocMemOffset()));
4964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4974428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
4994428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                         PseudoSourceValue::getStack(),
5004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                         VA.getLocMemOffset()));
5014428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    }
5024428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
5034428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5044428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Transform all store nodes into one single node because all store nodes are
5054428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // independent of each other.
5064428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  if (!MemOpChains.empty())
507825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
5084428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                        &MemOpChains[0], MemOpChains.size());
5094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5104428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Build a sequence of copy-to-reg nodes chained together with token chain and
5114428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // flag operands which copy the outgoing args into registers.  The InFlag in
5124428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // necessary since all emited instructions must be stuck together.
5134428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SDValue InFlag;
5144428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
5154428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
5164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             RegsToPass[i].second, InFlag);
5174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    InFlag = Chain.getValue(1);
5184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
5194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5204428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // If the callee is a GlobalAddress node (quite common, every direct call is)
5214428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
5224428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Likewise ExternalSymbol -> TargetExternalSymbol.
5234428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
524825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    Callee = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i16);
5254428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
526825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i16);
5274428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5284428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Returns a chain & a flag for retval copy to use.
529825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
5304428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<SDValue, 8> Ops;
5314428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Ops.push_back(Chain);
5324428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Ops.push_back(Callee);
5334428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5344428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Add argument registers to the end of the list so that they are
5354428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // known live into the call.
5364428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
5374428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Ops.push_back(DAG.getRegister(RegsToPass[i].first,
5384428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                  RegsToPass[i].second.getValueType()));
5394428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5404428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  if (InFlag.getNode())
5414428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Ops.push_back(InFlag);
5424428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5434428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Chain = DAG.getNode(MSP430ISD::CALL, dl, NodeTys, &Ops[0], Ops.size());
5444428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  InFlag = Chain.getValue(1);
5454428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5464428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Create the CALLSEQ_END node.
5474428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Chain = DAG.getCALLSEQ_END(Chain,
5484428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             DAG.getConstant(NumBytes, getPointerTy(), true),
5494428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             DAG.getConstant(0, getPointerTy(), true),
5504428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             InFlag);
5514428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  InFlag = Chain.getValue(1);
5524428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5534428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Handle result values, copying them out of physregs into vregs that we
5544428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // return.
55598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl,
55698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                         DAG, InVals);
5574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov}
5584428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
55998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// LowerCallResult - Lower the result values of a call into the
56098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// appropriate copies out of appropriate physical registers.
56198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman///
56298ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
5634428885c5acfffbbdd03ad2aab23960531c47753Anton KorobeynikovMSP430TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag,
56465c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                      CallingConv::ID CallConv, bool isVarArg,
56598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                      const SmallVectorImpl<ISD::InputArg> &Ins,
56698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                      DebugLoc dl, SelectionDAG &DAG,
56798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                      SmallVectorImpl<SDValue> &InVals) {
5684428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5694428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Assign locations to each value returned by this call.
5704428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<CCValAssign, 16> RVLocs;
57198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCState CCInfo(CallConv, isVarArg, getTargetMachine(),
572e922c0201916e0b980ab3cfe91e1413e68d55647Owen Anderson                 RVLocs, *DAG.getContext());
5734428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
57498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCInfo.AnalyzeCallResult(Ins, RetCC_MSP430);
5754428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Copy all of the result registers out of their specified physreg.
5774428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0; i != RVLocs.size(); ++i) {
5784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(),
5794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                               RVLocs[i].getValVT(), InFlag).getValue(1);
5804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    InFlag = Chain.getValue(2);
58198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman    InVals.push_back(Chain.getValue(0));
5824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
5834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
58498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return Chain;
5854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov}
5864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
587d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton KorobeynikovSDValue MSP430TargetLowering::LowerShifts(SDValue Op,
588d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov                                          SelectionDAG &DAG) {
589ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov  unsigned Opc = Op.getOpcode();
590d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  SDNode* N = Op.getNode();
591e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = Op.getValueType();
592d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  DebugLoc dl = N->getDebugLoc();
593d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
594ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov  // We currently only lower shifts of constant argument.
595d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  if (!isa<ConstantSDNode>(N->getOperand(1)))
596d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov    return SDValue();
597d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
598d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
599d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
600d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  // Expand the stuff into sequence of shifts.
601d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  // FIXME: for some shift amounts this might be done better!
602d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N
603d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  SDValue Victim = N->getOperand(0);
604e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov
605e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  if (Opc == ISD::SRL && ShiftAmount) {
606e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov    // Emit a special goodness here:
607e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov    // srl A, 1 => clrc; rrc A
608bf8ef3f29de28529b5d65970af9015c41f7c809bAnton Korobeynikov    Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim);
609e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov    ShiftAmount -= 1;
610e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  }
611e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov
612d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  while (ShiftAmount--)
613aceb620de855485a4fb2eed343d880d76f6c701cAnton Korobeynikov    Victim = DAG.getNode((Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA),
614ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov                         dl, VT, Victim);
615d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
616d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  return Victim;
617d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov}
618d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
6193513ca81c6beda087a281a66f1b0e612879c0aadAnton KorobeynikovSDValue MSP430TargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) {
6203513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
6213513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();
6223513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov
6233513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  // Create the TargetGlobalAddress node, folding in the constant offset.
6243513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  SDValue Result = DAG.getTargetGlobalAddress(GV, getPointerTy(), Offset);
6253513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  return DAG.getNode(MSP430ISD::Wrapper, Op.getDebugLoc(),
6263513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov                     getPointerTy(), Result);
6273513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov}
6283513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov
6295d59f68ade7573175f1ace09061a94286e59076bAnton KorobeynikovSDValue MSP430TargetLowering::LowerExternalSymbol(SDValue Op,
6305d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov                                                  SelectionDAG &DAG) {
6315d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  DebugLoc dl = Op.getDebugLoc();
6325d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol();
6335d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  SDValue Result = DAG.getTargetExternalSymbol(Sym, getPointerTy());
6345d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov
6355d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result);;
6365d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov}
6375d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov
6383926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikovstatic SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC,
6391bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov                       ISD::CondCode CC,
6401bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov                       DebugLoc dl, SelectionDAG &DAG) {
641ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  // FIXME: Handle bittests someday
642ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet");
643ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
644ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  // FIXME: Handle jump negative someday
6453926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  MSP430CC::CondCodes TCC = MSP430CC::COND_INVALID;
646ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  switch (CC) {
647c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Invalid integer condition!");
648ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETEQ:
6493926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_E;     // aka COND_Z
6501722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov    // Minor optimization: if RHS is a constant, swap operands, then the
6511722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov    // constant can be folded into comparison.
6521722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov    if (RHS.getOpcode() == ISD::Constant)
6531722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov      std::swap(LHS, RHS);
654ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
655ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETNE:
6563926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_NE;    // aka COND_NZ
6571722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov    // Minor optimization: if RHS is a constant, swap operands, then the
6581722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov    // constant can be folded into comparison.
6591722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov    if (RHS.getOpcode() == ISD::Constant)
6601722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov      std::swap(LHS, RHS);
661ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
662ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETULE:
663ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
664ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETUGE:
6653926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_HS;    // aka COND_C
666ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
667ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETUGT:
668ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
669ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETULT:
6703926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_LO;    // aka COND_NC
671ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
672ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETLE:
673ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
674ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETGE:
6753926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_GE;
676ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
677ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETGT:
678ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
679ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETLT:
6803926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_L;
681ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
682ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  }
683ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
6843926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  TargetCC = DAG.getConstant(TCC, MVT::i8);
685825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  return DAG.getNode(MSP430ISD::CMP, dl, MVT::Flag, LHS, RHS);
686ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov}
687ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
6881bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
6891bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton KorobeynikovSDValue MSP430TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) {
690ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  SDValue Chain = Op.getOperand(0);
6911bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
6921bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue LHS   = Op.getOperand(2);
6931bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue RHS   = Op.getOperand(3);
6941bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue Dest  = Op.getOperand(4);
6951bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  DebugLoc dl   = Op.getDebugLoc();
6961bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
6973926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  SDValue TargetCC;
6981bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
6991bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
7001bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(),
7013926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov                     Chain, Dest, TargetCC, Flag);
702ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov}
703ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
7041bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton KorobeynikovSDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) {
7051bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue LHS    = Op.getOperand(0);
7061bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue RHS    = Op.getOperand(1);
7071bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue TrueV  = Op.getOperand(2);
7081bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue FalseV = Op.getOperand(3);
7091bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
7108b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  DebugLoc dl    = Op.getDebugLoc();
7111bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
7123926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  SDValue TargetCC;
7131bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
7148b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
715825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Flag);
7168b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  SmallVector<SDValue, 4> Ops;
7178b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  Ops.push_back(TrueV);
7188b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  Ops.push_back(FalseV);
7193926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  Ops.push_back(TargetCC);
7201bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  Ops.push_back(Flag);
7218b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
7221bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size());
7238b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov}
7248b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
725b78e214274d397407b6167a293b7cd7c3b526ddeAnton KorobeynikovSDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op,
726b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov                                               SelectionDAG &DAG) {
727b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  SDValue Val = Op.getOperand(0);
728e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT      = Op.getValueType();
729b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  DebugLoc dl = Op.getDebugLoc();
730b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov
731825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  assert(VT == MVT::i16 && "Only support i16 for now!");
732b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov
733b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT,
734b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov                     DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val),
735b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov                     DAG.getValueType(Val.getValueType()));
736b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov}
737b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov
73806ccca5f70ef5f9c3e4add60b6fc842916705029Anton KorobeynikovSDValue MSP430TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) {
73906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MachineFunction &MF = DAG.getMachineFunction();
74006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
74106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  int ReturnAddrIndex = FuncInfo->getRAIndex();
74206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
74306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  if (ReturnAddrIndex == 0) {
74406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    // Set up a frame object for the return address.
74506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    uint64_t SlotSize = TD->getPointerSize();
74606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(SlotSize, -SlotSize,
74706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                                                           true, false);
74806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    FuncInfo->setRAIndex(ReturnAddrIndex);
74906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  }
75006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
75106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy());
75206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov}
75306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
75406ccca5f70ef5f9c3e4add60b6fc842916705029Anton KorobeynikovSDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) {
75506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
75606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  DebugLoc dl = Op.getDebugLoc();
75706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
75806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  if (Depth > 0) {
75906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
76006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    SDValue Offset =
76106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov      DAG.getConstant(TD->getPointerSize(), MVT::i16);
76206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
76306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                       DAG.getNode(ISD::ADD, dl, getPointerTy(),
76406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                                   FrameAddr, Offset),
76506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                       NULL, 0);
76606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  }
76706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
76806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  // Just load the return address.
76906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  SDValue RetAddrFI = getReturnAddressFrameIndex(DAG);
77006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
77106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                     RetAddrFI, NULL, 0);
77206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov}
77306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
77406ccca5f70ef5f9c3e4add60b6fc842916705029Anton KorobeynikovSDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
77506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
77606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MFI->setFrameAddressIsTaken(true);
77706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  EVT VT = Op.getValueType();
77806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  DebugLoc dl = Op.getDebugLoc();  // FIXME probably not meaningful
77906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
78006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl,
78106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                                         MSP430::FPW, VT);
78206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  while (Depth--)
78306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr, NULL, 0);
78406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  return FrameAddr;
78506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov}
78606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
7876534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// getPostIndexedAddressParts - returns true by value, base pointer and
7886534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// offset pointer and addressing mode by reference if this node can be
7896534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// combined with a load / store to form a post-indexed load / store.
7906534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikovbool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
7916534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      SDValue &Base,
7926534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      SDValue &Offset,
7936534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      ISD::MemIndexedMode &AM,
7946534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      SelectionDAG &DAG) const {
7956534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
7966534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  LoadSDNode *LD = cast<LoadSDNode>(N);
7976534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (LD->getExtensionType() != ISD::NON_EXTLOAD)
7986534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return false;
7996534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
8006534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  EVT VT = LD->getMemoryVT();
8016534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (VT != MVT::i8 && VT != MVT::i16)
8026534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return false;
8036534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
8046534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (Op->getOpcode() != ISD::ADD)
8056534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return false;
8066534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
8076534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) {
8086534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    uint64_t RHSC = RHS->getZExtValue();
8096534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    if ((VT == MVT::i16 && RHSC != 2) ||
8106534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov        (VT == MVT::i8 && RHSC != 1))
8116534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov      return false;
8126534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
8136534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    Base = Op->getOperand(0);
8146534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    Offset = DAG.getConstant(RHSC, VT);
8156534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    AM = ISD::POST_INC;
8166534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return true;
8176534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  }
8186534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
8196534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  return false;
8206534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov}
8216534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
8226534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
823fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikovconst char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
824fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  switch (Opcode) {
825fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  default: return NULL;
826fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  case MSP430ISD::RET_FLAG:           return "MSP430ISD::RET_FLAG";
827d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  case MSP430ISD::RRA:                return "MSP430ISD::RRA";
828e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  case MSP430ISD::RLA:                return "MSP430ISD::RLA";
829e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  case MSP430ISD::RRC:                return "MSP430ISD::RRC";
830b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov  case MSP430ISD::CALL:               return "MSP430ISD::CALL";
8313513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  case MSP430ISD::Wrapper:            return "MSP430ISD::Wrapper";
8321bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case MSP430ISD::BR_CC:              return "MSP430ISD::BR_CC";
833ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case MSP430ISD::CMP:                return "MSP430ISD::CMP";
8341bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case MSP430ISD::SELECT_CC:          return "MSP430ISD::SELECT_CC";
835fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  }
836fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov}
8378b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
8388b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===//
8398b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//  Other Lowering Code
8408b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===//
8418b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
8428b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMachineBasicBlock*
8438b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
844fb2e752e4175920d0531f2afc93a23d0cdf4db14Evan Cheng                                                  MachineBasicBlock *BB,
845fb2e752e4175920d0531f2afc93a23d0cdf4db14Evan Cheng                   DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const {
8468b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
8478b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  DebugLoc dl = MI->getDebugLoc();
848da4d2f63d8b138569ec732d970bb452a0403a3abAnton Korobeynikov  assert((MI->getOpcode() == MSP430::Select16 ||
849da4d2f63d8b138569ec732d970bb452a0403a3abAnton Korobeynikov          MI->getOpcode() == MSP430::Select8) &&
8508b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov         "Unexpected instr type to insert");
8518b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
8528b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // To "insert" a SELECT instruction, we actually have to insert the diamond
8538b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // control-flow pattern.  The incoming instruction knows the destination vreg
8548b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // to set, the condition code register to branch on, the true/false values to
8558b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // select between, and a branch opcode to use.
8568b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  const BasicBlock *LLVM_BB = BB->getBasicBlock();
8578b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineFunction::iterator I = BB;
8588b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  ++I;
8598b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
8608b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  thisMBB:
8618b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  ...
8628b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   TrueVal = ...
8638b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   cmpTY ccX, r1, r2
8648b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   jCC copy1MBB
8658b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   fallthrough --> copy0MBB
8668b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineBasicBlock *thisMBB = BB;
8678b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineFunction *F = BB->getParent();
8688b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
8698b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB);
8708b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BuildMI(BB, dl, TII.get(MSP430::JCC))
8718b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addMBB(copy1MBB)
8728b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addImm(MI->getOperand(3).getImm());
8738b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  F->insert(I, copy0MBB);
8748b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  F->insert(I, copy1MBB);
875ce31910eae5bd4896fa6c27798e7b26885691d3bEvan Cheng  // Inform sdisel of the edge changes.
876ce31910eae5bd4896fa6c27798e7b26885691d3bEvan Cheng  for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(),
877ce31910eae5bd4896fa6c27798e7b26885691d3bEvan Cheng         SE = BB->succ_end(); SI != SE; ++SI)
878ce31910eae5bd4896fa6c27798e7b26885691d3bEvan Cheng    EM->insert(std::make_pair(*SI, copy1MBB));
8798b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // Update machine-CFG edges by transferring all successors of the current
8808b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // block to the new block which will contain the Phi node for the select.
8818b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  copy1MBB->transferSuccessors(BB);
8828b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // Next, add the true and fallthrough blocks as its successors.
8838b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB->addSuccessor(copy0MBB);
8848b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB->addSuccessor(copy1MBB);
8858b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
8868b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  copy0MBB:
8878b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   %FalseValue = ...
8888b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   # fallthrough to copy1MBB
8898b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB = copy0MBB;
8908b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
8918b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // Update machine-CFG edges
8928b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB->addSuccessor(copy1MBB);
8938b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
8948b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  copy1MBB:
8958b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
8968b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  ...
8978b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB = copy1MBB;
8988b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BuildMI(BB, dl, TII.get(MSP430::PHI),
8998b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov          MI->getOperand(0).getReg())
9008b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB)
9018b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB);
9028b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
9038b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  F->DeleteMachineInstr(MI);   // The pseudo instruction is gone now.
9048b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  return BB;
9058b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov}
906