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);
17227253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov  setOperationAction(ISD::JumpTable,        MVT::i16,   Custom);
1730ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov
174b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  // Libcalls names.
175b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  if (HWMultMode == HWMultIntr) {
176b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I8,  "__mulqi3hw");
177b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I16, "__mulhi3hw");
178b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  } else if (HWMultMode == HWMultNoIntr) {
179b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I8,  "__mulqi3hw_noint");
180b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I16, "__mulhi3hw_noint");
181b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  }
182fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman
183fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman  setMinFunctionAlignment(1);
184fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman  setPrefFunctionAlignment(2);
185f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
186f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
187d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerOperation(SDValue Op,
188d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                             SelectionDAG &DAG) const {
189f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  switch (Op.getOpcode()) {
190ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov  case ISD::SHL: // FALLTHROUGH
191e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  case ISD::SRL:
1924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  case ISD::SRA:              return LowerShifts(Op, DAG);
1933513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  case ISD::GlobalAddress:    return LowerGlobalAddress(Op, DAG);
19469d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov  case ISD::BlockAddress:     return LowerBlockAddress(Op, DAG);
1955d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  case ISD::ExternalSymbol:   return LowerExternalSymbol(Op, DAG);
1968d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  case ISD::SETCC:            return LowerSETCC(Op, DAG);
1971bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case ISD::BR_CC:            return LowerBR_CC(Op, DAG);
1981bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case ISD::SELECT_CC:        return LowerSELECT_CC(Op, DAG);
199b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  case ISD::SIGN_EXTEND:      return LowerSIGN_EXTEND(Op, DAG);
20006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  case ISD::RETURNADDR:       return LowerRETURNADDR(Op, DAG);
20106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  case ISD::FRAMEADDR:        return LowerFRAMEADDR(Op, DAG);
2020ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  case ISD::VASTART:          return LowerVASTART(Op, DAG);
20327253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov  case ISD::JumpTable:        return LowerJumpTable(Op, DAG);
204f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  default:
205c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("unimplemented operand");
206f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  }
207f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
208f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
209c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===//
210cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//                       MSP430 Inline Assembly Support
211cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===//
212cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
213cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// getConstraintType - Given a constraint letter, return the type of
214cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// constraint it is for this target.
215cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovTargetLowering::ConstraintType
216cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering::getConstraintType(const std::string &Constraint) const {
217cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  if (Constraint.size() == 1) {
218cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    switch (Constraint[0]) {
219cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    case 'r':
220cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      return C_RegisterClass;
221cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    default:
222cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      break;
223cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    }
224cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  }
225cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  return TargetLowering::getConstraintType(Constraint);
226cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov}
227cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
228cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikovstd::pair<unsigned, const TargetRegisterClass*>
229cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering::
230cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovgetRegForInlineAsmConstraint(const std::string &Constraint,
2315b3fca50a08865f0db55fc92ad1c037a04e12177Chad Rosier                             MVT VT) const {
232cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  if (Constraint.size() == 1) {
233cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    // GCC Constraint Letters
234cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    switch (Constraint[0]) {
235cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    default: break;
236cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    case 'r':   // GENERAL_REGS
237cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      if (VT == MVT::i8)
238420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper        return std::make_pair(0U, &MSP430::GR8RegClass);
239cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
240420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper      return std::make_pair(0U, &MSP430::GR16RegClass);
241cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    }
242cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  }
243cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
244cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
245cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov}
246cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
247cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===//
248c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//                      Calling Convention Implementation
249c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===//
250c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
251f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430GenCallingConv.inc"
252c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
25398ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
25498ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerFormalArguments(SDValue Chain,
25565c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                           CallingConv::ID CallConv,
25698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           bool isVarArg,
25798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           const SmallVectorImpl<ISD::InputArg>
25898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                             &Ins,
259ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                           SDLoc dl,
26098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           SelectionDAG &DAG,
261d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                           SmallVectorImpl<SDValue> &InVals)
262d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                             const {
26398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
26498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  switch (CallConv) {
265c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  default:
266c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Unsupported calling convention");
267c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  case CallingConv::C:
268c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  case CallingConv::Fast:
26998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman    return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals);
270e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  case CallingConv::MSP430_INTR:
2714d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    if (Ins.empty())
2724d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie      return Chain;
27375361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("ISRs cannot have arguments");
274c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  }
275c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov}
276c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
27798ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
278d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin HolewinskiMSP430TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
279d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                SmallVectorImpl<SDValue> &InVals) const {
280d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SelectionDAG &DAG                     = CLI.DAG;
281ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc &dl                             = CLI.DL;
282a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper  SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
283a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper  SmallVectorImpl<SDValue> &OutVals     = CLI.OutVals;
284a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper  SmallVectorImpl<ISD::InputArg> &Ins   = CLI.Ins;
285d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SDValue Chain                         = CLI.Chain;
286d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SDValue Callee                        = CLI.Callee;
287d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  bool &isTailCall                      = CLI.IsTailCall;
288d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  CallingConv::ID CallConv              = CLI.CallConv;
289d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  bool isVarArg                         = CLI.IsVarArg;
290d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski
2910c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng  // MSP430 target does not yet support tail call optimization.
2920c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng  isTailCall = false;
29398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
29498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  switch (CallConv) {
2954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  default:
296c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Unsupported calling convention");
2974428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  case CallingConv::Fast:
2984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  case CallingConv::C:
29998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman    return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
300c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman                          Outs, OutVals, Ins, dl, DAG, InVals);
301e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  case CallingConv::MSP430_INTR:
30275361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("ISRs cannot be called directly");
3034428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
3044428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov}
3054428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
306c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// LowerCCCArguments - transform physical registers into virtual registers and
307c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// generate load operations for arguments places on the stack.
308c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// FIXME: struct return stuff
30998ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
31098ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCArguments(SDValue Chain,
31165c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                        CallingConv::ID CallConv,
31298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        bool isVarArg,
31398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        const SmallVectorImpl<ISD::InputArg>
31498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                          &Ins,
315ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                        SDLoc dl,
31698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        SelectionDAG &DAG,
317d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                        SmallVectorImpl<SDValue> &InVals)
318d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                          const {
319c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  MachineFunction &MF = DAG.getMachineFunction();
320c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  MachineFrameInfo *MFI = MF.getFrameInfo();
321c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  MachineRegisterInfo &RegInfo = MF.getRegInfo();
3220ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
323c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
324c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  // Assign locations to all of the incoming arguments.
325c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  SmallVector<CCValAssign, 16> ArgLocs;
326471e4224809f51652c71f319532697a879a75a0dEric Christopher  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
32756cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling                 getTargetMachine(), ArgLocs, *DAG.getContext());
32898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCInfo.AnalyzeFormalArguments(Ins, CC_MSP430);
329c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
3300ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  // Create frame index for the start of the first vararg value
3310ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  if (isVarArg) {
3320ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov    unsigned Offset = CCInfo.getNextStackOffset();
3330ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov    FuncInfo->setVarArgsFrameIndex(MFI->CreateFixedObject(1, Offset, true));
3340ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  }
335c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
336c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
337c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    CCValAssign &VA = ArgLocs[i];
338c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    if (VA.isRegLoc()) {
339c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      // Arguments passed in registers
340e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson      EVT RegVT = VA.getLocVT();
341825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      switch (RegVT.getSimpleVT().SimpleTy) {
34295771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson      default:
343804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin        {
344dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#ifndef NDEBUG
3454437ae213d5435390f0750213b53ec807c047f22Chris Lattner          errs() << "LowerFormalArguments Unhandled argument type: "
346825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson               << RegVT.getSimpleVT().SimpleTy << "\n";
347dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#endif
348c23197a26f34f559ea9797de51e187087c039c42Torok Edwin          llvm_unreachable(0);
349804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin        }
350825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      case MVT::i16:
351420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper        unsigned VReg = RegInfo.createVirtualRegister(&MSP430::GR16RegClass);
352c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        RegInfo.addLiveIn(VA.getLocReg(), VReg);
35398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman        SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, RegVT);
354c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
355c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        // If this is an 8-bit value, it is really passed promoted to 16
356c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        // bits. Insert an assert[sz]ext to capture this, then truncate to the
357c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        // right size.
358c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        if (VA.getLocInfo() == CCValAssign::SExt)
359c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov          ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue,
360c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov                                 DAG.getValueType(VA.getValVT()));
361c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        else if (VA.getLocInfo() == CCValAssign::ZExt)
362c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov          ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue,
363c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov                                 DAG.getValueType(VA.getValVT()));
364c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
365c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        if (VA.getLocInfo() != CCValAssign::Full)
366c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov          ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
367c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
36898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman        InVals.push_back(ArgValue);
369c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      }
370c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    } else {
371c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      // Sanity check
372c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      assert(VA.isMemLoc());
3736cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov
3746cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      SDValue InVal;
3756cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      ISD::ArgFlagsTy Flags = Ins[i].Flags;
3766cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov
3776cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      if (Flags.isByVal()) {
3786cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        int FI = MFI->CreateFixedObject(Flags.getByValSize(),
3796cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                                        VA.getLocMemOffset(), true);
3806cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        InVal = DAG.getFrameIndex(FI, getPointerTy());
3816cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      } else {
3826cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        // Load the argument to a virtual register
3836cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        unsigned ObjSize = VA.getLocVT().getSizeInBits()/8;
3846cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        if (ObjSize > 2) {
3856cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov            errs() << "LowerFormalArguments Unhandled argument type: "
3866cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                << EVT(VA.getLocVT()).getEVTString()
3876cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                << "\n";
3886cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        }
3896cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        // Create the frame index object for this incoming parameter...
3906cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);
3916cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov
3926cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        // Create the SelectionDAG nodes corresponding to a load
3936cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        //from this parameter
3946cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        SDValue FIN = DAG.getFrameIndex(FI, MVT::i16);
3956cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        InVal = DAG.getLoad(VA.getLocVT(), dl, Chain, FIN,
3966cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                            MachinePointerInfo::getFixedStack(FI),
3976cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                            false, false, false, 0);
398c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      }
3996cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov
4006cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      InVals.push_back(InVal);
401c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    }
402c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  }
403c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
40498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return Chain;
405c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov}
406fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
40798ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
40898ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerReturn(SDValue Chain,
40965c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                  CallingConv::ID CallConv, bool isVarArg,
41098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                  const SmallVectorImpl<ISD::OutputArg> &Outs,
411c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman                                  const SmallVectorImpl<SDValue> &OutVals,
412ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                  SDLoc dl, SelectionDAG &DAG) const {
41398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
414fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // CCValAssign - represent the assignment of the return value to a location
415fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  SmallVector<CCValAssign, 16> RVLocs;
416fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
417e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  // ISRs cannot return any value.
4184d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  if (CallConv == CallingConv::MSP430_INTR && !Outs.empty())
41975361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("ISRs cannot return any value");
420e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov
421fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // CCState - Info about the registers and stack slot.
422471e4224809f51652c71f319532697a879a75a0dEric Christopher  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
42356cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling                 getTargetMachine(), RVLocs, *DAG.getContext());
424fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
42598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  // Analize return values.
42698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCInfo.AnalyzeReturn(Outs, RetCC_MSP430);
427fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
428fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  SDValue Flag;
429294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen  SmallVector<SDValue, 4> RetOps(1, Chain);
430fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
431fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // Copy the result values into the output registers.
432fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  for (unsigned i = 0; i != RVLocs.size(); ++i) {
433fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    CCValAssign &VA = RVLocs[i];
434fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    assert(VA.isRegLoc() && "Can only return in registers!");
435fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
436fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
437c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman                             OutVals[i], Flag);
438fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
439dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov    // Guarantee that all emitted copies are stuck together,
440dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov    // avoiding something bad.
441fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    Flag = Chain.getValue(1);
442294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen    RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
443fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  }
444fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
445e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  unsigned Opc = (CallConv == CallingConv::MSP430_INTR ?
446e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov                  MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG);
447e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov
448294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen  RetOps[0] = Chain;  // Update chain.
449294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen
450294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen  // Add the flag if we have it.
451fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  if (Flag.getNode())
452294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen    RetOps.push_back(Flag);
453fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
454294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen  return DAG.getNode(Opc, dl, MVT::Other, &RetOps[0], RetOps.size());
455fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov}
456fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
4574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// LowerCCCCallTo - functions arguments are copied from virtual regs to
4584428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
4590bf3c99886bed6796eada8f65942ee6023fc6e89Job Noorman// TODO: sret.
46098ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
46198ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee,
46265c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                     CallingConv::ID CallConv, bool isVarArg,
46398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     bool isTailCall,
46498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     const SmallVectorImpl<ISD::OutputArg>
46598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                       &Outs,
466c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman                                     const SmallVectorImpl<SDValue> &OutVals,
46798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     const SmallVectorImpl<ISD::InputArg> &Ins,
468ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                     SDLoc dl, SelectionDAG &DAG,
469d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                     SmallVectorImpl<SDValue> &InVals) const {
4704428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Analyze operands of the call, assigning locations to each operand.
4714428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<CCValAssign, 16> ArgLocs;
472471e4224809f51652c71f319532697a879a75a0dEric Christopher  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
47356cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling                 getTargetMachine(), ArgLocs, *DAG.getContext());
4744428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
47598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCInfo.AnalyzeCallOperands(Outs, CC_MSP430);
4764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4774428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Get a count of how many bytes are to be pushed on the stack.
4784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  unsigned NumBytes = CCInfo.getNextStackOffset();
4794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Chain = DAG.getCALLSEQ_START(Chain ,DAG.getConstant(NumBytes,
4816e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick                                                      getPointerTy(), true),
4826e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick                               dl);
4834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass;
4854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<SDValue, 12> MemOpChains;
4864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SDValue StackPtr;
4874428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Walk the register/memloc assignments, inserting copies/loads.
4894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
4904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    CCValAssign &VA = ArgLocs[i];
4914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
492c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman    SDValue Arg = OutVals[i];
4934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4944428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    // Promote the value if needed.
4954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    switch (VA.getLocInfo()) {
496c23197a26f34f559ea9797de51e187087c039c42Torok Edwin      default: llvm_unreachable("Unknown loc info!");
4974428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::Full: break;
4984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::SExt:
4994428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
5004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        break;
5014428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::ZExt:
5024428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
5034428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        break;
5044428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::AExt:
5054428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
5064428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        break;
5074428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    }
5084428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    // Arguments that can be passed on register must be kept at RegsToPass
5104428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    // vector
5114428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    if (VA.isRegLoc()) {
5124428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
5134428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    } else {
5144428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      assert(VA.isMemLoc());
5154428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      if (StackPtr.getNode() == 0)
5174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SPW, getPointerTy());
5184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(),
5204428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                   StackPtr,
5214428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                   DAG.getIntPtrConstant(VA.getLocMemOffset()));
5224428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5236cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      SDValue MemOp;
5246cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      ISD::ArgFlagsTy Flags = Outs[i].Flags;
5256cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov
5266cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      if (Flags.isByVal()) {
5276cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), MVT::i16);
5286cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        MemOp = DAG.getMemcpy(Chain, dl, PtrOff, Arg, SizeNode,
5296cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                              Flags.getByValAlign(),
5306cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                              /*isVolatile*/false,
5316cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                              /*AlwaysInline=*/true,
5326cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                              MachinePointerInfo(),
5336cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                              MachinePointerInfo());
5346cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      } else {
5356cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        MemOp = DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo(),
5366cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                             false, false, 0);
5376cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      }
5384428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5396cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      MemOpChains.push_back(MemOp);
5404428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    }
5414428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
5424428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5434428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Transform all store nodes into one single node because all store nodes are
5444428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // independent of each other.
5454428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  if (!MemOpChains.empty())
546825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
5474428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                        &MemOpChains[0], MemOpChains.size());
5484428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5494428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Build a sequence of copy-to-reg nodes chained together with token chain and
5504428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // flag operands which copy the outgoing args into registers.  The InFlag in
5517a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner  // necessary since all emitted instructions must be stuck together.
5524428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SDValue InFlag;
5534428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
5544428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
5554428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             RegsToPass[i].second, InFlag);
5564428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    InFlag = Chain.getValue(1);
5574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
5584428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5594428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // If the callee is a GlobalAddress node (quite common, every direct call is)
5604428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
5614428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Likewise ExternalSymbol -> TargetExternalSymbol.
5624428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
5630d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel    Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i16);
5644428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
565825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i16);
5664428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5674428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Returns a chain & a flag for retval copy to use.
568f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner  SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
5694428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<SDValue, 8> Ops;
5704428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Ops.push_back(Chain);
5714428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Ops.push_back(Callee);
5724428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5734428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Add argument registers to the end of the list so that they are
5744428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // known live into the call.
5754428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
5764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Ops.push_back(DAG.getRegister(RegsToPass[i].first,
5774428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                  RegsToPass[i].second.getValueType()));
5784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  if (InFlag.getNode())
5804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Ops.push_back(InFlag);
5814428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Chain = DAG.getNode(MSP430ISD::CALL, dl, NodeTys, &Ops[0], Ops.size());
5834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  InFlag = Chain.getValue(1);
5844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Create the CALLSEQ_END node.
5864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Chain = DAG.getCALLSEQ_END(Chain,
5874428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             DAG.getConstant(NumBytes, getPointerTy(), true),
5884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             DAG.getConstant(0, getPointerTy(), true),
5896e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick                             InFlag, dl);
5904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  InFlag = Chain.getValue(1);
5914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Handle result values, copying them out of physregs into vregs that we
5934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // return.
59498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl,
59598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                         DAG, InVals);
5964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov}
5974428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
59898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// LowerCallResult - Lower the result values of a call into the
59998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// appropriate copies out of appropriate physical registers.
60098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman///
60198ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
6024428885c5acfffbbdd03ad2aab23960531c47753Anton KorobeynikovMSP430TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag,
60365c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                      CallingConv::ID CallConv, bool isVarArg,
60498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                      const SmallVectorImpl<ISD::InputArg> &Ins,
605ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                      SDLoc dl, SelectionDAG &DAG,
606d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                      SmallVectorImpl<SDValue> &InVals) const {
6074428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
6084428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Assign locations to each value returned by this call.
6094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<CCValAssign, 16> RVLocs;
610471e4224809f51652c71f319532697a879a75a0dEric Christopher  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
61156cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling                 getTargetMachine(), RVLocs, *DAG.getContext());
6124428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
61398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  CCInfo.AnalyzeCallResult(Ins, RetCC_MSP430);
6144428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
6154428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Copy all of the result registers out of their specified physreg.
6164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0; i != RVLocs.size(); ++i) {
6174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(),
6184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                               RVLocs[i].getValVT(), InFlag).getValue(1);
6194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    InFlag = Chain.getValue(2);
62098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman    InVals.push_back(Chain.getValue(0));
6214428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
6224428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
62398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return Chain;
6244428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov}
6254428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
626d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton KorobeynikovSDValue MSP430TargetLowering::LowerShifts(SDValue Op,
627d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                          SelectionDAG &DAG) const {
628ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov  unsigned Opc = Op.getOpcode();
629d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  SDNode* N = Op.getNode();
630e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = Op.getValueType();
631ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(N);
632d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
6332625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Expand non-constant shifts to loops:
634d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  if (!isa<ConstantSDNode>(N->getOperand(1)))
6352625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    switch (Opc) {
636bc2198133a1836598b54b943420748e75d5dea94Craig Topper    default: llvm_unreachable("Invalid shift opcode!");
6372625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    case ISD::SHL:
6382625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      return DAG.getNode(MSP430ISD::SHL, dl,
6392625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                         VT, N->getOperand(0), N->getOperand(1));
6402625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    case ISD::SRA:
6412625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      return DAG.getNode(MSP430ISD::SRA, dl,
6422625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                         VT, N->getOperand(0), N->getOperand(1));
6432625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    case ISD::SRL:
6442625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      return DAG.getNode(MSP430ISD::SRL, dl,
6452625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                         VT, N->getOperand(0), N->getOperand(1));
6462625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    }
647d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
648d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
649d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
650d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  // Expand the stuff into sequence of shifts.
651d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  // FIXME: for some shift amounts this might be done better!
652d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N
653d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  SDValue Victim = N->getOperand(0);
654e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov
655e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  if (Opc == ISD::SRL && ShiftAmount) {
656e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov    // Emit a special goodness here:
657e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov    // srl A, 1 => clrc; rrc A
658bf8ef3f29de28529b5d65970af9015c41f7c809bAnton Korobeynikov    Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim);
659e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov    ShiftAmount -= 1;
660e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  }
661e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov
662d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  while (ShiftAmount--)
663aceb620de855485a4fb2eed343d880d76f6c701cAnton Korobeynikov    Victim = DAG.getNode((Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA),
664ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov                         dl, VT, Victim);
665d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
666d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  return Victim;
667d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov}
668d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
669d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerGlobalAddress(SDValue Op,
670d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                                 SelectionDAG &DAG) const {
6713513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
6723513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();
6733513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov
6743513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  // Create the TargetGlobalAddress node, folding in the constant offset.
675ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDValue Result = DAG.getTargetGlobalAddress(GV, SDLoc(Op),
6760d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel                                              getPointerTy(), Offset);
677ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  return DAG.getNode(MSP430ISD::Wrapper, SDLoc(Op),
6783513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov                     getPointerTy(), Result);
6793513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov}
6803513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov
6815d59f68ade7573175f1ace09061a94286e59076bAnton KorobeynikovSDValue MSP430TargetLowering::LowerExternalSymbol(SDValue Op,
682d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                                  SelectionDAG &DAG) const {
683ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
6845d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol();
6855d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  SDValue Result = DAG.getTargetExternalSymbol(Sym, getPointerTy());
6865d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov
68790f20044ade3712c8b0c3f4ebe47d57ad15ae6ceChad Rosier  return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result);
6885d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov}
6895d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov
69069d5b48bc31b7a443355cdf1506005804b4f63e6Anton KorobeynikovSDValue MSP430TargetLowering::LowerBlockAddress(SDValue Op,
69169d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov                                                SelectionDAG &DAG) const {
692ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
69369d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov  const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
6946c7ccaa3fd1d6e96d0bf922554b09d2b17c3b0e3Michael Liao  SDValue Result = DAG.getTargetBlockAddress(BA, getPointerTy());
69569d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov
69690f20044ade3712c8b0c3f4ebe47d57ad15ae6ceChad Rosier  return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result);
69769d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov}
69869d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov
6993926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikovstatic SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC,
7001bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov                       ISD::CondCode CC,
701ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                       SDLoc dl, SelectionDAG &DAG) {
702ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  // FIXME: Handle bittests someday
703ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet");
704ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
705ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  // FIXME: Handle jump negative someday
7063926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  MSP430CC::CondCodes TCC = MSP430CC::COND_INVALID;
707ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  switch (CC) {
708c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Invalid integer condition!");
709ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETEQ:
7103926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_E;     // aka COND_Z
711f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    // Minor optimization: if LHS is a constant, swap operands, then the
7121722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov    // constant can be folded into comparison.
713f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    if (LHS.getOpcode() == ISD::Constant)
7141722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov      std::swap(LHS, RHS);
715ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
716ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETNE:
7173926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_NE;    // aka COND_NZ
718f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    // Minor optimization: if LHS is a constant, swap operands, then the
7191722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov    // constant can be folded into comparison.
720f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    if (LHS.getOpcode() == ISD::Constant)
7211722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov      std::swap(LHS, RHS);
722ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
723ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETULE:
724ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
725ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETUGE:
7260c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // Turn lhs u>= rhs with lhs constant into rhs u< lhs+1, this allows us to
7270c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
7280c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
7290c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
7300c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
7310c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_LO;
7320c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
7330c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
7343926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_HS;    // aka COND_C
735ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
736ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETUGT:
737ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
738ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETULT:
7390c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // Turn lhs u< rhs with lhs constant into rhs u>= lhs+1, this allows us to
7400c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
7410c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
7420c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
7430c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
7440c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_HS;
7450c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
7460c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
7473926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_LO;    // aka COND_NC
748ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
749ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETLE:
750ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
751ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETGE:
7520c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // Turn lhs >= rhs with lhs constant into rhs < lhs+1, this allows us to
7530c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
7540c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
7550c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
7560c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
7570c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_L;
7580c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
7590c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
7603926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_GE;
761ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
762ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETGT:
763ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
764ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETLT:
7650c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to
7660c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
7670c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
7680c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
7690c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
7700c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_GE;
7710c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
7720c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
7733926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_L;
774ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
775ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  }
776ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
7773926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  TargetCC = DAG.getConstant(TCC, MVT::i8);
778f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner  return DAG.getNode(MSP430ISD::CMP, dl, MVT::Glue, LHS, RHS);
779ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov}
780ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
7811bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
782d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
783ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  SDValue Chain = Op.getOperand(0);
7841bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
7851bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue LHS   = Op.getOperand(2);
7861bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue RHS   = Op.getOperand(3);
7871bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue Dest  = Op.getOperand(4);
788ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl  (Op);
7891bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
7903926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  SDValue TargetCC;
7911bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
7921bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
7931bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(),
7943926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov                     Chain, Dest, TargetCC, Flag);
795ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov}
796ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
797d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
7988d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue LHS   = Op.getOperand(0);
7998d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue RHS   = Op.getOperand(1);
800ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl  (Op);
8018d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov
8028d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // If we are doing an AND and testing against zero, then the CMP
8038d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // will not be generated.  The AND (or BIT) will generate the condition codes,
8048d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // but they are different from CMP.
805cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov  // FIXME: since we're doing a post-processing, use a pseudoinstr here, so
806cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov  // lowering & isel wouldn't diverge.
8078d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool andCC = false;
8088d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) {
8098d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    if (RHSC->isNullValue() && LHS.hasOneUse() &&
8108d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov        (LHS.getOpcode() == ISD::AND ||
8118d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov         (LHS.getOpcode() == ISD::TRUNCATE &&
8128d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov          LHS.getOperand(0).getOpcode() == ISD::AND))) {
8138d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov      andCC = true;
8148d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    }
8158d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  }
8168d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
8178d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue TargetCC;
8188d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
8198d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov
8208d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // Get the condition codes directly from the status register, if its easy.
8218d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // Otherwise a branch will be generated.  Note that the AND and BIT
8228d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // instructions generate different flags than CMP, the carry bit can be used
8238d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // for NE/EQ.
8248d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool Invert = false;
8258d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool Shift = false;
8268d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool Convert = true;
8278d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  switch (cast<ConstantSDNode>(TargetCC)->getZExtValue()) {
8288d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov   default:
8298d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Convert = false;
8308d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    break;
8318d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov   case MSP430CC::COND_HS:
8328d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     // Res = SRW & 1, no processing is required
8338d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
834cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov   case MSP430CC::COND_LO:
8358d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     // Res = ~(SRW & 1)
8368d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     Invert = true;
8378d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
838cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov   case MSP430CC::COND_NE:
8398d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     if (andCC) {
8408d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov       // C = ~Z, thus Res = SRW & 1, no processing is required
8418d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     } else {
842455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov       // Res = ~((SRW >> 1) & 1)
8438d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov       Shift = true;
844455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov       Invert = true;
8458d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     }
8468d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
847cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov   case MSP430CC::COND_E:
848455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov     Shift = true;
849455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov     // C = ~Z for AND instruction, thus we can put Res = ~(SRW & 1), however,
850455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov     // Res = (SRW >> 1) & 1 is 1 word shorter.
8518d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
8528d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  }
8538d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  EVT VT = Op.getValueType();
8548d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue One  = DAG.getConstant(1, VT);
8558d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  if (Convert) {
8568d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SRW,
857cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov                                    MVT::i16, Flag);
8588d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    if (Shift)
8598d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov      // FIXME: somewhere this is turned into a SRL, lower it MSP specific?
8608d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov      SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One);
8618d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    SR = DAG.getNode(ISD::AND, dl, MVT::i16, SR, One);
8628d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    if (Invert)
8638d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov      SR = DAG.getNode(ISD::XOR, dl, MVT::i16, SR, One);
8648d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    return SR;
8658d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  } else {
8668d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    SDValue Zero = DAG.getConstant(0, VT);
867f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner    SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
8688d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    SmallVector<SDValue, 4> Ops;
8698d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Ops.push_back(One);
8708d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Ops.push_back(Zero);
8718d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Ops.push_back(TargetCC);
8728d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Ops.push_back(Flag);
8738d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size());
8748d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  }
8758d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov}
8768d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov
877d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op,
878d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                             SelectionDAG &DAG) const {
8791bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue LHS    = Op.getOperand(0);
8801bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue RHS    = Op.getOperand(1);
8811bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue TrueV  = Op.getOperand(2);
8821bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue FalseV = Op.getOperand(3);
8831bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
884ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl   (Op);
8851bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
8863926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  SDValue TargetCC;
8871bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
8888b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
889f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner  SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
8908b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  SmallVector<SDValue, 4> Ops;
8918b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  Ops.push_back(TrueV);
8928b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  Ops.push_back(FalseV);
8933926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  Ops.push_back(TargetCC);
8941bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  Ops.push_back(Flag);
8958b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
8961bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size());
8978b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov}
8988b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
899b78e214274d397407b6167a293b7cd7c3b526ddeAnton KorobeynikovSDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op,
900d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                               SelectionDAG &DAG) const {
901b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  SDValue Val = Op.getOperand(0);
902e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT      = Op.getValueType();
903ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
904b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov
905825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  assert(VT == MVT::i16 && "Only support i16 for now!");
906b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov
907b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT,
908b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov                     DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val),
909b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov                     DAG.getValueType(Val.getValueType()));
910b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov}
911b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov
912d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue
913d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanMSP430TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) const {
91406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MachineFunction &MF = DAG.getMachineFunction();
91506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
91606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  int ReturnAddrIndex = FuncInfo->getRAIndex();
91706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
91806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  if (ReturnAddrIndex == 0) {
91906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    // Set up a frame object for the return address.
920426c2bf5cdd2173e4a33aea8cb92cf684a724f4bChandler Carruth    uint64_t SlotSize = TD->getPointerSize();
92106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(SlotSize, -SlotSize,
922ed2ae136d29dd36122d2476801e7d7a86e8301e3Evan Cheng                                                           true);
92306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    FuncInfo->setRAIndex(ReturnAddrIndex);
92406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  }
92506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
92606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy());
92706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov}
92806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
929d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op,
930d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                              SelectionDAG &DAG) const {
9312457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
9322457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng  MFI->setReturnAddressIsTaken(true);
9332457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng
93406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
935ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
93606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
93706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  if (Depth > 0) {
93806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
93906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    SDValue Offset =
940426c2bf5cdd2173e4a33aea8cb92cf684a724f4bChandler Carruth      DAG.getConstant(TD->getPointerSize(), MVT::i16);
94106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
94206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                       DAG.getNode(ISD::ADD, dl, getPointerTy(),
94306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                                   FrameAddr, Offset),
944d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                       MachinePointerInfo(), false, false, false, 0);
94506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  }
94606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
94706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  // Just load the return address.
94806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  SDValue RetAddrFI = getReturnAddressFrameIndex(DAG);
94906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
950d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                     RetAddrFI, MachinePointerInfo(), false, false, false, 0);
95106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov}
95206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
953d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op,
954d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                             SelectionDAG &DAG) const {
95506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
95606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MFI->setFrameAddressIsTaken(true);
9572457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng
95806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  EVT VT = Op.getValueType();
959ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);  // FIXME probably not meaningful
96006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
96106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl,
96206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                                         MSP430::FPW, VT);
96306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  while (Depth--)
964d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner    FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
965d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner                            MachinePointerInfo(),
966d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                            false, false, false, 0);
96706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  return FrameAddr;
96806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov}
96906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
9700ae61240341ca76e1329f251c64d2f475fa89278Anton KorobeynikovSDValue MSP430TargetLowering::LowerVASTART(SDValue Op,
9710ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov                                           SelectionDAG &DAG) const {
9720ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  MachineFunction &MF = DAG.getMachineFunction();
9730ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
9740ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov
9750ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  // Frame index of first vararg argument
9760ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  SDValue FrameIndex = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),
9770ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov                                         getPointerTy());
9780ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
9790ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov
9800ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  // Create a store of the frame index to the location operand
981ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  return DAG.getStore(Op.getOperand(0), SDLoc(Op), FrameIndex,
9820ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov                      Op.getOperand(1), MachinePointerInfo(SV),
9830ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov                      false, false, 0);
9840ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov}
9850ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov
98627253f5edd04791bfbd0b5dd6e228be1d8071fceAnton KorobeynikovSDValue MSP430TargetLowering::LowerJumpTable(SDValue Op,
98727253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov                                             SelectionDAG &DAG) const {
98827253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov    JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
98927253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov    SDValue Result = DAG.getTargetJumpTable(JT->getIndex(), getPointerTy());
990a77f816c4c6e4c833ac9ab78e2e038dcfb861c73Anton Korobeynikov    return DAG.getNode(MSP430ISD::Wrapper, SDLoc(JT),
991a77f816c4c6e4c833ac9ab78e2e038dcfb861c73Anton Korobeynikov                       getPointerTy(), Result);
99227253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov}
99327253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov
9946534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// getPostIndexedAddressParts - returns true by value, base pointer and
9956534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// offset pointer and addressing mode by reference if this node can be
9966534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// combined with a load / store to form a post-indexed load / store.
9976534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikovbool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
9986534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      SDValue &Base,
9996534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      SDValue &Offset,
10006534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      ISD::MemIndexedMode &AM,
10016534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      SelectionDAG &DAG) const {
10026534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
10036534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  LoadSDNode *LD = cast<LoadSDNode>(N);
10046534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (LD->getExtensionType() != ISD::NON_EXTLOAD)
10056534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return false;
10066534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
10076534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  EVT VT = LD->getMemoryVT();
10086534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (VT != MVT::i8 && VT != MVT::i16)
10096534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return false;
10106534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
10116534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (Op->getOpcode() != ISD::ADD)
10126534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return false;
10136534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
10146534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) {
10156534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    uint64_t RHSC = RHS->getZExtValue();
10166534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    if ((VT == MVT::i16 && RHSC != 2) ||
10176534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov        (VT == MVT::i8 && RHSC != 1))
10186534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov      return false;
10196534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
10206534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    Base = Op->getOperand(0);
10216534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    Offset = DAG.getConstant(RHSC, VT);
10226534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    AM = ISD::POST_INC;
10236534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return true;
10246534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  }
10256534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
10266534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  return false;
10276534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov}
10286534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
10296534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
1030fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikovconst char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
1031fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  switch (Opcode) {
1032fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  default: return NULL;
1033fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  case MSP430ISD::RET_FLAG:           return "MSP430ISD::RET_FLAG";
10346bfcba7e137113e5f38cc4f937ad61cc7253ec74Anton Korobeynikov  case MSP430ISD::RETI_FLAG:          return "MSP430ISD::RETI_FLAG";
1035d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  case MSP430ISD::RRA:                return "MSP430ISD::RRA";
1036e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  case MSP430ISD::RLA:                return "MSP430ISD::RLA";
1037e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  case MSP430ISD::RRC:                return "MSP430ISD::RRC";
1038b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov  case MSP430ISD::CALL:               return "MSP430ISD::CALL";
10393513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  case MSP430ISD::Wrapper:            return "MSP430ISD::Wrapper";
10401bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case MSP430ISD::BR_CC:              return "MSP430ISD::BR_CC";
1041ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case MSP430ISD::CMP:                return "MSP430ISD::CMP";
10421bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case MSP430ISD::SELECT_CC:          return "MSP430ISD::SELECT_CC";
10432625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430ISD::SHL:                return "MSP430ISD::SHL";
10442625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430ISD::SRA:                return "MSP430ISD::SRA";
1045fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  }
1046fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov}
10478b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
1048db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattnerbool MSP430TargetLowering::isTruncateFree(Type *Ty1,
1049db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner                                          Type *Ty2) const {
1050b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands  if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
10519afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov    return false;
10529afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
10539afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  return (Ty1->getPrimitiveSizeInBits() > Ty2->getPrimitiveSizeInBits());
10549afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov}
10559afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
10569afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikovbool MSP430TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
10579afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  if (!VT1.isInteger() || !VT2.isInteger())
10589afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov    return false;
10599afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
10609afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  return (VT1.getSizeInBits() > VT2.getSizeInBits());
10619afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov}
10629afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
1063db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattnerbool MSP430TargetLowering::isZExtFree(Type *Ty1, Type *Ty2) const {
10649afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
1065b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands  return 0 && Ty1->isIntegerTy(8) && Ty2->isIntegerTy(16);
10669afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov}
10679afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
10689afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikovbool MSP430TargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
10699afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
10709afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  return 0 && VT1 == MVT::i8 && VT2 == MVT::i16;
10719afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov}
10729afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
1073968b667e27d7fc9a5bf5da52191a7af629e174dcEli Benderskybool MSP430TargetLowering::isZExtFree(SDValue Val, EVT VT2) const {
1074968b667e27d7fc9a5bf5da52191a7af629e174dcEli Bendersky  return isZExtFree(Val.getValueType(), VT2);
1075968b667e27d7fc9a5bf5da52191a7af629e174dcEli Bendersky}
1076968b667e27d7fc9a5bf5da52191a7af629e174dcEli Bendersky
10778b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===//
10788b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//  Other Lowering Code
10798b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===//
10808b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
10818b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMachineBasicBlock*
10822625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMSP430TargetLowering::EmitShiftInstr(MachineInstr *MI,
1083af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman                                     MachineBasicBlock *BB) const {
10842625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineFunction *F = BB->getParent();
10852625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineRegisterInfo &RI = F->getRegInfo();
10862625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  DebugLoc dl = MI->getDebugLoc();
10872625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
10882625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10892625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned Opc;
10902625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  const TargetRegisterClass * RC;
10912625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  switch (MI->getOpcode()) {
1092bc2198133a1836598b54b943420748e75d5dea94Craig Topper  default: llvm_unreachable("Invalid shift opcode!");
10932625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Shl8:
10942625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SHL8r1;
1095420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR8RegClass;
10962625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
10972625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Shl16:
10982625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SHL16r1;
1099420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR16RegClass;
11002625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
11012625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Sra8:
11022625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR8r1;
1103420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR8RegClass;
11042625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
11052625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Sra16:
11062625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR16r1;
1107420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR16RegClass;
11082625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
11092625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Srl8:
11102625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR8r1c;
1111420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR8RegClass;
11122625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
11132625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Srl16:
11142625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR16r1c;
1115420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR16RegClass;
11162625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
11172625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  }
11182625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11192625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  const BasicBlock *LLVM_BB = BB->getBasicBlock();
11202625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineFunction::iterator I = BB;
11212625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  ++I;
11222625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11232625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Create loop block
11242625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB);
11252625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineBasicBlock *RemBB  = F->CreateMachineBasicBlock(LLVM_BB);
11262625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11272625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  F->insert(I, LoopBB);
11282625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  F->insert(I, RemBB);
11292625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11302625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Update machine-CFG edges by transferring all successors of the current
11312625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // block to the block containing instructions after shift.
113214152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  RemBB->splice(RemBB->begin(), BB,
113314152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman                llvm::next(MachineBasicBlock::iterator(MI)),
113414152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman                BB->end());
113514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  RemBB->transferSuccessorsAndUpdatePHIs(BB);
11362625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11372625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Add adges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB
11382625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BB->addSuccessor(LoopBB);
11392625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BB->addSuccessor(RemBB);
11402625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  LoopBB->addSuccessor(RemBB);
11412625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  LoopBB->addSuccessor(LoopBB);
11422625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
1143420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper  unsigned ShiftAmtReg = RI.createVirtualRegister(&MSP430::GR8RegClass);
1144420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper  unsigned ShiftAmtReg2 = RI.createVirtualRegister(&MSP430::GR8RegClass);
11452625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned ShiftReg = RI.createVirtualRegister(RC);
11462625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned ShiftReg2 = RI.createVirtualRegister(RC);
11472625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned ShiftAmtSrcReg = MI->getOperand(2).getReg();
11482625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned SrcReg = MI->getOperand(1).getReg();
11492625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned DstReg = MI->getOperand(0).getReg();
11502625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11512625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // BB:
11522625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // cmp 0, N
11532625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // je RemBB
1154f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov  BuildMI(BB, dl, TII.get(MSP430::CMP8ri))
1155f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    .addReg(ShiftAmtSrcReg).addImm(0);
11562625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(BB, dl, TII.get(MSP430::JCC))
11572625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addMBB(RemBB)
11582625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addImm(MSP430CC::COND_E);
11592625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11602625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // LoopBB:
11612625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB]
11622625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // ShiftAmt = phi [%N, BB],      [%ShiftAmt2, LoopBB]
11632625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // ShiftReg2 = shift ShiftReg
11642625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // ShiftAmt2 = ShiftAmt - 1;
11652625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftReg)
11662625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(SrcReg).addMBB(BB)
11672625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftReg2).addMBB(LoopBB);
11682625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg)
11692625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftAmtSrcReg).addMBB(BB)
11702625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftAmtReg2).addMBB(LoopBB);
11712625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2)
11722625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftReg);
11732625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2)
11742625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftAmtReg).addImm(1);
11752625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::JCC))
11762625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addMBB(LoopBB)
11772625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addImm(MSP430CC::COND_NE);
11782625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11792625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // RemBB:
11802625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB]
118114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  BuildMI(*RemBB, RemBB->begin(), dl, TII.get(MSP430::PHI), DstReg)
11822625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(SrcReg).addMBB(BB)
11832625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftReg2).addMBB(LoopBB);
11842625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
118514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  MI->eraseFromParent();   // The pseudo instruction is gone now.
11862625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  return RemBB;
11872625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov}
11882625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11892625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMachineBasicBlock*
11908b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
1191af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman                                                  MachineBasicBlock *BB) const {
11922625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned Opc = MI->getOpcode();
11932625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11942625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 ||
11952625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      Opc == MSP430::Sra8 || Opc == MSP430::Sra16 ||
11962625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      Opc == MSP430::Srl8 || Opc == MSP430::Srl16)
1197af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman    return EmitShiftInstr(MI, BB);
11982625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11998b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
12008b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  DebugLoc dl = MI->getDebugLoc();
12012625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
12022625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  assert((Opc == MSP430::Select16 || Opc == MSP430::Select8) &&
12038b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov         "Unexpected instr type to insert");
12048b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
12058b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // To "insert" a SELECT instruction, we actually have to insert the diamond
12068b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // control-flow pattern.  The incoming instruction knows the destination vreg
12078b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // to set, the condition code register to branch on, the true/false values to
12088b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // select between, and a branch opcode to use.
12098b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  const BasicBlock *LLVM_BB = BB->getBasicBlock();
12108b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineFunction::iterator I = BB;
12118b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  ++I;
12128b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
12138b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  thisMBB:
12148b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  ...
12158b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   TrueVal = ...
12168b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   cmpTY ccX, r1, r2
12178b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   jCC copy1MBB
12188b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   fallthrough --> copy0MBB
12198b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineBasicBlock *thisMBB = BB;
12208b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineFunction *F = BB->getParent();
12218b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
12228b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB);
12238b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  F->insert(I, copy0MBB);
12248b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  F->insert(I, copy1MBB);
12258b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // Update machine-CFG edges by transferring all successors of the current
12268b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // block to the new block which will contain the Phi node for the select.
122714152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  copy1MBB->splice(copy1MBB->begin(), BB,
122814152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman                   llvm::next(MachineBasicBlock::iterator(MI)),
122914152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman                   BB->end());
123014152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  copy1MBB->transferSuccessorsAndUpdatePHIs(BB);
12318b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // Next, add the true and fallthrough blocks as its successors.
12328b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB->addSuccessor(copy0MBB);
12338b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB->addSuccessor(copy1MBB);
12348b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
123514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  BuildMI(BB, dl, TII.get(MSP430::JCC))
123614152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman    .addMBB(copy1MBB)
123714152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman    .addImm(MI->getOperand(3).getImm());
123814152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman
12398b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  copy0MBB:
12408b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   %FalseValue = ...
12418b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   # fallthrough to copy1MBB
12428b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB = copy0MBB;
12438b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
12448b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // Update machine-CFG edges
12458b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB->addSuccessor(copy1MBB);
12468b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
12478b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  copy1MBB:
12488b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
12498b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  ...
12508b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB = copy1MBB;
125114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  BuildMI(*BB, BB->begin(), dl, TII.get(MSP430::PHI),
12528b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov          MI->getOperand(0).getReg())
12538b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB)
12548b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB);
12558b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
125614152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  MI->eraseFromParent();   // The pseudo instruction is gone now.
12578b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  return BB;
12588b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov}
1259