MSP430ISelLowering.cpp revision a7542d5f870c5d98960d1676e23ac1d1d975d7e5
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"
32f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/SelectionDAGISel.h"
33362dd0bef5437f85586c046bc53287b6fbe9c099Anton Korobeynikov#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
34f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/ValueTypes.h"
35b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov#include "llvm/Support/CommandLine.h"
36f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/Support/Debug.h"
37804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin#include "llvm/Support/ErrorHandling.h"
384437ae213d5435390f0750213b53ec807c047f22Chris Lattner#include "llvm/Support/raw_ostream.h"
39f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovusing namespace llvm;
40f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
41b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikovtypedef enum {
42b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  NoHWMult,
43b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  HWMultIntr,
44b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  HWMultNoIntr
45b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov} HWMultUseMode;
46b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov
47b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikovstatic cl::opt<HWMultUseMode>
48b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton KorobeynikovHWMultMode("msp430-hwmult-mode",
49b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov           cl::desc("Hardware multiplier use mode"),
50b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov           cl::init(HWMultNoIntr),
51b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov           cl::values(
52b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov             clEnumValN(NoHWMult, "no",
53b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov                "Do not use hardware multiplier"),
54b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov             clEnumValN(HWMultIntr, "interrupts",
55b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov                "Assume hardware multiplier can be used inside interrupts"),
56b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov             clEnumValN(HWMultNoIntr, "use",
57b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov                "Assume hardware multiplier cannot be used inside interrupts"),
58b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov             clEnumValEnd));
59b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov
60f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovMSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) :
61f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner  TargetLowering(tm, new TargetLoweringObjectFileELF()),
62a7542d5f870c5d98960d1676e23ac1d1d975d7e5Benjamin Kramer  Subtarget(*tm.getSubtargetImpl()) {
63f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
6406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  TD = getTargetData();
6506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
66f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  // Set up the register classes.
67420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper  addRegisterClass(MVT::i8,  &MSP430::GR8RegClass);
68420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper  addRegisterClass(MVT::i16, &MSP430::GR16RegClass);
69f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
70f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  // Compute derived properties from the register classes
71f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  computeRegisterProperties();
72fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
731476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov  // Provide all sorts of operation actions
741476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov
751476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov  // Division is expensive
761476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov  setIntDivIsCheap(false);
771476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov
78c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov  setStackPointerRegisterToSaveRestore(MSP430::SPW);
79c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov  setBooleanContents(ZeroOrOneBooleanContent);
8028b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands  setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?
81c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov
8206ac0820a6cefa6896000054d8e4906326c0cce6Anton Korobeynikov  // We have post-incremented loads / stores.
836534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  setIndexedLoadAction(ISD::POST_INC, MVT::i8, Legal);
846534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  setIndexedLoadAction(ISD::POST_INC, MVT::i16, Legal);
856534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
866534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  setLoadExtAction(ISD::EXTLOAD,  MVT::i1,  Promote);
876534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  setLoadExtAction(ISD::SEXTLOAD, MVT::i1,  Promote);
886534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  setLoadExtAction(ISD::ZEXTLOAD, MVT::i1,  Promote);
896534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  setLoadExtAction(ISD::SEXTLOAD, MVT::i8,  Expand);
90825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Expand);
9136b6e533c1aac85452438161f7034a9f54bd1830Anton Korobeynikov
9254f30d3fc94e055f13e6744378323d05c5c050baAnton Korobeynikov  // We don't have any truncstores
93825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setTruncStoreAction(MVT::i16, MVT::i8, Expand);
94825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
95825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRA,              MVT::i8,    Custom);
96825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SHL,              MVT::i8,    Custom);
97825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRL,              MVT::i8,    Custom);
98825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRA,              MVT::i16,   Custom);
99825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SHL,              MVT::i16,   Custom);
100825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRL,              MVT::i16,   Custom);
101825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ROTL,             MVT::i8,    Expand);
102825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ROTR,             MVT::i8,    Expand);
103825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ROTL,             MVT::i16,   Expand);
104825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ROTR,             MVT::i16,   Expand);
105825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::GlobalAddress,    MVT::i16,   Custom);
106825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ExternalSymbol,   MVT::i16,   Custom);
10769d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov  setOperationAction(ISD::BlockAddress,     MVT::i16,   Custom);
108825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BR_JT,            MVT::Other, Expand);
109825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BR_CC,            MVT::i8,    Custom);
110825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BR_CC,            MVT::i16,   Custom);
111825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BRCOND,           MVT::Other, Expand);
1128d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  setOperationAction(ISD::SETCC,            MVT::i8,    Custom);
1138d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  setOperationAction(ISD::SETCC,            MVT::i16,   Custom);
114825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT,           MVT::i8,    Expand);
115825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT,           MVT::i16,   Expand);
116825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT_CC,        MVT::i8,    Custom);
117825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT_CC,        MVT::i16,   Custom);
118825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SIGN_EXTEND,      MVT::i16,   Custom);
119379a087cc7175532ff0c24c60069da5eec596879Anton Korobeynikov  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i8, Expand);
120379a087cc7175532ff0c24c60069da5eec596879Anton Korobeynikov  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i16, Expand);
121825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
122825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTTZ,             MVT::i8,    Expand);
123825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTTZ,             MVT::i16,   Expand);
12463974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth  setOperationAction(ISD::CTTZ_ZERO_UNDEF,  MVT::i8,    Expand);
12563974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth  setOperationAction(ISD::CTTZ_ZERO_UNDEF,  MVT::i16,   Expand);
126825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTLZ,             MVT::i8,    Expand);
127825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTLZ,             MVT::i16,   Expand);
12863974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth  setOperationAction(ISD::CTLZ_ZERO_UNDEF,  MVT::i8,    Expand);
12963974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth  setOperationAction(ISD::CTLZ_ZERO_UNDEF,  MVT::i16,   Expand);
130825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTPOP,            MVT::i8,    Expand);
131825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTPOP,            MVT::i16,   Expand);
132825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
133825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SHL_PARTS,        MVT::i8,    Expand);
134825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SHL_PARTS,        MVT::i16,   Expand);
135825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRL_PARTS,        MVT::i8,    Expand);
136825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRL_PARTS,        MVT::i16,   Expand);
137825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRA_PARTS,        MVT::i8,    Expand);
138825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRA_PARTS,        MVT::i16,   Expand);
139825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
140825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1,   Expand);
141e4ce880dfa340bf45ddce10bb1dbe856553677b6Eli Friedman
1428725bd22bf91c29e2351a127295c19fea996e2c7Anton Korobeynikov  // FIXME: Implement efficiently multiplication by a constant
1438983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::MUL,              MVT::i8,    Expand);
1448983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::MULHS,            MVT::i8,    Expand);
1458983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::MULHU,            MVT::i8,    Expand);
1468983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::SMUL_LOHI,        MVT::i8,    Expand);
1478983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::UMUL_LOHI,        MVT::i8,    Expand);
148825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::MUL,              MVT::i16,   Expand);
149825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::MULHS,            MVT::i16,   Expand);
150825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::MULHU,            MVT::i16,   Expand);
151825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SMUL_LOHI,        MVT::i16,   Expand);
152825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::UMUL_LOHI,        MVT::i16,   Expand);
153825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
1548983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::UDIV,             MVT::i8,    Expand);
1558983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::UDIVREM,          MVT::i8,    Expand);
1568983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::UREM,             MVT::i8,    Expand);
1578983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::SDIV,             MVT::i8,    Expand);
1588983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::SDIVREM,          MVT::i8,    Expand);
1598983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::SREM,             MVT::i8,    Expand);
160825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::UDIV,             MVT::i16,   Expand);
161825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::UDIVREM,          MVT::i16,   Expand);
162825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::UREM,             MVT::i16,   Expand);
163825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SDIV,             MVT::i16,   Expand);
164825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SDIVREM,          MVT::i16,   Expand);
165825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SREM,             MVT::i16,   Expand);
166b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov
167b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  // Libcalls names.
168b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  if (HWMultMode == HWMultIntr) {
169b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I8,  "__mulqi3hw");
170b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I16, "__mulhi3hw");
171b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  } else if (HWMultMode == HWMultNoIntr) {
172b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I8,  "__mulqi3hw_noint");
173b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I16, "__mulhi3hw_noint");
174b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  }
175fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman
176fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman  setMinFunctionAlignment(1);
177fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman  setPrefFunctionAlignment(2);
178f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
179f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
180d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerOperation(SDValue Op,
181d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                             SelectionDAG &DAG) const {
182f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  switch (Op.getOpcode()) {
183ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov  case ISD::SHL: // FALLTHROUGH
184e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  case ISD::SRL:
1854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  case ISD::SRA:              return LowerShifts(Op, DAG);
1863513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  case ISD::GlobalAddress:    return LowerGlobalAddress(Op, DAG);
18769d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov  case ISD::BlockAddress:     return LowerBlockAddress(Op, DAG);
1885d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  case ISD::ExternalSymbol:   return LowerExternalSymbol(Op, DAG);
1898d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  case ISD::SETCC:            return LowerSETCC(Op, DAG);
1901bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case ISD::BR_CC:            return LowerBR_CC(Op, DAG);
1911bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case ISD::SELECT_CC:        return LowerSELECT_CC(Op, DAG);
192b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  case ISD::SIGN_EXTEND:      return LowerSIGN_EXTEND(Op, DAG);
19306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  case ISD::RETURNADDR:       return LowerRETURNADDR(Op, DAG);
19406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  case ISD::FRAMEADDR:        return LowerFRAMEADDR(Op, DAG);
195f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  default:
196c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("unimplemented operand");
197f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  }
198f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
199f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
200c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===//
201cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//                       MSP430 Inline Assembly Support
202cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===//
203cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
204cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// getConstraintType - Given a constraint letter, return the type of
205cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// constraint it is for this target.
206cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovTargetLowering::ConstraintType
207cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering::getConstraintType(const std::string &Constraint) const {
208cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  if (Constraint.size() == 1) {
209cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    switch (Constraint[0]) {
210cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    case 'r':
211cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      return C_RegisterClass;
212cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    default:
213cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      break;
214cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    }
215cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  }
216cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  return TargetLowering::getConstraintType(Constraint);
217cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov}
218cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
219cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikovstd::pair<unsigned, const TargetRegisterClass*>
220cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering::
221cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovgetRegForInlineAsmConstraint(const std::string &Constraint,
222cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov                             EVT VT) const {
223cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  if (Constraint.size() == 1) {
224cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    // GCC Constraint Letters
225cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    switch (Constraint[0]) {
226cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    default: break;
227cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    case 'r':   // GENERAL_REGS
228cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      if (VT == MVT::i8)
229420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper        return std::make_pair(0U, &MSP430::GR8RegClass);
230cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
231420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper      return std::make_pair(0U, &MSP430::GR16RegClass);
232cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    }
233cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  }
234cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
235cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
236cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov}
237cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
238cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===//
239c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//                      Calling Convention Implementation
240c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===//
241c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
242f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430GenCallingConv.inc"
243c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
24498ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
24598ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerFormalArguments(SDValue Chain,
24665c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                           CallingConv::ID CallConv,
24798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           bool isVarArg,
24898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           const SmallVectorImpl<ISD::InputArg>
24998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                             &Ins,
25098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           DebugLoc dl,
25198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           SelectionDAG &DAG,
252d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                           SmallVectorImpl<SDValue> &InVals)
253d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                             const {
25498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
25598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  switch (CallConv) {
256c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  default:
257c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Unsupported calling convention");
258c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  case CallingConv::C:
259c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  case CallingConv::Fast:
26098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman    return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals);
261e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  case CallingConv::MSP430_INTR:
2624d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    if (Ins.empty())
2634d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie      return Chain;
26475361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("ISRs cannot have arguments");
265c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  }
266c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov}
267c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
26898ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
269d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin HolewinskiMSP430TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
270d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                SmallVectorImpl<SDValue> &InVals) const {
271d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SelectionDAG &DAG                     = CLI.DAG;
272d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  DebugLoc &dl                          = CLI.DL;
273d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs;
274d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SmallVector<SDValue, 32> &OutVals     = CLI.OutVals;
275d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SmallVector<ISD::InputArg, 32> &Ins   = CLI.Ins;
276d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SDValue Chain                         = CLI.Chain;
277d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SDValue Callee                        = CLI.Callee;
278d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  bool &isTailCall                      = CLI.IsTailCall;
279d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  CallingConv::ID CallConv              = CLI.CallConv;
280d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  bool isVarArg                         = CLI.IsVarArg;
281d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski
2820c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng  // MSP430 target does not yet support tail call optimization.
2830c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng  isTailCall = false;
28498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
28598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  switch (CallConv) {
2864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  default:
287c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Unsupported calling convention");
2884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  case CallingConv::Fast:
2894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  case CallingConv::C:
29098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman    return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
291c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman                          Outs, OutVals, Ins, dl, DAG, InVals);
292e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  case CallingConv::MSP430_INTR:
29375361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("ISRs cannot be called directly");
2944428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
2954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov}
2964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
297c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// LowerCCCArguments - transform physical registers into virtual registers and
298c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// generate load operations for arguments places on the stack.
299c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// FIXME: struct return stuff
300c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// FIXME: varargs
30198ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
30298ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCArguments(SDValue Chain,
30365c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                        CallingConv::ID CallConv,
30498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        bool isVarArg,
30598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        const SmallVectorImpl<ISD::InputArg>
30698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                          &Ins,
30798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        DebugLoc dl,
30898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        SelectionDAG &DAG,
309d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                        SmallVectorImpl<SDValue> &InVals)
310d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                          const {
311c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  MachineFunction &MF = DAG.getMachineFunction();
312c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  MachineFrameInfo *MFI = MF.getFrameInfo();
313c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  MachineRegisterInfo &RegInfo = MF.getRegInfo();
314c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
315c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  // Assign locations to all of the incoming arguments.
316c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  SmallVector<CCValAssign, 16> ArgLocs;
317471e4224809f51652c71f319532697a879a75a0dEric Christopher  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
318471e4224809f51652c71f319532697a879a75a0dEric Christopher		 getTargetMachine(), ArgLocs, *DAG.getContext());
31998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCInfo.AnalyzeFormalArguments(Ins, CC_MSP430);
320c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
321c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  assert(!isVarArg && "Varargs not supported yet");
322c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
323c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
324c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    CCValAssign &VA = ArgLocs[i];
325c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    if (VA.isRegLoc()) {
326c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      // Arguments passed in registers
327e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson      EVT RegVT = VA.getLocVT();
328825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      switch (RegVT.getSimpleVT().SimpleTy) {
32995771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson      default:
330804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin        {
331dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#ifndef NDEBUG
3324437ae213d5435390f0750213b53ec807c047f22Chris Lattner          errs() << "LowerFormalArguments Unhandled argument type: "
333825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson               << RegVT.getSimpleVT().SimpleTy << "\n";
334dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#endif
335c23197a26f34f559ea9797de51e187087c039c42Torok Edwin          llvm_unreachable(0);
336804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin        }
337825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      case MVT::i16:
338420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper        unsigned VReg = RegInfo.createVirtualRegister(&MSP430::GR16RegClass);
339c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        RegInfo.addLiveIn(VA.getLocReg(), VReg);
34098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman        SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, RegVT);
341c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
342c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        // If this is an 8-bit value, it is really passed promoted to 16
343c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        // bits. Insert an assert[sz]ext to capture this, then truncate to the
344c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        // right size.
345c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        if (VA.getLocInfo() == CCValAssign::SExt)
346c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov          ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue,
347c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov                                 DAG.getValueType(VA.getValVT()));
348c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        else if (VA.getLocInfo() == CCValAssign::ZExt)
349c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov          ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue,
350c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov                                 DAG.getValueType(VA.getValVT()));
351c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
352c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        if (VA.getLocInfo() != CCValAssign::Full)
353c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov          ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
354c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
35598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman        InVals.push_back(ArgValue);
356c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      }
357c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    } else {
358c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      // Sanity check
359c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      assert(VA.isMemLoc());
360c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      // Load the argument to a virtual register
361c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      unsigned ObjSize = VA.getLocVT().getSizeInBits()/8;
362c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      if (ObjSize > 2) {
3634437ae213d5435390f0750213b53ec807c047f22Chris Lattner        errs() << "LowerFormalArguments Unhandled argument type: "
3641440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands             << EVT(VA.getLocVT()).getEVTString()
365c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov             << "\n";
366c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      }
367c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      // Create the frame index object for this incoming parameter...
368ed2ae136d29dd36122d2476801e7d7a86e8301e3Evan Cheng      int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);
369c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
370c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      // Create the SelectionDAG nodes corresponding to a load
371c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      //from this parameter
372825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      SDValue FIN = DAG.getFrameIndex(FI, MVT::i16);
37398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman      InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN,
374d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner                                   MachinePointerInfo::getFixedStack(FI),
375d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                                   false, false, false, 0));
376c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    }
377c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  }
378c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
37998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return Chain;
380c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov}
381fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
38298ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
38398ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerReturn(SDValue Chain,
38465c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                  CallingConv::ID CallConv, bool isVarArg,
38598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                  const SmallVectorImpl<ISD::OutputArg> &Outs,
386c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman                                  const SmallVectorImpl<SDValue> &OutVals,
387d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                  DebugLoc dl, SelectionDAG &DAG) const {
38898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
389fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // CCValAssign - represent the assignment of the return value to a location
390fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  SmallVector<CCValAssign, 16> RVLocs;
391fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
392e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  // ISRs cannot return any value.
3934d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  if (CallConv == CallingConv::MSP430_INTR && !Outs.empty())
39475361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("ISRs cannot return any value");
395e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov
396fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // CCState - Info about the registers and stack slot.
397471e4224809f51652c71f319532697a879a75a0dEric Christopher  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
398471e4224809f51652c71f319532697a879a75a0dEric Christopher		 getTargetMachine(), RVLocs, *DAG.getContext());
399fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
40098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  // Analize return values.
40198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCInfo.AnalyzeReturn(Outs, RetCC_MSP430);
402fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
403fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // If this is the first return lowered for this function, add the regs to the
404fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // liveout set for the function.
405fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
406fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    for (unsigned i = 0; i != RVLocs.size(); ++i)
407fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov      if (RVLocs[i].isRegLoc())
408fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov        DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
409fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  }
410fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
411fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  SDValue Flag;
412fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
413fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // Copy the result values into the output registers.
414fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  for (unsigned i = 0; i != RVLocs.size(); ++i) {
415fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    CCValAssign &VA = RVLocs[i];
416fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    assert(VA.isRegLoc() && "Can only return in registers!");
417fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
418fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
419c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman                             OutVals[i], Flag);
420fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
421dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov    // Guarantee that all emitted copies are stuck together,
422dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov    // avoiding something bad.
423fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    Flag = Chain.getValue(1);
424fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  }
425fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
426e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  unsigned Opc = (CallConv == CallingConv::MSP430_INTR ?
427e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov                  MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG);
428e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov
429fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  if (Flag.getNode())
430e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    return DAG.getNode(Opc, dl, MVT::Other, Chain, Flag);
431fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
432fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // Return Void
433e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  return DAG.getNode(Opc, dl, MVT::Other, Chain);
434fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov}
435fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
4364428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// LowerCCCCallTo - functions arguments are copied from virtual regs to
4374428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
4384428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// TODO: sret.
43998ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
44098ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee,
44165c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                     CallingConv::ID CallConv, bool isVarArg,
44298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     bool isTailCall,
44398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     const SmallVectorImpl<ISD::OutputArg>
44498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                       &Outs,
445c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman                                     const SmallVectorImpl<SDValue> &OutVals,
44698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     const SmallVectorImpl<ISD::InputArg> &Ins,
44798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     DebugLoc dl, SelectionDAG &DAG,
448d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                     SmallVectorImpl<SDValue> &InVals) const {
4494428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Analyze operands of the call, assigning locations to each operand.
4504428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<CCValAssign, 16> ArgLocs;
451471e4224809f51652c71f319532697a879a75a0dEric Christopher  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
452471e4224809f51652c71f319532697a879a75a0dEric Christopher		 getTargetMachine(), ArgLocs, *DAG.getContext());
4534428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
45498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCInfo.AnalyzeCallOperands(Outs, CC_MSP430);
4554428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4564428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Get a count of how many bytes are to be pushed on the stack.
4574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  unsigned NumBytes = CCInfo.getNextStackOffset();
4584428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4594428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Chain = DAG.getCALLSEQ_START(Chain ,DAG.getConstant(NumBytes,
4604428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                                      getPointerTy(), true));
4614428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4624428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass;
4634428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<SDValue, 12> MemOpChains;
4644428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SDValue StackPtr;
4654428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4664428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Walk the register/memloc assignments, inserting copies/loads.
4674428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
4684428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    CCValAssign &VA = ArgLocs[i];
4694428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
470c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman    SDValue Arg = OutVals[i];
4714428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4724428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    // Promote the value if needed.
4734428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    switch (VA.getLocInfo()) {
474c23197a26f34f559ea9797de51e187087c039c42Torok Edwin      default: llvm_unreachable("Unknown loc info!");
4754428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::Full: break;
4764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::SExt:
4774428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
4784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        break;
4794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::ZExt:
4804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
4814428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        break;
4824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::AExt:
4834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
4844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        break;
4854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    }
4864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4874428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    // Arguments that can be passed on register must be kept at RegsToPass
4884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    // vector
4894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    if (VA.isRegLoc()) {
4904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
4914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    } else {
4924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      assert(VA.isMemLoc());
4934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4944428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      if (StackPtr.getNode() == 0)
4954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SPW, getPointerTy());
4964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4974428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(),
4984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                   StackPtr,
4994428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                   DAG.getIntPtrConstant(VA.getLocMemOffset()));
5004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5014428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5024428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
5036229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner                                         MachinePointerInfo(),false, false, 0));
5044428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    }
5054428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
5064428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5074428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Transform all store nodes into one single node because all store nodes are
5084428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // independent of each other.
5094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  if (!MemOpChains.empty())
510825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
5114428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                        &MemOpChains[0], MemOpChains.size());
5124428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5134428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Build a sequence of copy-to-reg nodes chained together with token chain and
5144428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // flag operands which copy the outgoing args into registers.  The InFlag in
5157a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner  // necessary since all emitted instructions must be stuck together.
5164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SDValue InFlag;
5174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
5184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
5194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             RegsToPass[i].second, InFlag);
5204428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    InFlag = Chain.getValue(1);
5214428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
5224428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5234428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // If the callee is a GlobalAddress node (quite common, every direct call is)
5244428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
5254428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Likewise ExternalSymbol -> TargetExternalSymbol.
5264428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
5270d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel    Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i16);
5284428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
529825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i16);
5304428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5314428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Returns a chain & a flag for retval copy to use.
532f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner  SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
5334428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<SDValue, 8> Ops;
5344428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Ops.push_back(Chain);
5354428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Ops.push_back(Callee);
5364428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5374428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Add argument registers to the end of the list so that they are
5384428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // known live into the call.
5394428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
5404428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Ops.push_back(DAG.getRegister(RegsToPass[i].first,
5414428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                  RegsToPass[i].second.getValueType()));
5424428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5434428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  if (InFlag.getNode())
5444428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Ops.push_back(InFlag);
5454428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5464428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Chain = DAG.getNode(MSP430ISD::CALL, dl, NodeTys, &Ops[0], Ops.size());
5474428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  InFlag = Chain.getValue(1);
5484428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5494428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Create the CALLSEQ_END node.
5504428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Chain = DAG.getCALLSEQ_END(Chain,
5514428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             DAG.getConstant(NumBytes, getPointerTy(), true),
5524428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             DAG.getConstant(0, getPointerTy(), true),
5534428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             InFlag);
5544428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  InFlag = Chain.getValue(1);
5554428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5564428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Handle result values, copying them out of physregs into vregs that we
5574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // return.
55898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl,
55998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                         DAG, InVals);
5604428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov}
5614428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
56298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// LowerCallResult - Lower the result values of a call into the
56398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// appropriate copies out of appropriate physical registers.
56498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman///
56598ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
5664428885c5acfffbbdd03ad2aab23960531c47753Anton KorobeynikovMSP430TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag,
56765c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                      CallingConv::ID CallConv, bool isVarArg,
56898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                      const SmallVectorImpl<ISD::InputArg> &Ins,
56998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                      DebugLoc dl, SelectionDAG &DAG,
570d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                      SmallVectorImpl<SDValue> &InVals) const {
5714428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5724428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Assign locations to each value returned by this call.
5734428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<CCValAssign, 16> RVLocs;
574471e4224809f51652c71f319532697a879a75a0dEric Christopher  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
575471e4224809f51652c71f319532697a879a75a0dEric Christopher		 getTargetMachine(), RVLocs, *DAG.getContext());
5764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
57798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCInfo.AnalyzeCallResult(Ins, RetCC_MSP430);
5784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Copy all of the result registers out of their specified physreg.
5804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0; i != RVLocs.size(); ++i) {
5814428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(),
5824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                               RVLocs[i].getValVT(), InFlag).getValue(1);
5834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    InFlag = Chain.getValue(2);
58498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman    InVals.push_back(Chain.getValue(0));
5854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
5864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
58798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return Chain;
5884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov}
5894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
590d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton KorobeynikovSDValue MSP430TargetLowering::LowerShifts(SDValue Op,
591d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                          SelectionDAG &DAG) const {
592ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov  unsigned Opc = Op.getOpcode();
593d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  SDNode* N = Op.getNode();
594e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = Op.getValueType();
595d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  DebugLoc dl = N->getDebugLoc();
596d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
5972625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Expand non-constant shifts to loops:
598d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  if (!isa<ConstantSDNode>(N->getOperand(1)))
5992625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    switch (Opc) {
600bc2198133a1836598b54b943420748e75d5dea94Craig Topper    default: llvm_unreachable("Invalid shift opcode!");
6012625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    case ISD::SHL:
6022625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      return DAG.getNode(MSP430ISD::SHL, dl,
6032625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                         VT, N->getOperand(0), N->getOperand(1));
6042625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    case ISD::SRA:
6052625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      return DAG.getNode(MSP430ISD::SRA, dl,
6062625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                         VT, N->getOperand(0), N->getOperand(1));
6072625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    case ISD::SRL:
6082625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      return DAG.getNode(MSP430ISD::SRL, dl,
6092625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                         VT, N->getOperand(0), N->getOperand(1));
6102625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    }
611d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
612d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
613d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
614d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  // Expand the stuff into sequence of shifts.
615d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  // FIXME: for some shift amounts this might be done better!
616d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N
617d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  SDValue Victim = N->getOperand(0);
618e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov
619e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  if (Opc == ISD::SRL && ShiftAmount) {
620e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov    // Emit a special goodness here:
621e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov    // srl A, 1 => clrc; rrc A
622bf8ef3f29de28529b5d65970af9015c41f7c809bAnton Korobeynikov    Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim);
623e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov    ShiftAmount -= 1;
624e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  }
625e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov
626d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  while (ShiftAmount--)
627aceb620de855485a4fb2eed343d880d76f6c701cAnton Korobeynikov    Victim = DAG.getNode((Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA),
628ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov                         dl, VT, Victim);
629d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
630d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  return Victim;
631d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov}
632d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
633d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerGlobalAddress(SDValue Op,
634d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                                 SelectionDAG &DAG) const {
6353513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
6363513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();
6373513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov
6383513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  // Create the TargetGlobalAddress node, folding in the constant offset.
6390d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel  SDValue Result = DAG.getTargetGlobalAddress(GV, Op.getDebugLoc(),
6400d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel                                              getPointerTy(), Offset);
6413513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  return DAG.getNode(MSP430ISD::Wrapper, Op.getDebugLoc(),
6423513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov                     getPointerTy(), Result);
6433513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov}
6443513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov
6455d59f68ade7573175f1ace09061a94286e59076bAnton KorobeynikovSDValue MSP430TargetLowering::LowerExternalSymbol(SDValue Op,
646d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                                  SelectionDAG &DAG) const {
6475d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  DebugLoc dl = Op.getDebugLoc();
6485d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol();
6495d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  SDValue Result = DAG.getTargetExternalSymbol(Sym, getPointerTy());
6505d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov
65190f20044ade3712c8b0c3f4ebe47d57ad15ae6ceChad Rosier  return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result);
6525d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov}
6535d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov
65469d5b48bc31b7a443355cdf1506005804b4f63e6Anton KorobeynikovSDValue MSP430TargetLowering::LowerBlockAddress(SDValue Op,
65569d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov                                                SelectionDAG &DAG) const {
65669d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov  DebugLoc dl = Op.getDebugLoc();
65769d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov  const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
65869d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov  SDValue Result = DAG.getBlockAddress(BA, getPointerTy(), /*isTarget=*/true);
65969d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov
66090f20044ade3712c8b0c3f4ebe47d57ad15ae6ceChad Rosier  return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result);
66169d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov}
66269d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov
6633926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikovstatic SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC,
6641bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov                       ISD::CondCode CC,
6651bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov                       DebugLoc dl, SelectionDAG &DAG) {
666ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  // FIXME: Handle bittests someday
667ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet");
668ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
669ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  // FIXME: Handle jump negative someday
6703926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  MSP430CC::CondCodes TCC = MSP430CC::COND_INVALID;
671ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  switch (CC) {
672c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Invalid integer condition!");
673ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETEQ:
6743926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_E;     // aka COND_Z
675f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    // Minor optimization: if LHS is a constant, swap operands, then the
6761722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov    // constant can be folded into comparison.
677f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    if (LHS.getOpcode() == ISD::Constant)
6781722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov      std::swap(LHS, RHS);
679ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
680ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETNE:
6813926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_NE;    // aka COND_NZ
682f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    // Minor optimization: if LHS is a constant, swap operands, then the
6831722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov    // constant can be folded into comparison.
684f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    if (LHS.getOpcode() == ISD::Constant)
6851722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov      std::swap(LHS, RHS);
686ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
687ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETULE:
688ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
689ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETUGE:
6900c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // Turn lhs u>= rhs with lhs constant into rhs u< lhs+1, this allows us to
6910c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
6920c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
6930c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
6940c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
6950c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_LO;
6960c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
6970c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
6983926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_HS;    // aka COND_C
699ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
700ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETUGT:
701ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
702ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETULT:
7030c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // Turn lhs u< rhs with lhs constant into rhs u>= lhs+1, this allows us to
7040c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
7050c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
7060c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
7070c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
7080c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_HS;
7090c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
7100c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
7113926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_LO;    // aka COND_NC
712ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
713ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETLE:
714ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
715ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETGE:
7160c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // Turn lhs >= rhs with lhs constant into rhs < lhs+1, this allows us to
7170c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
7180c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
7190c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
7200c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
7210c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_L;
7220c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
7230c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
7243926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_GE;
725ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
726ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETGT:
727ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
728ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETLT:
7290c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to
7300c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
7310c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
7320c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
7330c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
7340c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_GE;
7350c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
7360c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
7373926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_L;
738ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
739ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  }
740ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
7413926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  TargetCC = DAG.getConstant(TCC, MVT::i8);
742f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner  return DAG.getNode(MSP430ISD::CMP, dl, MVT::Glue, LHS, RHS);
743ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov}
744ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
7451bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
746d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
747ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  SDValue Chain = Op.getOperand(0);
7481bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
7491bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue LHS   = Op.getOperand(2);
7501bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue RHS   = Op.getOperand(3);
7511bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue Dest  = Op.getOperand(4);
7521bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  DebugLoc dl   = Op.getDebugLoc();
7531bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
7543926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  SDValue TargetCC;
7551bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
7561bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
7571bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(),
7583926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov                     Chain, Dest, TargetCC, Flag);
759ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov}
760ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
761d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
7628d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue LHS   = Op.getOperand(0);
7638d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue RHS   = Op.getOperand(1);
7648d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  DebugLoc dl   = Op.getDebugLoc();
7658d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov
7668d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // If we are doing an AND and testing against zero, then the CMP
7678d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // will not be generated.  The AND (or BIT) will generate the condition codes,
7688d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // but they are different from CMP.
769cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov  // FIXME: since we're doing a post-processing, use a pseudoinstr here, so
770cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov  // lowering & isel wouldn't diverge.
7718d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool andCC = false;
7728d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) {
7738d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    if (RHSC->isNullValue() && LHS.hasOneUse() &&
7748d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov        (LHS.getOpcode() == ISD::AND ||
7758d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov         (LHS.getOpcode() == ISD::TRUNCATE &&
7768d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov          LHS.getOperand(0).getOpcode() == ISD::AND))) {
7778d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov      andCC = true;
7788d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    }
7798d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  }
7808d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
7818d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue TargetCC;
7828d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
7838d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov
7848d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // Get the condition codes directly from the status register, if its easy.
7858d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // Otherwise a branch will be generated.  Note that the AND and BIT
7868d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // instructions generate different flags than CMP, the carry bit can be used
7878d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // for NE/EQ.
7888d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool Invert = false;
7898d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool Shift = false;
7908d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool Convert = true;
7918d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  switch (cast<ConstantSDNode>(TargetCC)->getZExtValue()) {
7928d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov   default:
7938d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Convert = false;
7948d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    break;
7958d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov   case MSP430CC::COND_HS:
7968d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     // Res = SRW & 1, no processing is required
7978d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
798cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov   case MSP430CC::COND_LO:
7998d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     // Res = ~(SRW & 1)
8008d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     Invert = true;
8018d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
802cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov   case MSP430CC::COND_NE:
8038d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     if (andCC) {
8048d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov       // C = ~Z, thus Res = SRW & 1, no processing is required
8058d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     } else {
806455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov       // Res = ~((SRW >> 1) & 1)
8078d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov       Shift = true;
808455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov       Invert = true;
8098d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     }
8108d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
811cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov   case MSP430CC::COND_E:
812455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov     Shift = true;
813455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov     // C = ~Z for AND instruction, thus we can put Res = ~(SRW & 1), however,
814455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov     // Res = (SRW >> 1) & 1 is 1 word shorter.
8158d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
8168d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  }
8178d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  EVT VT = Op.getValueType();
8188d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue One  = DAG.getConstant(1, VT);
8198d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  if (Convert) {
8208d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SRW,
821cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov                                    MVT::i16, Flag);
8228d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    if (Shift)
8238d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov      // FIXME: somewhere this is turned into a SRL, lower it MSP specific?
8248d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov      SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One);
8258d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    SR = DAG.getNode(ISD::AND, dl, MVT::i16, SR, One);
8268d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    if (Invert)
8278d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov      SR = DAG.getNode(ISD::XOR, dl, MVT::i16, SR, One);
8288d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    return SR;
8298d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  } else {
8308d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    SDValue Zero = DAG.getConstant(0, VT);
831f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner    SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
8328d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    SmallVector<SDValue, 4> Ops;
8338d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Ops.push_back(One);
8348d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Ops.push_back(Zero);
8358d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Ops.push_back(TargetCC);
8368d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Ops.push_back(Flag);
8378d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size());
8388d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  }
8398d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov}
8408d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov
841d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op,
842d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                             SelectionDAG &DAG) const {
8431bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue LHS    = Op.getOperand(0);
8441bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue RHS    = Op.getOperand(1);
8451bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue TrueV  = Op.getOperand(2);
8461bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue FalseV = Op.getOperand(3);
8471bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
8488b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  DebugLoc dl    = Op.getDebugLoc();
8491bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
8503926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  SDValue TargetCC;
8511bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
8528b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
853f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner  SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
8548b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  SmallVector<SDValue, 4> Ops;
8558b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  Ops.push_back(TrueV);
8568b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  Ops.push_back(FalseV);
8573926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  Ops.push_back(TargetCC);
8581bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  Ops.push_back(Flag);
8598b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
8601bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size());
8618b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov}
8628b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
863b78e214274d397407b6167a293b7cd7c3b526ddeAnton KorobeynikovSDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op,
864d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                               SelectionDAG &DAG) const {
865b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  SDValue Val = Op.getOperand(0);
866e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT      = Op.getValueType();
867b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  DebugLoc dl = Op.getDebugLoc();
868b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov
869825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  assert(VT == MVT::i16 && "Only support i16 for now!");
870b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov
871b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT,
872b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov                     DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val),
873b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov                     DAG.getValueType(Val.getValueType()));
874b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov}
875b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov
876d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue
877d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanMSP430TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) const {
87806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MachineFunction &MF = DAG.getMachineFunction();
87906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
88006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  int ReturnAddrIndex = FuncInfo->getRAIndex();
88106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
88206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  if (ReturnAddrIndex == 0) {
88306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    // Set up a frame object for the return address.
88406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    uint64_t SlotSize = TD->getPointerSize();
88506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(SlotSize, -SlotSize,
886ed2ae136d29dd36122d2476801e7d7a86e8301e3Evan Cheng                                                           true);
88706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    FuncInfo->setRAIndex(ReturnAddrIndex);
88806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  }
88906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
89006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy());
89106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov}
89206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
893d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op,
894d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                              SelectionDAG &DAG) const {
8952457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
8962457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng  MFI->setReturnAddressIsTaken(true);
8972457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng
89806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
89906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  DebugLoc dl = Op.getDebugLoc();
90006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
90106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  if (Depth > 0) {
90206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
90306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    SDValue Offset =
90406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov      DAG.getConstant(TD->getPointerSize(), MVT::i16);
90506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
90606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                       DAG.getNode(ISD::ADD, dl, getPointerTy(),
90706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                                   FrameAddr, Offset),
908d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                       MachinePointerInfo(), false, false, false, 0);
90906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  }
91006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
91106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  // Just load the return address.
91206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  SDValue RetAddrFI = getReturnAddressFrameIndex(DAG);
91306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
914d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                     RetAddrFI, MachinePointerInfo(), false, false, false, 0);
91506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov}
91606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
917d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op,
918d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                             SelectionDAG &DAG) const {
91906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
92006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MFI->setFrameAddressIsTaken(true);
9212457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng
92206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  EVT VT = Op.getValueType();
92306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  DebugLoc dl = Op.getDebugLoc();  // FIXME probably not meaningful
92406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
92506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl,
92606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                                         MSP430::FPW, VT);
92706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  while (Depth--)
928d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner    FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
929d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner                            MachinePointerInfo(),
930d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                            false, false, false, 0);
93106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  return FrameAddr;
93206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov}
93306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
9346534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// getPostIndexedAddressParts - returns true by value, base pointer and
9356534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// offset pointer and addressing mode by reference if this node can be
9366534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// combined with a load / store to form a post-indexed load / store.
9376534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikovbool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
9386534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      SDValue &Base,
9396534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      SDValue &Offset,
9406534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      ISD::MemIndexedMode &AM,
9416534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      SelectionDAG &DAG) const {
9426534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
9436534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  LoadSDNode *LD = cast<LoadSDNode>(N);
9446534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (LD->getExtensionType() != ISD::NON_EXTLOAD)
9456534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return false;
9466534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
9476534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  EVT VT = LD->getMemoryVT();
9486534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (VT != MVT::i8 && VT != MVT::i16)
9496534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return false;
9506534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
9516534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (Op->getOpcode() != ISD::ADD)
9526534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return false;
9536534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
9546534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) {
9556534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    uint64_t RHSC = RHS->getZExtValue();
9566534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    if ((VT == MVT::i16 && RHSC != 2) ||
9576534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov        (VT == MVT::i8 && RHSC != 1))
9586534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov      return false;
9596534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
9606534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    Base = Op->getOperand(0);
9616534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    Offset = DAG.getConstant(RHSC, VT);
9626534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    AM = ISD::POST_INC;
9636534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return true;
9646534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  }
9656534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
9666534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  return false;
9676534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov}
9686534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
9696534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
970fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikovconst char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
971fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  switch (Opcode) {
972fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  default: return NULL;
973fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  case MSP430ISD::RET_FLAG:           return "MSP430ISD::RET_FLAG";
9746bfcba7e137113e5f38cc4f937ad61cc7253ec74Anton Korobeynikov  case MSP430ISD::RETI_FLAG:          return "MSP430ISD::RETI_FLAG";
975d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  case MSP430ISD::RRA:                return "MSP430ISD::RRA";
976e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  case MSP430ISD::RLA:                return "MSP430ISD::RLA";
977e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  case MSP430ISD::RRC:                return "MSP430ISD::RRC";
978b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov  case MSP430ISD::CALL:               return "MSP430ISD::CALL";
9793513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  case MSP430ISD::Wrapper:            return "MSP430ISD::Wrapper";
9801bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case MSP430ISD::BR_CC:              return "MSP430ISD::BR_CC";
981ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case MSP430ISD::CMP:                return "MSP430ISD::CMP";
9821bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case MSP430ISD::SELECT_CC:          return "MSP430ISD::SELECT_CC";
9832625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430ISD::SHL:                return "MSP430ISD::SHL";
9842625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430ISD::SRA:                return "MSP430ISD::SRA";
985fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  }
986fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov}
9878b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
988db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattnerbool MSP430TargetLowering::isTruncateFree(Type *Ty1,
989db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner                                          Type *Ty2) const {
990b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands  if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
9919afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov    return false;
9929afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
9939afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  return (Ty1->getPrimitiveSizeInBits() > Ty2->getPrimitiveSizeInBits());
9949afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov}
9959afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
9969afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikovbool MSP430TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
9979afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  if (!VT1.isInteger() || !VT2.isInteger())
9989afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov    return false;
9999afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
10009afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  return (VT1.getSizeInBits() > VT2.getSizeInBits());
10019afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov}
10029afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
1003db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattnerbool MSP430TargetLowering::isZExtFree(Type *Ty1, Type *Ty2) const {
10049afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
1005b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands  return 0 && Ty1->isIntegerTy(8) && Ty2->isIntegerTy(16);
10069afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov}
10079afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
10089afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikovbool MSP430TargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
10099afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
10109afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  return 0 && VT1 == MVT::i8 && VT2 == MVT::i16;
10119afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov}
10129afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
10138b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===//
10148b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//  Other Lowering Code
10158b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===//
10168b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
10178b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMachineBasicBlock*
10182625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMSP430TargetLowering::EmitShiftInstr(MachineInstr *MI,
1019af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman                                     MachineBasicBlock *BB) const {
10202625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineFunction *F = BB->getParent();
10212625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineRegisterInfo &RI = F->getRegInfo();
10222625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  DebugLoc dl = MI->getDebugLoc();
10232625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
10242625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10252625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned Opc;
10262625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  const TargetRegisterClass * RC;
10272625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  switch (MI->getOpcode()) {
1028bc2198133a1836598b54b943420748e75d5dea94Craig Topper  default: llvm_unreachable("Invalid shift opcode!");
10292625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Shl8:
10302625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SHL8r1;
1031420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR8RegClass;
10322625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
10332625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Shl16:
10342625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SHL16r1;
1035420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR16RegClass;
10362625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
10372625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Sra8:
10382625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR8r1;
1039420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR8RegClass;
10402625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
10412625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Sra16:
10422625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR16r1;
1043420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR16RegClass;
10442625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
10452625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Srl8:
10462625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR8r1c;
1047420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR8RegClass;
10482625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
10492625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Srl16:
10502625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR16r1c;
1051420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR16RegClass;
10522625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
10532625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  }
10542625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10552625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  const BasicBlock *LLVM_BB = BB->getBasicBlock();
10562625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineFunction::iterator I = BB;
10572625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  ++I;
10582625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10592625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Create loop block
10602625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB);
10612625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineBasicBlock *RemBB  = F->CreateMachineBasicBlock(LLVM_BB);
10622625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10632625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  F->insert(I, LoopBB);
10642625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  F->insert(I, RemBB);
10652625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10662625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Update machine-CFG edges by transferring all successors of the current
10672625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // block to the block containing instructions after shift.
106814152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  RemBB->splice(RemBB->begin(), BB,
106914152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman                llvm::next(MachineBasicBlock::iterator(MI)),
107014152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman                BB->end());
107114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  RemBB->transferSuccessorsAndUpdatePHIs(BB);
10722625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10732625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Add adges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB
10742625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BB->addSuccessor(LoopBB);
10752625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BB->addSuccessor(RemBB);
10762625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  LoopBB->addSuccessor(RemBB);
10772625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  LoopBB->addSuccessor(LoopBB);
10782625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
1079420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper  unsigned ShiftAmtReg = RI.createVirtualRegister(&MSP430::GR8RegClass);
1080420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper  unsigned ShiftAmtReg2 = RI.createVirtualRegister(&MSP430::GR8RegClass);
10812625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned ShiftReg = RI.createVirtualRegister(RC);
10822625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned ShiftReg2 = RI.createVirtualRegister(RC);
10832625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned ShiftAmtSrcReg = MI->getOperand(2).getReg();
10842625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned SrcReg = MI->getOperand(1).getReg();
10852625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned DstReg = MI->getOperand(0).getReg();
10862625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10872625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // BB:
10882625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // cmp 0, N
10892625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // je RemBB
1090f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov  BuildMI(BB, dl, TII.get(MSP430::CMP8ri))
1091f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    .addReg(ShiftAmtSrcReg).addImm(0);
10922625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(BB, dl, TII.get(MSP430::JCC))
10932625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addMBB(RemBB)
10942625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addImm(MSP430CC::COND_E);
10952625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10962625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // LoopBB:
10972625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB]
10982625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // ShiftAmt = phi [%N, BB],      [%ShiftAmt2, LoopBB]
10992625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // ShiftReg2 = shift ShiftReg
11002625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // ShiftAmt2 = ShiftAmt - 1;
11012625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftReg)
11022625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(SrcReg).addMBB(BB)
11032625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftReg2).addMBB(LoopBB);
11042625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg)
11052625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftAmtSrcReg).addMBB(BB)
11062625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftAmtReg2).addMBB(LoopBB);
11072625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2)
11082625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftReg);
11092625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2)
11102625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftAmtReg).addImm(1);
11112625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::JCC))
11122625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addMBB(LoopBB)
11132625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addImm(MSP430CC::COND_NE);
11142625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11152625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // RemBB:
11162625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB]
111714152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  BuildMI(*RemBB, RemBB->begin(), dl, TII.get(MSP430::PHI), DstReg)
11182625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(SrcReg).addMBB(BB)
11192625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftReg2).addMBB(LoopBB);
11202625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
112114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  MI->eraseFromParent();   // The pseudo instruction is gone now.
11222625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  return RemBB;
11232625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov}
11242625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11252625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMachineBasicBlock*
11268b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
1127af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman                                                  MachineBasicBlock *BB) const {
11282625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned Opc = MI->getOpcode();
11292625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11302625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 ||
11312625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      Opc == MSP430::Sra8 || Opc == MSP430::Sra16 ||
11322625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      Opc == MSP430::Srl8 || Opc == MSP430::Srl16)
1133af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman    return EmitShiftInstr(MI, BB);
11342625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11358b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
11368b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  DebugLoc dl = MI->getDebugLoc();
11372625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11382625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  assert((Opc == MSP430::Select16 || Opc == MSP430::Select8) &&
11398b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov         "Unexpected instr type to insert");
11408b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
11418b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // To "insert" a SELECT instruction, we actually have to insert the diamond
11428b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // control-flow pattern.  The incoming instruction knows the destination vreg
11438b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // to set, the condition code register to branch on, the true/false values to
11448b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // select between, and a branch opcode to use.
11458b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  const BasicBlock *LLVM_BB = BB->getBasicBlock();
11468b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineFunction::iterator I = BB;
11478b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  ++I;
11488b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
11498b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  thisMBB:
11508b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  ...
11518b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   TrueVal = ...
11528b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   cmpTY ccX, r1, r2
11538b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   jCC copy1MBB
11548b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   fallthrough --> copy0MBB
11558b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineBasicBlock *thisMBB = BB;
11568b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineFunction *F = BB->getParent();
11578b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
11588b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB);
11598b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  F->insert(I, copy0MBB);
11608b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  F->insert(I, copy1MBB);
11618b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // Update machine-CFG edges by transferring all successors of the current
11628b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // block to the new block which will contain the Phi node for the select.
116314152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  copy1MBB->splice(copy1MBB->begin(), BB,
116414152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman                   llvm::next(MachineBasicBlock::iterator(MI)),
116514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman                   BB->end());
116614152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  copy1MBB->transferSuccessorsAndUpdatePHIs(BB);
11678b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // Next, add the true and fallthrough blocks as its successors.
11688b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB->addSuccessor(copy0MBB);
11698b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB->addSuccessor(copy1MBB);
11708b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
117114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  BuildMI(BB, dl, TII.get(MSP430::JCC))
117214152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman    .addMBB(copy1MBB)
117314152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman    .addImm(MI->getOperand(3).getImm());
117414152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman
11758b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  copy0MBB:
11768b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   %FalseValue = ...
11778b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   # fallthrough to copy1MBB
11788b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB = copy0MBB;
11798b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
11808b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // Update machine-CFG edges
11818b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB->addSuccessor(copy1MBB);
11828b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
11838b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  copy1MBB:
11848b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
11858b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  ...
11868b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB = copy1MBB;
118714152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  BuildMI(*BB, BB->begin(), dl, TII.get(MSP430::PHI),
11888b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov          MI->getOperand(0).getReg())
11898b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB)
11908b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB);
11918b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
119214152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  MI->eraseFromParent();   // The pseudo instruction is gone now.
11938b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  return BB;
11948b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov}
1195