MSP430ISelLowering.cpp revision ac6d9bec671252dd1e596fa71180ff6b39d06b5d
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 "MSP430Subtarget.h"
20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "MSP430TargetMachine.h"
21f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/CallingConvLower.h"
22f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h"
23f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineFunction.h"
24f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h"
25f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineRegisterInfo.h"
26f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/SelectionDAGISel.h"
27362dd0bef5437f85586c046bc53287b6fbe9c099Anton Korobeynikov#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
28f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/ValueTypes.h"
290b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/CallingConv.h"
300b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h"
310b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h"
320b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/GlobalAlias.h"
330b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/GlobalVariable.h"
340b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Intrinsics.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
643574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow  TD = getDataLayout();
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
1670ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  // varargs support
1680ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  setOperationAction(ISD::VASTART,          MVT::Other, Custom);
1690ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  setOperationAction(ISD::VAARG,            MVT::Other, Expand);
1700ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  setOperationAction(ISD::VAEND,            MVT::Other, Expand);
1710ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  setOperationAction(ISD::VACOPY,           MVT::Other, Expand);
1720ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov
173b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  // Libcalls names.
174b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  if (HWMultMode == HWMultIntr) {
175b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I8,  "__mulqi3hw");
176b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I16, "__mulhi3hw");
177b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  } else if (HWMultMode == HWMultNoIntr) {
178b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I8,  "__mulqi3hw_noint");
179b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I16, "__mulhi3hw_noint");
180b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  }
181fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman
182fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman  setMinFunctionAlignment(1);
183fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman  setPrefFunctionAlignment(2);
184f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
185f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
186d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerOperation(SDValue Op,
187d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                             SelectionDAG &DAG) const {
188f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  switch (Op.getOpcode()) {
189ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov  case ISD::SHL: // FALLTHROUGH
190e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  case ISD::SRL:
1914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  case ISD::SRA:              return LowerShifts(Op, DAG);
1923513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  case ISD::GlobalAddress:    return LowerGlobalAddress(Op, DAG);
19369d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov  case ISD::BlockAddress:     return LowerBlockAddress(Op, DAG);
1945d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  case ISD::ExternalSymbol:   return LowerExternalSymbol(Op, DAG);
1958d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  case ISD::SETCC:            return LowerSETCC(Op, DAG);
1961bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case ISD::BR_CC:            return LowerBR_CC(Op, DAG);
1971bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case ISD::SELECT_CC:        return LowerSELECT_CC(Op, DAG);
198b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  case ISD::SIGN_EXTEND:      return LowerSIGN_EXTEND(Op, DAG);
19906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  case ISD::RETURNADDR:       return LowerRETURNADDR(Op, DAG);
20006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  case ISD::FRAMEADDR:        return LowerFRAMEADDR(Op, DAG);
2010ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  case ISD::VASTART:          return LowerVASTART(Op, DAG);
202f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  default:
203c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("unimplemented operand");
204f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  }
205f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
206f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
207c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===//
208cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//                       MSP430 Inline Assembly Support
209cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===//
210cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
211cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// getConstraintType - Given a constraint letter, return the type of
212cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// constraint it is for this target.
213cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovTargetLowering::ConstraintType
214cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering::getConstraintType(const std::string &Constraint) const {
215cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  if (Constraint.size() == 1) {
216cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    switch (Constraint[0]) {
217cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    case 'r':
218cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      return C_RegisterClass;
219cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    default:
220cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      break;
221cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    }
222cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  }
223cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  return TargetLowering::getConstraintType(Constraint);
224cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov}
225cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
226cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikovstd::pair<unsigned, const TargetRegisterClass*>
227cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering::
228cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovgetRegForInlineAsmConstraint(const std::string &Constraint,
229cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov                             EVT VT) const {
230cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  if (Constraint.size() == 1) {
231cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    // GCC Constraint Letters
232cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    switch (Constraint[0]) {
233cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    default: break;
234cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    case 'r':   // GENERAL_REGS
235cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      if (VT == MVT::i8)
236420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper        return std::make_pair(0U, &MSP430::GR8RegClass);
237cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
238420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper      return std::make_pair(0U, &MSP430::GR16RegClass);
239cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    }
240cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  }
241cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
242cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
243cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov}
244cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
245cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===//
246c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//                      Calling Convention Implementation
247c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===//
248c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
249f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430GenCallingConv.inc"
250c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
25198ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
25298ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerFormalArguments(SDValue Chain,
25365c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                           CallingConv::ID CallConv,
25498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           bool isVarArg,
25598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           const SmallVectorImpl<ISD::InputArg>
25698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                             &Ins,
257ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                           SDLoc dl,
25898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           SelectionDAG &DAG,
259d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                           SmallVectorImpl<SDValue> &InVals)
260d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                             const {
26198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
26298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  switch (CallConv) {
263c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  default:
264c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Unsupported calling convention");
265c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  case CallingConv::C:
266c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  case CallingConv::Fast:
26798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman    return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals);
268e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  case CallingConv::MSP430_INTR:
2694d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    if (Ins.empty())
2704d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie      return Chain;
27175361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("ISRs cannot have arguments");
272c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  }
273c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov}
274c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
27598ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
276d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin HolewinskiMSP430TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
277d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                SmallVectorImpl<SDValue> &InVals) const {
278d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SelectionDAG &DAG                     = CLI.DAG;
279ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc &dl                             = CLI.DL;
280d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs;
281d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SmallVector<SDValue, 32> &OutVals     = CLI.OutVals;
282d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SmallVector<ISD::InputArg, 32> &Ins   = CLI.Ins;
283d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SDValue Chain                         = CLI.Chain;
284d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SDValue Callee                        = CLI.Callee;
285d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  bool &isTailCall                      = CLI.IsTailCall;
286d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  CallingConv::ID CallConv              = CLI.CallConv;
287d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  bool isVarArg                         = CLI.IsVarArg;
288d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski
2890c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng  // MSP430 target does not yet support tail call optimization.
2900c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng  isTailCall = false;
29198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
29298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  switch (CallConv) {
2934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  default:
294c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Unsupported calling convention");
2954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  case CallingConv::Fast:
2964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  case CallingConv::C:
29798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman    return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
298c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman                          Outs, OutVals, Ins, dl, DAG, InVals);
299e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  case CallingConv::MSP430_INTR:
30075361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("ISRs cannot be called directly");
3014428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
3024428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov}
3034428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
304c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// LowerCCCArguments - transform physical registers into virtual registers and
305c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// generate load operations for arguments places on the stack.
306c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// FIXME: struct return stuff
30798ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
30898ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCArguments(SDValue Chain,
30965c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                        CallingConv::ID CallConv,
31098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        bool isVarArg,
31198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        const SmallVectorImpl<ISD::InputArg>
31298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                          &Ins,
313ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                        SDLoc dl,
31498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        SelectionDAG &DAG,
315d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                        SmallVectorImpl<SDValue> &InVals)
316d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                          const {
317c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  MachineFunction &MF = DAG.getMachineFunction();
318c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  MachineFrameInfo *MFI = MF.getFrameInfo();
319c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  MachineRegisterInfo &RegInfo = MF.getRegInfo();
3200ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
321c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
322c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  // Assign locations to all of the incoming arguments.
323c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  SmallVector<CCValAssign, 16> ArgLocs;
324471e4224809f51652c71f319532697a879a75a0dEric Christopher  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
32556cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling                 getTargetMachine(), ArgLocs, *DAG.getContext());
32698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCInfo.AnalyzeFormalArguments(Ins, CC_MSP430);
327c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
3280ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  // Create frame index for the start of the first vararg value
3290ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  if (isVarArg) {
3300ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov    unsigned Offset = CCInfo.getNextStackOffset();
3310ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov    FuncInfo->setVarArgsFrameIndex(MFI->CreateFixedObject(1, Offset, true));
3320ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  }
333c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
334c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
335c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    CCValAssign &VA = ArgLocs[i];
336c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    if (VA.isRegLoc()) {
337c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      // Arguments passed in registers
338e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson      EVT RegVT = VA.getLocVT();
339825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      switch (RegVT.getSimpleVT().SimpleTy) {
34095771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson      default:
341804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin        {
342dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#ifndef NDEBUG
3434437ae213d5435390f0750213b53ec807c047f22Chris Lattner          errs() << "LowerFormalArguments Unhandled argument type: "
344825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson               << RegVT.getSimpleVT().SimpleTy << "\n";
345dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#endif
346c23197a26f34f559ea9797de51e187087c039c42Torok Edwin          llvm_unreachable(0);
347804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin        }
348825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      case MVT::i16:
349420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper        unsigned VReg = RegInfo.createVirtualRegister(&MSP430::GR16RegClass);
350c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        RegInfo.addLiveIn(VA.getLocReg(), VReg);
35198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman        SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, RegVT);
352c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
353c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        // If this is an 8-bit value, it is really passed promoted to 16
354c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        // bits. Insert an assert[sz]ext to capture this, then truncate to the
355c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        // right size.
356c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        if (VA.getLocInfo() == CCValAssign::SExt)
357c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov          ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue,
358c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov                                 DAG.getValueType(VA.getValVT()));
359c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        else if (VA.getLocInfo() == CCValAssign::ZExt)
360c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov          ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue,
361c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov                                 DAG.getValueType(VA.getValVT()));
362c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
363c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        if (VA.getLocInfo() != CCValAssign::Full)
364c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov          ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
365c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
36698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman        InVals.push_back(ArgValue);
367c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      }
368c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    } else {
369c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      // Sanity check
370c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      assert(VA.isMemLoc());
3716cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov
3726cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      SDValue InVal;
3736cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      ISD::ArgFlagsTy Flags = Ins[i].Flags;
3746cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov
3756cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      if (Flags.isByVal()) {
3766cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        int FI = MFI->CreateFixedObject(Flags.getByValSize(),
3776cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                                        VA.getLocMemOffset(), true);
3786cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        InVal = DAG.getFrameIndex(FI, getPointerTy());
3796cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      } else {
3806cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        // Load the argument to a virtual register
3816cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        unsigned ObjSize = VA.getLocVT().getSizeInBits()/8;
3826cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        if (ObjSize > 2) {
3836cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov            errs() << "LowerFormalArguments Unhandled argument type: "
3846cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                << EVT(VA.getLocVT()).getEVTString()
3856cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                << "\n";
3866cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        }
3876cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        // Create the frame index object for this incoming parameter...
3886cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);
3896cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov
3906cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        // Create the SelectionDAG nodes corresponding to a load
3916cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        //from this parameter
3926cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        SDValue FIN = DAG.getFrameIndex(FI, MVT::i16);
3936cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        InVal = DAG.getLoad(VA.getLocVT(), dl, Chain, FIN,
3946cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                            MachinePointerInfo::getFixedStack(FI),
3956cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                            false, false, false, 0);
396c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      }
3976cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov
3986cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      InVals.push_back(InVal);
399c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    }
400c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  }
401c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
40298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return Chain;
403c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov}
404fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
40598ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
40698ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerReturn(SDValue Chain,
40765c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                  CallingConv::ID CallConv, bool isVarArg,
40898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                  const SmallVectorImpl<ISD::OutputArg> &Outs,
409c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman                                  const SmallVectorImpl<SDValue> &OutVals,
410ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                  SDLoc dl, SelectionDAG &DAG) const {
41198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
412fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // CCValAssign - represent the assignment of the return value to a location
413fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  SmallVector<CCValAssign, 16> RVLocs;
414fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
415e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  // ISRs cannot return any value.
4164d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  if (CallConv == CallingConv::MSP430_INTR && !Outs.empty())
41775361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("ISRs cannot return any value");
418e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov
419fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // CCState - Info about the registers and stack slot.
420471e4224809f51652c71f319532697a879a75a0dEric Christopher  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
42156cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling                 getTargetMachine(), RVLocs, *DAG.getContext());
422fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
42398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  // Analize return values.
42498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCInfo.AnalyzeReturn(Outs, RetCC_MSP430);
425fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
426fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  SDValue Flag;
427294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen  SmallVector<SDValue, 4> RetOps(1, Chain);
428fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
429fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // Copy the result values into the output registers.
430fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  for (unsigned i = 0; i != RVLocs.size(); ++i) {
431fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    CCValAssign &VA = RVLocs[i];
432fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    assert(VA.isRegLoc() && "Can only return in registers!");
433fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
434fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
435c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman                             OutVals[i], Flag);
436fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
437dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov    // Guarantee that all emitted copies are stuck together,
438dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov    // avoiding something bad.
439fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    Flag = Chain.getValue(1);
440294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen    RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
441fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  }
442fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
443e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  unsigned Opc = (CallConv == CallingConv::MSP430_INTR ?
444e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov                  MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG);
445e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov
446294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen  RetOps[0] = Chain;  // Update chain.
447294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen
448294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen  // Add the flag if we have it.
449fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  if (Flag.getNode())
450294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen    RetOps.push_back(Flag);
451fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
452294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen  return DAG.getNode(Opc, dl, MVT::Other, &RetOps[0], RetOps.size());
453fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov}
454fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
4554428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// LowerCCCCallTo - functions arguments are copied from virtual regs to
4564428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
4574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// TODO: sret.
45898ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
45998ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee,
46065c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                     CallingConv::ID CallConv, bool isVarArg,
46198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     bool isTailCall,
46298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     const SmallVectorImpl<ISD::OutputArg>
46398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                       &Outs,
464c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman                                     const SmallVectorImpl<SDValue> &OutVals,
46598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     const SmallVectorImpl<ISD::InputArg> &Ins,
466ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                     SDLoc dl, SelectionDAG &DAG,
467d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                     SmallVectorImpl<SDValue> &InVals) const {
4684428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Analyze operands of the call, assigning locations to each operand.
4694428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<CCValAssign, 16> ArgLocs;
470471e4224809f51652c71f319532697a879a75a0dEric Christopher  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
47156cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling                 getTargetMachine(), ArgLocs, *DAG.getContext());
4724428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
47398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCInfo.AnalyzeCallOperands(Outs, CC_MSP430);
4744428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4754428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Get a count of how many bytes are to be pushed on the stack.
4764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  unsigned NumBytes = CCInfo.getNextStackOffset();
4774428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Chain = DAG.getCALLSEQ_START(Chain ,DAG.getConstant(NumBytes,
4794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                                      getPointerTy(), true));
4804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4814428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass;
4824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<SDValue, 12> MemOpChains;
4834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SDValue StackPtr;
4844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Walk the register/memloc assignments, inserting copies/loads.
4864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
4874428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    CCValAssign &VA = ArgLocs[i];
4884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
489c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman    SDValue Arg = OutVals[i];
4904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    // Promote the value if needed.
4924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    switch (VA.getLocInfo()) {
493c23197a26f34f559ea9797de51e187087c039c42Torok Edwin      default: llvm_unreachable("Unknown loc info!");
4944428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::Full: break;
4954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::SExt:
4964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
4974428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        break;
4984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::ZExt:
4994428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
5004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        break;
5014428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::AExt:
5024428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
5034428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        break;
5044428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    }
5054428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5064428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    // Arguments that can be passed on register must be kept at RegsToPass
5074428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    // vector
5084428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    if (VA.isRegLoc()) {
5094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
5104428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    } else {
5114428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      assert(VA.isMemLoc());
5124428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5134428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      if (StackPtr.getNode() == 0)
5144428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SPW, getPointerTy());
5154428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(),
5174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                   StackPtr,
5184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                   DAG.getIntPtrConstant(VA.getLocMemOffset()));
5194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5206cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      SDValue MemOp;
5216cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      ISD::ArgFlagsTy Flags = Outs[i].Flags;
5226cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov
5236cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      if (Flags.isByVal()) {
5246cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), MVT::i16);
5256cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        MemOp = DAG.getMemcpy(Chain, dl, PtrOff, Arg, SizeNode,
5266cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                              Flags.getByValAlign(),
5276cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                              /*isVolatile*/false,
5286cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                              /*AlwaysInline=*/true,
5296cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                              MachinePointerInfo(),
5306cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                              MachinePointerInfo());
5316cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      } else {
5326cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        MemOp = DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo(),
5336cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                             false, false, 0);
5346cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      }
5354428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5366cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      MemOpChains.push_back(MemOp);
5374428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    }
5384428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
5394428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5404428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Transform all store nodes into one single node because all store nodes are
5414428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // independent of each other.
5424428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  if (!MemOpChains.empty())
543825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
5444428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                        &MemOpChains[0], MemOpChains.size());
5454428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5464428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Build a sequence of copy-to-reg nodes chained together with token chain and
5474428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // flag operands which copy the outgoing args into registers.  The InFlag in
5487a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner  // necessary since all emitted instructions must be stuck together.
5494428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SDValue InFlag;
5504428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
5514428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
5524428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             RegsToPass[i].second, InFlag);
5534428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    InFlag = Chain.getValue(1);
5544428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
5554428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5564428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // If the callee is a GlobalAddress node (quite common, every direct call is)
5574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
5584428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Likewise ExternalSymbol -> TargetExternalSymbol.
5594428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
5600d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel    Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i16);
5614428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
562825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i16);
5634428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5644428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Returns a chain & a flag for retval copy to use.
565f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner  SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
5664428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<SDValue, 8> Ops;
5674428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Ops.push_back(Chain);
5684428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Ops.push_back(Callee);
5694428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5704428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Add argument registers to the end of the list so that they are
5714428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // known live into the call.
5724428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
5734428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Ops.push_back(DAG.getRegister(RegsToPass[i].first,
5744428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                  RegsToPass[i].second.getValueType()));
5754428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  if (InFlag.getNode())
5774428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Ops.push_back(InFlag);
5784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Chain = DAG.getNode(MSP430ISD::CALL, dl, NodeTys, &Ops[0], Ops.size());
5804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  InFlag = Chain.getValue(1);
5814428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Create the CALLSEQ_END node.
5834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Chain = DAG.getCALLSEQ_END(Chain,
5844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             DAG.getConstant(NumBytes, getPointerTy(), true),
5854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             DAG.getConstant(0, getPointerTy(), true),
5864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             InFlag);
5874428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  InFlag = Chain.getValue(1);
5884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Handle result values, copying them out of physregs into vregs that we
5904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // return.
59198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl,
59298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                         DAG, InVals);
5934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov}
5944428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
59598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// LowerCallResult - Lower the result values of a call into the
59698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// appropriate copies out of appropriate physical registers.
59798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman///
59898ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
5994428885c5acfffbbdd03ad2aab23960531c47753Anton KorobeynikovMSP430TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag,
60065c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                      CallingConv::ID CallConv, bool isVarArg,
60198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                      const SmallVectorImpl<ISD::InputArg> &Ins,
602ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                      SDLoc dl, SelectionDAG &DAG,
603d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                      SmallVectorImpl<SDValue> &InVals) const {
6044428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
6054428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Assign locations to each value returned by this call.
6064428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<CCValAssign, 16> RVLocs;
607471e4224809f51652c71f319532697a879a75a0dEric Christopher  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
60856cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling                 getTargetMachine(), RVLocs, *DAG.getContext());
6094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
61098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCInfo.AnalyzeCallResult(Ins, RetCC_MSP430);
6114428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
6124428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Copy all of the result registers out of their specified physreg.
6134428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0; i != RVLocs.size(); ++i) {
6144428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(),
6154428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                               RVLocs[i].getValVT(), InFlag).getValue(1);
6164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    InFlag = Chain.getValue(2);
61798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman    InVals.push_back(Chain.getValue(0));
6184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
6194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
62098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return Chain;
6214428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov}
6224428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
623d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton KorobeynikovSDValue MSP430TargetLowering::LowerShifts(SDValue Op,
624d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                          SelectionDAG &DAG) const {
625ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov  unsigned Opc = Op.getOpcode();
626d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  SDNode* N = Op.getNode();
627e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = Op.getValueType();
628ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(N);
629d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
6302625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Expand non-constant shifts to loops:
631d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  if (!isa<ConstantSDNode>(N->getOperand(1)))
6322625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    switch (Opc) {
633bc2198133a1836598b54b943420748e75d5dea94Craig Topper    default: llvm_unreachable("Invalid shift opcode!");
6342625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    case ISD::SHL:
6352625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      return DAG.getNode(MSP430ISD::SHL, dl,
6362625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                         VT, N->getOperand(0), N->getOperand(1));
6372625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    case ISD::SRA:
6382625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      return DAG.getNode(MSP430ISD::SRA, dl,
6392625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                         VT, N->getOperand(0), N->getOperand(1));
6402625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    case ISD::SRL:
6412625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      return DAG.getNode(MSP430ISD::SRL, dl,
6422625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                         VT, N->getOperand(0), N->getOperand(1));
6432625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    }
644d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
645d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
646d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
647d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  // Expand the stuff into sequence of shifts.
648d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  // FIXME: for some shift amounts this might be done better!
649d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N
650d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  SDValue Victim = N->getOperand(0);
651e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov
652e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  if (Opc == ISD::SRL && ShiftAmount) {
653e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov    // Emit a special goodness here:
654e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov    // srl A, 1 => clrc; rrc A
655bf8ef3f29de28529b5d65970af9015c41f7c809bAnton Korobeynikov    Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim);
656e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov    ShiftAmount -= 1;
657e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  }
658e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov
659d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  while (ShiftAmount--)
660aceb620de855485a4fb2eed343d880d76f6c701cAnton Korobeynikov    Victim = DAG.getNode((Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA),
661ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov                         dl, VT, Victim);
662d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
663d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  return Victim;
664d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov}
665d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
666d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerGlobalAddress(SDValue Op,
667d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                                 SelectionDAG &DAG) const {
6683513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
6693513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();
6703513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov
6713513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  // Create the TargetGlobalAddress node, folding in the constant offset.
672ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDValue Result = DAG.getTargetGlobalAddress(GV, SDLoc(Op),
6730d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel                                              getPointerTy(), Offset);
674ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  return DAG.getNode(MSP430ISD::Wrapper, SDLoc(Op),
6753513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov                     getPointerTy(), Result);
6763513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov}
6773513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov
6785d59f68ade7573175f1ace09061a94286e59076bAnton KorobeynikovSDValue MSP430TargetLowering::LowerExternalSymbol(SDValue Op,
679d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                                  SelectionDAG &DAG) const {
680ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
6815d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol();
6825d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  SDValue Result = DAG.getTargetExternalSymbol(Sym, getPointerTy());
6835d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov
68490f20044ade3712c8b0c3f4ebe47d57ad15ae6ceChad Rosier  return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result);
6855d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov}
6865d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov
68769d5b48bc31b7a443355cdf1506005804b4f63e6Anton KorobeynikovSDValue MSP430TargetLowering::LowerBlockAddress(SDValue Op,
68869d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov                                                SelectionDAG &DAG) const {
689ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
69069d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov  const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
6916c7ccaa3fd1d6e96d0bf922554b09d2b17c3b0e3Michael Liao  SDValue Result = DAG.getTargetBlockAddress(BA, getPointerTy());
69269d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov
69390f20044ade3712c8b0c3f4ebe47d57ad15ae6ceChad Rosier  return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result);
69469d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov}
69569d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov
6963926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikovstatic SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC,
6971bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov                       ISD::CondCode CC,
698ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                       SDLoc dl, SelectionDAG &DAG) {
699ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  // FIXME: Handle bittests someday
700ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet");
701ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
702ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  // FIXME: Handle jump negative someday
7033926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  MSP430CC::CondCodes TCC = MSP430CC::COND_INVALID;
704ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  switch (CC) {
705c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Invalid integer condition!");
706ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETEQ:
7073926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_E;     // aka COND_Z
708f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    // Minor optimization: if LHS is a constant, swap operands, then the
7091722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov    // constant can be folded into comparison.
710f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    if (LHS.getOpcode() == ISD::Constant)
7111722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov      std::swap(LHS, RHS);
712ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
713ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETNE:
7143926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_NE;    // aka COND_NZ
715f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    // Minor optimization: if LHS is a constant, swap operands, then the
7161722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov    // constant can be folded into comparison.
717f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    if (LHS.getOpcode() == ISD::Constant)
7181722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov      std::swap(LHS, RHS);
719ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
720ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETULE:
721ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
722ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETUGE:
7230c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // Turn lhs u>= rhs with lhs constant into rhs u< lhs+1, this allows us to
7240c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
7250c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
7260c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
7270c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
7280c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_LO;
7290c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
7300c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
7313926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_HS;    // aka COND_C
732ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
733ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETUGT:
734ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
735ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETULT:
7360c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // Turn lhs u< rhs with lhs constant into rhs u>= lhs+1, this allows us to
7370c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
7380c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
7390c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
7400c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
7410c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_HS;
7420c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
7430c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
7443926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_LO;    // aka COND_NC
745ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
746ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETLE:
747ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
748ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETGE:
7490c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // Turn lhs >= rhs with lhs constant into rhs < lhs+1, this allows us to
7500c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
7510c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
7520c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
7530c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
7540c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_L;
7550c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
7560c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
7573926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_GE;
758ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
759ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETGT:
760ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
761ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETLT:
7620c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to
7630c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
7640c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
7650c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
7660c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
7670c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_GE;
7680c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
7690c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
7703926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_L;
771ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
772ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  }
773ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
7743926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  TargetCC = DAG.getConstant(TCC, MVT::i8);
775f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner  return DAG.getNode(MSP430ISD::CMP, dl, MVT::Glue, LHS, RHS);
776ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov}
777ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
7781bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
779d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
780ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  SDValue Chain = Op.getOperand(0);
7811bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
7821bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue LHS   = Op.getOperand(2);
7831bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue RHS   = Op.getOperand(3);
7841bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue Dest  = Op.getOperand(4);
785ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl  (Op);
7861bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
7873926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  SDValue TargetCC;
7881bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
7891bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
7901bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(),
7913926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov                     Chain, Dest, TargetCC, Flag);
792ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov}
793ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
794d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
7958d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue LHS   = Op.getOperand(0);
7968d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue RHS   = Op.getOperand(1);
797ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl  (Op);
7988d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov
7998d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // If we are doing an AND and testing against zero, then the CMP
8008d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // will not be generated.  The AND (or BIT) will generate the condition codes,
8018d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // but they are different from CMP.
802cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov  // FIXME: since we're doing a post-processing, use a pseudoinstr here, so
803cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov  // lowering & isel wouldn't diverge.
8048d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool andCC = false;
8058d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) {
8068d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    if (RHSC->isNullValue() && LHS.hasOneUse() &&
8078d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov        (LHS.getOpcode() == ISD::AND ||
8088d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov         (LHS.getOpcode() == ISD::TRUNCATE &&
8098d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov          LHS.getOperand(0).getOpcode() == ISD::AND))) {
8108d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov      andCC = true;
8118d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    }
8128d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  }
8138d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
8148d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue TargetCC;
8158d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
8168d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov
8178d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // Get the condition codes directly from the status register, if its easy.
8188d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // Otherwise a branch will be generated.  Note that the AND and BIT
8198d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // instructions generate different flags than CMP, the carry bit can be used
8208d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // for NE/EQ.
8218d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool Invert = false;
8228d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool Shift = false;
8238d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool Convert = true;
8248d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  switch (cast<ConstantSDNode>(TargetCC)->getZExtValue()) {
8258d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov   default:
8268d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Convert = false;
8278d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    break;
8288d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov   case MSP430CC::COND_HS:
8298d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     // Res = SRW & 1, no processing is required
8308d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
831cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov   case MSP430CC::COND_LO:
8328d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     // Res = ~(SRW & 1)
8338d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     Invert = true;
8348d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
835cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov   case MSP430CC::COND_NE:
8368d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     if (andCC) {
8378d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov       // C = ~Z, thus Res = SRW & 1, no processing is required
8388d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     } else {
839455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov       // Res = ~((SRW >> 1) & 1)
8408d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov       Shift = true;
841455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov       Invert = true;
8428d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     }
8438d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
844cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov   case MSP430CC::COND_E:
845455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov     Shift = true;
846455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov     // C = ~Z for AND instruction, thus we can put Res = ~(SRW & 1), however,
847455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov     // Res = (SRW >> 1) & 1 is 1 word shorter.
8488d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
8498d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  }
8508d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  EVT VT = Op.getValueType();
8518d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue One  = DAG.getConstant(1, VT);
8528d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  if (Convert) {
8538d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SRW,
854cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov                                    MVT::i16, Flag);
8558d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    if (Shift)
8568d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov      // FIXME: somewhere this is turned into a SRL, lower it MSP specific?
8578d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov      SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One);
8588d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    SR = DAG.getNode(ISD::AND, dl, MVT::i16, SR, One);
8598d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    if (Invert)
8608d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov      SR = DAG.getNode(ISD::XOR, dl, MVT::i16, SR, One);
8618d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    return SR;
8628d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  } else {
8638d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    SDValue Zero = DAG.getConstant(0, VT);
864f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner    SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
8658d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    SmallVector<SDValue, 4> Ops;
8668d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Ops.push_back(One);
8678d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Ops.push_back(Zero);
8688d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Ops.push_back(TargetCC);
8698d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Ops.push_back(Flag);
8708d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size());
8718d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  }
8728d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov}
8738d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov
874d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op,
875d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                             SelectionDAG &DAG) const {
8761bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue LHS    = Op.getOperand(0);
8771bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue RHS    = Op.getOperand(1);
8781bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue TrueV  = Op.getOperand(2);
8791bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue FalseV = Op.getOperand(3);
8801bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
881ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl   (Op);
8821bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
8833926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  SDValue TargetCC;
8841bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
8858b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
886f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner  SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
8878b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  SmallVector<SDValue, 4> Ops;
8888b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  Ops.push_back(TrueV);
8898b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  Ops.push_back(FalseV);
8903926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  Ops.push_back(TargetCC);
8911bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  Ops.push_back(Flag);
8928b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
8931bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size());
8948b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov}
8958b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
896b78e214274d397407b6167a293b7cd7c3b526ddeAnton KorobeynikovSDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op,
897d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                               SelectionDAG &DAG) const {
898b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  SDValue Val = Op.getOperand(0);
899e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT      = Op.getValueType();
900ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
901b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov
902825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  assert(VT == MVT::i16 && "Only support i16 for now!");
903b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov
904b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT,
905b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov                     DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val),
906b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov                     DAG.getValueType(Val.getValueType()));
907b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov}
908b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov
909d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue
910d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanMSP430TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) const {
91106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MachineFunction &MF = DAG.getMachineFunction();
91206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
91306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  int ReturnAddrIndex = FuncInfo->getRAIndex();
91406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
91506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  if (ReturnAddrIndex == 0) {
91606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    // Set up a frame object for the return address.
917426c2bf5cdd2173e4a33aea8cb92cf684a724f4bChandler Carruth    uint64_t SlotSize = TD->getPointerSize();
91806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(SlotSize, -SlotSize,
919ed2ae136d29dd36122d2476801e7d7a86e8301e3Evan Cheng                                                           true);
92006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    FuncInfo->setRAIndex(ReturnAddrIndex);
92106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  }
92206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
92306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy());
92406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov}
92506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
926d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op,
927d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                              SelectionDAG &DAG) const {
9282457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
9292457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng  MFI->setReturnAddressIsTaken(true);
9302457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng
93106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
932ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
93306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
93406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  if (Depth > 0) {
93506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
93606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    SDValue Offset =
937426c2bf5cdd2173e4a33aea8cb92cf684a724f4bChandler Carruth      DAG.getConstant(TD->getPointerSize(), MVT::i16);
93806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
93906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                       DAG.getNode(ISD::ADD, dl, getPointerTy(),
94006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                                   FrameAddr, Offset),
941d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                       MachinePointerInfo(), false, false, false, 0);
94206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  }
94306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
94406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  // Just load the return address.
94506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  SDValue RetAddrFI = getReturnAddressFrameIndex(DAG);
94606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
947d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                     RetAddrFI, MachinePointerInfo(), false, false, false, 0);
94806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov}
94906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
950d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op,
951d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                             SelectionDAG &DAG) const {
95206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
95306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MFI->setFrameAddressIsTaken(true);
9542457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng
95506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  EVT VT = Op.getValueType();
956ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);  // FIXME probably not meaningful
95706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
95806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl,
95906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                                         MSP430::FPW, VT);
96006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  while (Depth--)
961d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner    FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
962d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner                            MachinePointerInfo(),
963d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                            false, false, false, 0);
96406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  return FrameAddr;
96506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov}
96606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
9670ae61240341ca76e1329f251c64d2f475fa89278Anton KorobeynikovSDValue MSP430TargetLowering::LowerVASTART(SDValue Op,
9680ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov                                           SelectionDAG &DAG) const {
9690ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  MachineFunction &MF = DAG.getMachineFunction();
9700ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
9710ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov
9720ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  // Frame index of first vararg argument
9730ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  SDValue FrameIndex = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),
9740ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov                                         getPointerTy());
9750ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
9760ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov
9770ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  // Create a store of the frame index to the location operand
978ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  return DAG.getStore(Op.getOperand(0), SDLoc(Op), FrameIndex,
9790ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov                      Op.getOperand(1), MachinePointerInfo(SV),
9800ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov                      false, false, 0);
9810ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov}
9820ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov
9836534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// getPostIndexedAddressParts - returns true by value, base pointer and
9846534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// offset pointer and addressing mode by reference if this node can be
9856534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// combined with a load / store to form a post-indexed load / store.
9866534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikovbool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
9876534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      SDValue &Base,
9886534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      SDValue &Offset,
9896534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      ISD::MemIndexedMode &AM,
9906534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      SelectionDAG &DAG) const {
9916534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
9926534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  LoadSDNode *LD = cast<LoadSDNode>(N);
9936534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (LD->getExtensionType() != ISD::NON_EXTLOAD)
9946534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return false;
9956534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
9966534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  EVT VT = LD->getMemoryVT();
9976534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (VT != MVT::i8 && VT != MVT::i16)
9986534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return false;
9996534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
10006534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (Op->getOpcode() != ISD::ADD)
10016534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return false;
10026534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
10036534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) {
10046534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    uint64_t RHSC = RHS->getZExtValue();
10056534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    if ((VT == MVT::i16 && RHSC != 2) ||
10066534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov        (VT == MVT::i8 && RHSC != 1))
10076534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov      return false;
10086534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
10096534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    Base = Op->getOperand(0);
10106534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    Offset = DAG.getConstant(RHSC, VT);
10116534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    AM = ISD::POST_INC;
10126534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return true;
10136534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  }
10146534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
10156534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  return false;
10166534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov}
10176534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
10186534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
1019fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikovconst char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
1020fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  switch (Opcode) {
1021fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  default: return NULL;
1022fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  case MSP430ISD::RET_FLAG:           return "MSP430ISD::RET_FLAG";
10236bfcba7e137113e5f38cc4f937ad61cc7253ec74Anton Korobeynikov  case MSP430ISD::RETI_FLAG:          return "MSP430ISD::RETI_FLAG";
1024d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  case MSP430ISD::RRA:                return "MSP430ISD::RRA";
1025e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  case MSP430ISD::RLA:                return "MSP430ISD::RLA";
1026e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  case MSP430ISD::RRC:                return "MSP430ISD::RRC";
1027b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov  case MSP430ISD::CALL:               return "MSP430ISD::CALL";
10283513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  case MSP430ISD::Wrapper:            return "MSP430ISD::Wrapper";
10291bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case MSP430ISD::BR_CC:              return "MSP430ISD::BR_CC";
1030ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case MSP430ISD::CMP:                return "MSP430ISD::CMP";
10311bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case MSP430ISD::SELECT_CC:          return "MSP430ISD::SELECT_CC";
10322625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430ISD::SHL:                return "MSP430ISD::SHL";
10332625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430ISD::SRA:                return "MSP430ISD::SRA";
1034fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  }
1035fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov}
10368b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
1037db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattnerbool MSP430TargetLowering::isTruncateFree(Type *Ty1,
1038db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner                                          Type *Ty2) const {
1039b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands  if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
10409afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov    return false;
10419afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
10429afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  return (Ty1->getPrimitiveSizeInBits() > Ty2->getPrimitiveSizeInBits());
10439afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov}
10449afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
10459afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikovbool MSP430TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
10469afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  if (!VT1.isInteger() || !VT2.isInteger())
10479afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov    return false;
10489afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
10499afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  return (VT1.getSizeInBits() > VT2.getSizeInBits());
10509afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov}
10519afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
1052db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattnerbool MSP430TargetLowering::isZExtFree(Type *Ty1, Type *Ty2) const {
10539afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
1054b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands  return 0 && Ty1->isIntegerTy(8) && Ty2->isIntegerTy(16);
10559afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov}
10569afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
10579afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikovbool MSP430TargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
10589afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
10599afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  return 0 && VT1 == MVT::i8 && VT2 == MVT::i16;
10609afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov}
10619afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
1062968b667e27d7fc9a5bf5da52191a7af629e174dcEli Benderskybool MSP430TargetLowering::isZExtFree(SDValue Val, EVT VT2) const {
1063968b667e27d7fc9a5bf5da52191a7af629e174dcEli Bendersky  return isZExtFree(Val.getValueType(), VT2);
1064968b667e27d7fc9a5bf5da52191a7af629e174dcEli Bendersky}
1065968b667e27d7fc9a5bf5da52191a7af629e174dcEli Bendersky
10668b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===//
10678b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//  Other Lowering Code
10688b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===//
10698b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
10708b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMachineBasicBlock*
10712625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMSP430TargetLowering::EmitShiftInstr(MachineInstr *MI,
1072af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman                                     MachineBasicBlock *BB) const {
10732625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineFunction *F = BB->getParent();
10742625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineRegisterInfo &RI = F->getRegInfo();
10752625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  DebugLoc dl = MI->getDebugLoc();
10762625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
10772625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10782625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned Opc;
10792625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  const TargetRegisterClass * RC;
10802625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  switch (MI->getOpcode()) {
1081bc2198133a1836598b54b943420748e75d5dea94Craig Topper  default: llvm_unreachable("Invalid shift opcode!");
10822625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Shl8:
10832625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SHL8r1;
1084420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR8RegClass;
10852625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
10862625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Shl16:
10872625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SHL16r1;
1088420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR16RegClass;
10892625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
10902625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Sra8:
10912625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR8r1;
1092420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR8RegClass;
10932625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
10942625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Sra16:
10952625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR16r1;
1096420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR16RegClass;
10972625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
10982625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Srl8:
10992625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR8r1c;
1100420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR8RegClass;
11012625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
11022625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Srl16:
11032625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR16r1c;
1104420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR16RegClass;
11052625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
11062625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  }
11072625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11082625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  const BasicBlock *LLVM_BB = BB->getBasicBlock();
11092625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineFunction::iterator I = BB;
11102625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  ++I;
11112625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11122625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Create loop block
11132625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB);
11142625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineBasicBlock *RemBB  = F->CreateMachineBasicBlock(LLVM_BB);
11152625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11162625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  F->insert(I, LoopBB);
11172625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  F->insert(I, RemBB);
11182625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11192625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Update machine-CFG edges by transferring all successors of the current
11202625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // block to the block containing instructions after shift.
112114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  RemBB->splice(RemBB->begin(), BB,
112214152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman                llvm::next(MachineBasicBlock::iterator(MI)),
112314152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman                BB->end());
112414152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  RemBB->transferSuccessorsAndUpdatePHIs(BB);
11252625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11262625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Add adges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB
11272625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BB->addSuccessor(LoopBB);
11282625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BB->addSuccessor(RemBB);
11292625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  LoopBB->addSuccessor(RemBB);
11302625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  LoopBB->addSuccessor(LoopBB);
11312625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
1132420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper  unsigned ShiftAmtReg = RI.createVirtualRegister(&MSP430::GR8RegClass);
1133420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper  unsigned ShiftAmtReg2 = RI.createVirtualRegister(&MSP430::GR8RegClass);
11342625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned ShiftReg = RI.createVirtualRegister(RC);
11352625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned ShiftReg2 = RI.createVirtualRegister(RC);
11362625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned ShiftAmtSrcReg = MI->getOperand(2).getReg();
11372625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned SrcReg = MI->getOperand(1).getReg();
11382625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned DstReg = MI->getOperand(0).getReg();
11392625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11402625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // BB:
11412625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // cmp 0, N
11422625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // je RemBB
1143f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov  BuildMI(BB, dl, TII.get(MSP430::CMP8ri))
1144f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    .addReg(ShiftAmtSrcReg).addImm(0);
11452625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(BB, dl, TII.get(MSP430::JCC))
11462625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addMBB(RemBB)
11472625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addImm(MSP430CC::COND_E);
11482625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11492625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // LoopBB:
11502625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB]
11512625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // ShiftAmt = phi [%N, BB],      [%ShiftAmt2, LoopBB]
11522625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // ShiftReg2 = shift ShiftReg
11532625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // ShiftAmt2 = ShiftAmt - 1;
11542625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftReg)
11552625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(SrcReg).addMBB(BB)
11562625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftReg2).addMBB(LoopBB);
11572625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg)
11582625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftAmtSrcReg).addMBB(BB)
11592625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftAmtReg2).addMBB(LoopBB);
11602625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2)
11612625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftReg);
11622625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2)
11632625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftAmtReg).addImm(1);
11642625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::JCC))
11652625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addMBB(LoopBB)
11662625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addImm(MSP430CC::COND_NE);
11672625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11682625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // RemBB:
11692625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB]
117014152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  BuildMI(*RemBB, RemBB->begin(), dl, TII.get(MSP430::PHI), DstReg)
11712625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(SrcReg).addMBB(BB)
11722625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftReg2).addMBB(LoopBB);
11732625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
117414152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  MI->eraseFromParent();   // The pseudo instruction is gone now.
11752625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  return RemBB;
11762625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov}
11772625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11782625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMachineBasicBlock*
11798b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
1180af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman                                                  MachineBasicBlock *BB) const {
11812625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned Opc = MI->getOpcode();
11822625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11832625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 ||
11842625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      Opc == MSP430::Sra8 || Opc == MSP430::Sra16 ||
11852625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      Opc == MSP430::Srl8 || Opc == MSP430::Srl16)
1186af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman    return EmitShiftInstr(MI, BB);
11872625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11888b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
11898b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  DebugLoc dl = MI->getDebugLoc();
11902625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11912625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  assert((Opc == MSP430::Select16 || Opc == MSP430::Select8) &&
11928b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov         "Unexpected instr type to insert");
11938b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
11948b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // To "insert" a SELECT instruction, we actually have to insert the diamond
11958b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // control-flow pattern.  The incoming instruction knows the destination vreg
11968b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // to set, the condition code register to branch on, the true/false values to
11978b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // select between, and a branch opcode to use.
11988b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  const BasicBlock *LLVM_BB = BB->getBasicBlock();
11998b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineFunction::iterator I = BB;
12008b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  ++I;
12018b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
12028b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  thisMBB:
12038b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  ...
12048b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   TrueVal = ...
12058b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   cmpTY ccX, r1, r2
12068b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   jCC copy1MBB
12078b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   fallthrough --> copy0MBB
12088b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineBasicBlock *thisMBB = BB;
12098b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineFunction *F = BB->getParent();
12108b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
12118b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB);
12128b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  F->insert(I, copy0MBB);
12138b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  F->insert(I, copy1MBB);
12148b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // Update machine-CFG edges by transferring all successors of the current
12158b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // block to the new block which will contain the Phi node for the select.
121614152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  copy1MBB->splice(copy1MBB->begin(), BB,
121714152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman                   llvm::next(MachineBasicBlock::iterator(MI)),
121814152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman                   BB->end());
121914152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  copy1MBB->transferSuccessorsAndUpdatePHIs(BB);
12208b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // Next, add the true and fallthrough blocks as its successors.
12218b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB->addSuccessor(copy0MBB);
12228b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB->addSuccessor(copy1MBB);
12238b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
122414152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  BuildMI(BB, dl, TII.get(MSP430::JCC))
122514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman    .addMBB(copy1MBB)
122614152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman    .addImm(MI->getOperand(3).getImm());
122714152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman
12288b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  copy0MBB:
12298b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   %FalseValue = ...
12308b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   # fallthrough to copy1MBB
12318b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB = copy0MBB;
12328b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
12338b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // Update machine-CFG edges
12348b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB->addSuccessor(copy1MBB);
12358b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
12368b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  copy1MBB:
12378b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
12388b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  ...
12398b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB = copy1MBB;
124014152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  BuildMI(*BB, BB->begin(), dl, TII.get(MSP430::PHI),
12418b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov          MI->getOperand(0).getReg())
12428b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB)
12438b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB);
12448b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
124514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  MI->eraseFromParent();   // The pseudo instruction is gone now.
12468b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  return BB;
12478b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov}
1248