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#include "MSP430ISelLowering.h"
15f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430.h"
1606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov#include "MSP430MachineFunctionInfo.h"
17f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430Subtarget.h"
18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "MSP430TargetMachine.h"
19f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/CallingConvLower.h"
20f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h"
21f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineFunction.h"
22f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h"
23f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineRegisterInfo.h"
24f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/SelectionDAGISel.h"
25362dd0bef5437f85586c046bc53287b6fbe9c099Anton Korobeynikov#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
26f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/ValueTypes.h"
270b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/CallingConv.h"
280b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h"
290b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h"
300b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/GlobalAlias.h"
310b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/GlobalVariable.h"
320b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Intrinsics.h"
33b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov#include "llvm/Support/CommandLine.h"
34f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/Support/Debug.h"
35804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin#include "llvm/Support/ErrorHandling.h"
364437ae213d5435390f0750213b53ec807c047f22Chris Lattner#include "llvm/Support/raw_ostream.h"
37f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovusing namespace llvm;
38f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
39dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "msp430-lower"
40dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
41b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikovtypedef enum {
42b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  NoHWMult,
43b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  HWMultIntr,
44b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  HWMultNoIntr
45b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov} HWMultUseMode;
46b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov
47b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikovstatic cl::opt<HWMultUseMode>
48fe16848601bdde6e3a5e0860199169dd171222a4Nadav RotemHWMultMode("msp430-hwmult-mode", cl::Hidden,
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
60cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMSP430TargetLowering::MSP430TargetLowering(const TargetMachine &TM)
61cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    : TargetLowering(TM, new TargetLoweringObjectFileELF()) {
6206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
63f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  // Set up the register classes.
64420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper  addRegisterClass(MVT::i8,  &MSP430::GR8RegClass);
65420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper  addRegisterClass(MVT::i16, &MSP430::GR16RegClass);
66f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
67f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  // Compute derived properties from the register classes
68f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  computeRegisterProperties();
69fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
701476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov  // Provide all sorts of operation actions
711476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov
721476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov  // Division is expensive
731476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov  setIntDivIsCheap(false);
741476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov
75c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov  setStackPointerRegisterToSaveRestore(MSP430::SPW);
76c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov  setBooleanContents(ZeroOrOneBooleanContent);
7728b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands  setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?
78c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov
7906ac0820a6cefa6896000054d8e4906326c0cce6Anton Korobeynikov  // We have post-incremented loads / stores.
806534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  setIndexedLoadAction(ISD::POST_INC, MVT::i8, Legal);
816534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  setIndexedLoadAction(ISD::POST_INC, MVT::i16, Legal);
826534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
836534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  setLoadExtAction(ISD::EXTLOAD,  MVT::i1,  Promote);
846534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  setLoadExtAction(ISD::SEXTLOAD, MVT::i1,  Promote);
856534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  setLoadExtAction(ISD::ZEXTLOAD, MVT::i1,  Promote);
866534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  setLoadExtAction(ISD::SEXTLOAD, MVT::i8,  Expand);
87825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Expand);
8836b6e533c1aac85452438161f7034a9f54bd1830Anton Korobeynikov
8954f30d3fc94e055f13e6744378323d05c5c050baAnton Korobeynikov  // We don't have any truncstores
90825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setTruncStoreAction(MVT::i16, MVT::i8, Expand);
91825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
92825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRA,              MVT::i8,    Custom);
93825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SHL,              MVT::i8,    Custom);
94825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRL,              MVT::i8,    Custom);
95825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRA,              MVT::i16,   Custom);
96825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SHL,              MVT::i16,   Custom);
97825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRL,              MVT::i16,   Custom);
98825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ROTL,             MVT::i8,    Expand);
99825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ROTR,             MVT::i8,    Expand);
100825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ROTL,             MVT::i16,   Expand);
101825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ROTR,             MVT::i16,   Expand);
102825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::GlobalAddress,    MVT::i16,   Custom);
103825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ExternalSymbol,   MVT::i16,   Custom);
10469d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov  setOperationAction(ISD::BlockAddress,     MVT::i16,   Custom);
105825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BR_JT,            MVT::Other, Expand);
106825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BR_CC,            MVT::i8,    Custom);
107825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BR_CC,            MVT::i16,   Custom);
108825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BRCOND,           MVT::Other, Expand);
1098d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  setOperationAction(ISD::SETCC,            MVT::i8,    Custom);
1108d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  setOperationAction(ISD::SETCC,            MVT::i16,   Custom);
111825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT,           MVT::i8,    Expand);
112825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT,           MVT::i16,   Expand);
113825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT_CC,        MVT::i8,    Custom);
114825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT_CC,        MVT::i16,   Custom);
115825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SIGN_EXTEND,      MVT::i16,   Custom);
116379a087cc7175532ff0c24c60069da5eec596879Anton Korobeynikov  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i8, Expand);
117379a087cc7175532ff0c24c60069da5eec596879Anton Korobeynikov  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i16, Expand);
118825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
119825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTTZ,             MVT::i8,    Expand);
120825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTTZ,             MVT::i16,   Expand);
12163974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth  setOperationAction(ISD::CTTZ_ZERO_UNDEF,  MVT::i8,    Expand);
12263974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth  setOperationAction(ISD::CTTZ_ZERO_UNDEF,  MVT::i16,   Expand);
123825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTLZ,             MVT::i8,    Expand);
124825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTLZ,             MVT::i16,   Expand);
12563974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth  setOperationAction(ISD::CTLZ_ZERO_UNDEF,  MVT::i8,    Expand);
12663974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth  setOperationAction(ISD::CTLZ_ZERO_UNDEF,  MVT::i16,   Expand);
127825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTPOP,            MVT::i8,    Expand);
128825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTPOP,            MVT::i16,   Expand);
129825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
130825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SHL_PARTS,        MVT::i8,    Expand);
131825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SHL_PARTS,        MVT::i16,   Expand);
132825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRL_PARTS,        MVT::i8,    Expand);
133825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRL_PARTS,        MVT::i16,   Expand);
134825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRA_PARTS,        MVT::i8,    Expand);
135825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRA_PARTS,        MVT::i16,   Expand);
136825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
137825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1,   Expand);
138e4ce880dfa340bf45ddce10bb1dbe856553677b6Eli Friedman
1398725bd22bf91c29e2351a127295c19fea996e2c7Anton Korobeynikov  // FIXME: Implement efficiently multiplication by a constant
1408983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::MUL,              MVT::i8,    Expand);
1418983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::MULHS,            MVT::i8,    Expand);
1428983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::MULHU,            MVT::i8,    Expand);
1438983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::SMUL_LOHI,        MVT::i8,    Expand);
1448983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::UMUL_LOHI,        MVT::i8,    Expand);
145825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::MUL,              MVT::i16,   Expand);
146825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::MULHS,            MVT::i16,   Expand);
147825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::MULHU,            MVT::i16,   Expand);
148825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SMUL_LOHI,        MVT::i16,   Expand);
149825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::UMUL_LOHI,        MVT::i16,   Expand);
150825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
1518983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::UDIV,             MVT::i8,    Expand);
1528983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::UDIVREM,          MVT::i8,    Expand);
1538983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::UREM,             MVT::i8,    Expand);
1548983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::SDIV,             MVT::i8,    Expand);
1558983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::SDIVREM,          MVT::i8,    Expand);
1568983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::SREM,             MVT::i8,    Expand);
157825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::UDIV,             MVT::i16,   Expand);
158825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::UDIVREM,          MVT::i16,   Expand);
159825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::UREM,             MVT::i16,   Expand);
160825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SDIV,             MVT::i16,   Expand);
161825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SDIVREM,          MVT::i16,   Expand);
162825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SREM,             MVT::i16,   Expand);
163b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov
1640ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  // varargs support
1650ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  setOperationAction(ISD::VASTART,          MVT::Other, Custom);
1660ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  setOperationAction(ISD::VAARG,            MVT::Other, Expand);
1670ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  setOperationAction(ISD::VAEND,            MVT::Other, Expand);
1680ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  setOperationAction(ISD::VACOPY,           MVT::Other, Expand);
16927253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov  setOperationAction(ISD::JumpTable,        MVT::i16,   Custom);
1700ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov
171b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  // Libcalls names.
172b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  if (HWMultMode == HWMultIntr) {
173b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I8,  "__mulqi3hw");
174b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I16, "__mulhi3hw");
175b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  } else if (HWMultMode == HWMultNoIntr) {
176b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I8,  "__mulqi3hw_noint");
177b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I16, "__mulhi3hw_noint");
178b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  }
179fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman
180fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman  setMinFunctionAlignment(1);
181fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman  setPrefFunctionAlignment(2);
182f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
183f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
184d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerOperation(SDValue Op,
185d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                             SelectionDAG &DAG) const {
186f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  switch (Op.getOpcode()) {
187ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov  case ISD::SHL: // FALLTHROUGH
188e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  case ISD::SRL:
1894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  case ISD::SRA:              return LowerShifts(Op, DAG);
1903513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  case ISD::GlobalAddress:    return LowerGlobalAddress(Op, DAG);
19169d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov  case ISD::BlockAddress:     return LowerBlockAddress(Op, DAG);
1925d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  case ISD::ExternalSymbol:   return LowerExternalSymbol(Op, DAG);
1938d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  case ISD::SETCC:            return LowerSETCC(Op, DAG);
1941bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case ISD::BR_CC:            return LowerBR_CC(Op, DAG);
1951bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case ISD::SELECT_CC:        return LowerSELECT_CC(Op, DAG);
196b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  case ISD::SIGN_EXTEND:      return LowerSIGN_EXTEND(Op, DAG);
19706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  case ISD::RETURNADDR:       return LowerRETURNADDR(Op, DAG);
19806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  case ISD::FRAMEADDR:        return LowerFRAMEADDR(Op, DAG);
1990ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  case ISD::VASTART:          return LowerVASTART(Op, DAG);
20027253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov  case ISD::JumpTable:        return LowerJumpTable(Op, DAG);
201f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  default:
202c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("unimplemented operand");
203f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  }
204f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
205f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
206c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===//
207cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//                       MSP430 Inline Assembly Support
208cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===//
209cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
210cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// getConstraintType - Given a constraint letter, return the type of
211cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// constraint it is for this target.
212cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovTargetLowering::ConstraintType
213cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering::getConstraintType(const std::string &Constraint) const {
214cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  if (Constraint.size() == 1) {
215cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    switch (Constraint[0]) {
216cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    case 'r':
217cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      return C_RegisterClass;
218cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    default:
219cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      break;
220cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    }
221cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  }
222cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  return TargetLowering::getConstraintType(Constraint);
223cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov}
224cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
225cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikovstd::pair<unsigned, const TargetRegisterClass*>
226cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering::
227cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovgetRegForInlineAsmConstraint(const std::string &Constraint,
2285b3fca50a08865f0db55fc92ad1c037a04e12177Chad Rosier                             MVT VT) const {
229cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  if (Constraint.size() == 1) {
230cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    // GCC Constraint Letters
231cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    switch (Constraint[0]) {
232cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    default: break;
233cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    case 'r':   // GENERAL_REGS
234cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      if (VT == MVT::i8)
235420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper        return std::make_pair(0U, &MSP430::GR8RegClass);
236cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
237420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper      return std::make_pair(0U, &MSP430::GR16RegClass);
238cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    }
239cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  }
240cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
241cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
242cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov}
243cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
244cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===//
245c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//                      Calling Convention Implementation
246c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===//
247c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
248f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430GenCallingConv.inc"
249c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
2503edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman/// For each argument in a function store the number of pieces it is composed
2513edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman/// of.
2523edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormantemplate<typename ArgT>
2533edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void ParseFunctionArgs(const SmallVectorImpl<ArgT> &Args,
2543edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman                              SmallVectorImpl<unsigned> &Out) {
2553edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  unsigned CurrentArgIndex = ~0U;
2563edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  for (unsigned i = 0, e = Args.size(); i != e; i++) {
2573edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    if (CurrentArgIndex == Args[i].OrigArgIndex) {
2583edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      Out.back()++;
2593edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    } else {
2603edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      Out.push_back(1);
2613edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      CurrentArgIndex++;
2623edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    }
2633edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  }
2643edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman}
2653edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
2663edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void AnalyzeVarArgs(CCState &State,
2673edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman                           const SmallVectorImpl<ISD::OutputArg> &Outs) {
2683edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  State.AnalyzeCallOperands(Outs, CC_MSP430_AssignStack);
2693edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman}
2703edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
2713edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void AnalyzeVarArgs(CCState &State,
2723edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman                           const SmallVectorImpl<ISD::InputArg> &Ins) {
2733edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  State.AnalyzeFormalArguments(Ins, CC_MSP430_AssignStack);
2743edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman}
2753edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
2763edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman/// Analyze incoming and outgoing function arguments. We need custom C++ code
2773edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman/// to handle special constraints in the ABI like reversing the order of the
2783edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman/// pieces of splitted arguments. In addition, all pieces of a certain argument
2793edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman/// have to be passed either using registers or the stack but never mixing both.
2803edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormantemplate<typename ArgT>
2813edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void AnalyzeArguments(CCState &State,
2823edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman                             SmallVectorImpl<CCValAssign> &ArgLocs,
2833edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman                             const SmallVectorImpl<ArgT> &Args) {
284dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  static const MCPhysReg RegList[] = {
2853edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    MSP430::R15W, MSP430::R14W, MSP430::R13W, MSP430::R12W
2863edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  };
2873edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  static const unsigned NbRegs = array_lengthof(RegList);
2883edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
2893edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  if (State.isVarArg()) {
2903edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    AnalyzeVarArgs(State, Args);
2913edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    return;
2923edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  }
2933edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
2943edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  SmallVector<unsigned, 4> ArgsParts;
2953edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  ParseFunctionArgs(Args, ArgsParts);
2963edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
2973edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  unsigned RegsLeft = NbRegs;
2983edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  bool UseStack = false;
2993edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  unsigned ValNo = 0;
3003edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
3013edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  for (unsigned i = 0, e = ArgsParts.size(); i != e; i++) {
3023edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    MVT ArgVT = Args[ValNo].VT;
3033edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    ISD::ArgFlagsTy ArgFlags = Args[ValNo].Flags;
3043edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    MVT LocVT = ArgVT;
3053edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    CCValAssign::LocInfo LocInfo = CCValAssign::Full;
3063edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
3073edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    // Promote i8 to i16
3083edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    if (LocVT == MVT::i8) {
3093edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      LocVT = MVT::i16;
3103edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      if (ArgFlags.isSExt())
3113edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman          LocInfo = CCValAssign::SExt;
3123edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      else if (ArgFlags.isZExt())
3133edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman          LocInfo = CCValAssign::ZExt;
3143edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      else
3153edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman          LocInfo = CCValAssign::AExt;
3163edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    }
3173edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
3183edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    // Handle byval arguments
3193edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    if (ArgFlags.isByVal()) {
3203edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      State.HandleByVal(ValNo++, ArgVT, LocVT, LocInfo, 2, 2, ArgFlags);
3213edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      continue;
3223edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    }
3233edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
3243edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    unsigned Parts = ArgsParts[i];
3253edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
3263edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    if (!UseStack && Parts <= RegsLeft) {
3273edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      unsigned FirstVal = ValNo;
3283edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      for (unsigned j = 0; j < Parts; j++) {
3293edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman        unsigned Reg = State.AllocateReg(RegList, NbRegs);
3303edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman        State.addLoc(CCValAssign::getReg(ValNo++, ArgVT, Reg, LocVT, LocInfo));
3313edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman        RegsLeft--;
3323edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      }
3333edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
3343edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      // Reverse the order of the pieces to agree with the "big endian" format
3353edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      // required in the calling convention ABI.
3363edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      SmallVectorImpl<CCValAssign>::iterator B = ArgLocs.begin() + FirstVal;
3373edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      std::reverse(B, B + Parts);
3383edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    } else {
3393edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      UseStack = true;
3403edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      for (unsigned j = 0; j < Parts; j++)
3413edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman        CC_MSP430_AssignStack(ValNo++, ArgVT, LocVT, LocInfo, ArgFlags, State);
3423edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    }
3433edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  }
3443edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman}
3453edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
3463edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void AnalyzeRetResult(CCState &State,
3473edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman                             const SmallVectorImpl<ISD::InputArg> &Ins) {
3483edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  State.AnalyzeCallResult(Ins, RetCC_MSP430);
3493edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman}
3503edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
3513edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void AnalyzeRetResult(CCState &State,
3523edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman                             const SmallVectorImpl<ISD::OutputArg> &Outs) {
3533edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  State.AnalyzeReturn(Outs, RetCC_MSP430);
3543edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman}
3553edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
3563edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormantemplate<typename ArgT>
3573edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void AnalyzeReturnValues(CCState &State,
3583edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman                                SmallVectorImpl<CCValAssign> &RVLocs,
3593edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman                                const SmallVectorImpl<ArgT> &Args) {
3603edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  AnalyzeRetResult(State, Args);
3613edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
3623edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  // Reverse splitted return values to get the "big endian" format required
3633edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  // to agree with the calling convention ABI.
3643edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  std::reverse(RVLocs.begin(), RVLocs.end());
3653edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman}
3663edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
36798ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
36898ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerFormalArguments(SDValue Chain,
36965c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                           CallingConv::ID CallConv,
37098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           bool isVarArg,
37198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           const SmallVectorImpl<ISD::InputArg>
37298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                             &Ins,
373ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                           SDLoc dl,
37498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           SelectionDAG &DAG,
375d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                           SmallVectorImpl<SDValue> &InVals)
376d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                             const {
37798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
37898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  switch (CallConv) {
379c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  default:
380c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Unsupported calling convention");
381c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  case CallingConv::C:
382c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  case CallingConv::Fast:
38398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman    return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals);
384e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  case CallingConv::MSP430_INTR:
3854d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    if (Ins.empty())
3864d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie      return Chain;
38775361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("ISRs cannot have arguments");
388c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  }
389c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov}
390c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
39198ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
392d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin HolewinskiMSP430TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
393d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                SmallVectorImpl<SDValue> &InVals) const {
394d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SelectionDAG &DAG                     = CLI.DAG;
395ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc &dl                             = CLI.DL;
396a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper  SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
397a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper  SmallVectorImpl<SDValue> &OutVals     = CLI.OutVals;
398a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper  SmallVectorImpl<ISD::InputArg> &Ins   = CLI.Ins;
399d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SDValue Chain                         = CLI.Chain;
400d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SDValue Callee                        = CLI.Callee;
401d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  bool &isTailCall                      = CLI.IsTailCall;
402d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  CallingConv::ID CallConv              = CLI.CallConv;
403d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  bool isVarArg                         = CLI.IsVarArg;
404d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski
4050c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng  // MSP430 target does not yet support tail call optimization.
4060c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng  isTailCall = false;
40798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
40898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  switch (CallConv) {
4094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  default:
410c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Unsupported calling convention");
4114428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  case CallingConv::Fast:
4124428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  case CallingConv::C:
41398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman    return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
414c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman                          Outs, OutVals, Ins, dl, DAG, InVals);
415e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  case CallingConv::MSP430_INTR:
41675361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("ISRs cannot be called directly");
4174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
4184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov}
4194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
420c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// LowerCCCArguments - transform physical registers into virtual registers and
421c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// generate load operations for arguments places on the stack.
422c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// FIXME: struct return stuff
42398ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
42498ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCArguments(SDValue Chain,
42565c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                        CallingConv::ID CallConv,
42698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        bool isVarArg,
42798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        const SmallVectorImpl<ISD::InputArg>
42898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                          &Ins,
429ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                        SDLoc dl,
43098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        SelectionDAG &DAG,
431d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                        SmallVectorImpl<SDValue> &InVals)
432d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                          const {
433c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  MachineFunction &MF = DAG.getMachineFunction();
434c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  MachineFrameInfo *MFI = MF.getFrameInfo();
435c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  MachineRegisterInfo &RegInfo = MF.getRegInfo();
4360ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
437c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
438c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  // Assign locations to all of the incoming arguments.
439c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  SmallVector<CCValAssign, 16> ArgLocs;
440471e4224809f51652c71f319532697a879a75a0dEric Christopher  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
44156cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling                 getTargetMachine(), ArgLocs, *DAG.getContext());
4423edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  AnalyzeArguments(CCInfo, ArgLocs, Ins);
443c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
4440ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  // Create frame index for the start of the first vararg value
4450ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  if (isVarArg) {
4460ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov    unsigned Offset = CCInfo.getNextStackOffset();
4470ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov    FuncInfo->setVarArgsFrameIndex(MFI->CreateFixedObject(1, Offset, true));
4480ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  }
449c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
450c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
451c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    CCValAssign &VA = ArgLocs[i];
452c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    if (VA.isRegLoc()) {
453c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      // Arguments passed in registers
454e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson      EVT RegVT = VA.getLocVT();
455825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      switch (RegVT.getSimpleVT().SimpleTy) {
45695771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson      default:
457804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin        {
458dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#ifndef NDEBUG
4594437ae213d5435390f0750213b53ec807c047f22Chris Lattner          errs() << "LowerFormalArguments Unhandled argument type: "
460825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson               << RegVT.getSimpleVT().SimpleTy << "\n";
461dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#endif
462dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          llvm_unreachable(nullptr);
463804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin        }
464825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      case MVT::i16:
465420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper        unsigned VReg = RegInfo.createVirtualRegister(&MSP430::GR16RegClass);
466c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        RegInfo.addLiveIn(VA.getLocReg(), VReg);
46798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman        SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, RegVT);
468c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
469c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        // If this is an 8-bit value, it is really passed promoted to 16
470c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        // bits. Insert an assert[sz]ext to capture this, then truncate to the
471c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        // right size.
472c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        if (VA.getLocInfo() == CCValAssign::SExt)
473c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov          ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue,
474c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov                                 DAG.getValueType(VA.getValVT()));
475c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        else if (VA.getLocInfo() == CCValAssign::ZExt)
476c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov          ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue,
477c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov                                 DAG.getValueType(VA.getValVT()));
478c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
479c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        if (VA.getLocInfo() != CCValAssign::Full)
480c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov          ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
481c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
48298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman        InVals.push_back(ArgValue);
483c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      }
484c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    } else {
485c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      // Sanity check
486c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      assert(VA.isMemLoc());
4876cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov
4886cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      SDValue InVal;
4896cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      ISD::ArgFlagsTy Flags = Ins[i].Flags;
4906cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov
4916cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      if (Flags.isByVal()) {
4926cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        int FI = MFI->CreateFixedObject(Flags.getByValSize(),
4936cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                                        VA.getLocMemOffset(), true);
4946cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        InVal = DAG.getFrameIndex(FI, getPointerTy());
4956cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      } else {
4966cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        // Load the argument to a virtual register
4976cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        unsigned ObjSize = VA.getLocVT().getSizeInBits()/8;
4986cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        if (ObjSize > 2) {
4996cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov            errs() << "LowerFormalArguments Unhandled argument type: "
5006cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                << EVT(VA.getLocVT()).getEVTString()
5016cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                << "\n";
5026cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        }
5036cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        // Create the frame index object for this incoming parameter...
5046cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);
5056cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov
5066cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        // Create the SelectionDAG nodes corresponding to a load
5076cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        //from this parameter
5086cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        SDValue FIN = DAG.getFrameIndex(FI, MVT::i16);
5096cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        InVal = DAG.getLoad(VA.getLocVT(), dl, Chain, FIN,
5106cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                            MachinePointerInfo::getFixedStack(FI),
5116cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                            false, false, false, 0);
512c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      }
5136cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov
5146cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      InVals.push_back(InVal);
515c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    }
516c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  }
517c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
51898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return Chain;
519c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov}
520fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
52198ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
52298ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerReturn(SDValue Chain,
52365c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                  CallingConv::ID CallConv, bool isVarArg,
52498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                  const SmallVectorImpl<ISD::OutputArg> &Outs,
525c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman                                  const SmallVectorImpl<SDValue> &OutVals,
526ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                  SDLoc dl, SelectionDAG &DAG) const {
52798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
528fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // CCValAssign - represent the assignment of the return value to a location
529fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  SmallVector<CCValAssign, 16> RVLocs;
530fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
531e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  // ISRs cannot return any value.
5324d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  if (CallConv == CallingConv::MSP430_INTR && !Outs.empty())
53375361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("ISRs cannot return any value");
534e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov
535fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // CCState - Info about the registers and stack slot.
536471e4224809f51652c71f319532697a879a75a0dEric Christopher  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
53756cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling                 getTargetMachine(), RVLocs, *DAG.getContext());
538fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
53998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  // Analize return values.
5403edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  AnalyzeReturnValues(CCInfo, RVLocs, Outs);
541fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
542fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  SDValue Flag;
543294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen  SmallVector<SDValue, 4> RetOps(1, Chain);
544fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
545fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // Copy the result values into the output registers.
546fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  for (unsigned i = 0; i != RVLocs.size(); ++i) {
547fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    CCValAssign &VA = RVLocs[i];
548fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    assert(VA.isRegLoc() && "Can only return in registers!");
549fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
550fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
551c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman                             OutVals[i], Flag);
552fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
553dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov    // Guarantee that all emitted copies are stuck together,
554dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov    // avoiding something bad.
555fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    Flag = Chain.getValue(1);
556294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen    RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
557fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  }
558fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
559e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  unsigned Opc = (CallConv == CallingConv::MSP430_INTR ?
560e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov                  MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG);
561e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov
562294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen  RetOps[0] = Chain;  // Update chain.
563294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen
564294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen  // Add the flag if we have it.
565fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  if (Flag.getNode())
566294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen    RetOps.push_back(Flag);
567fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
568dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return DAG.getNode(Opc, dl, MVT::Other, RetOps);
569fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov}
570fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
5714428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// LowerCCCCallTo - functions arguments are copied from virtual regs to
5724428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
5730bf3c99886bed6796eada8f65942ee6023fc6e89Job Noorman// TODO: sret.
57498ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
57598ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee,
57665c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                     CallingConv::ID CallConv, bool isVarArg,
57798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     bool isTailCall,
57898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     const SmallVectorImpl<ISD::OutputArg>
57998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                       &Outs,
580c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman                                     const SmallVectorImpl<SDValue> &OutVals,
58198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     const SmallVectorImpl<ISD::InputArg> &Ins,
582ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                     SDLoc dl, SelectionDAG &DAG,
583d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                     SmallVectorImpl<SDValue> &InVals) const {
5844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Analyze operands of the call, assigning locations to each operand.
5854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<CCValAssign, 16> ArgLocs;
586471e4224809f51652c71f319532697a879a75a0dEric Christopher  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
58756cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling                 getTargetMachine(), ArgLocs, *DAG.getContext());
5883edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  AnalyzeArguments(CCInfo, ArgLocs, Outs);
5894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Get a count of how many bytes are to be pushed on the stack.
5914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  unsigned NumBytes = CCInfo.getNextStackOffset();
5924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Chain = DAG.getCALLSEQ_START(Chain ,DAG.getConstant(NumBytes,
5946e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick                                                      getPointerTy(), true),
5956e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick                               dl);
5964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5974428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass;
5984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<SDValue, 12> MemOpChains;
5994428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SDValue StackPtr;
6004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
6014428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Walk the register/memloc assignments, inserting copies/loads.
6024428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
6034428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    CCValAssign &VA = ArgLocs[i];
6044428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
605c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman    SDValue Arg = OutVals[i];
6064428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
6074428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    // Promote the value if needed.
6084428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    switch (VA.getLocInfo()) {
609c23197a26f34f559ea9797de51e187087c039c42Torok Edwin      default: llvm_unreachable("Unknown loc info!");
6104428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::Full: break;
6114428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::SExt:
6124428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
6134428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        break;
6144428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::ZExt:
6154428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
6164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        break;
6174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::AExt:
6184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
6194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        break;
6204428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    }
6214428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
6224428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    // Arguments that can be passed on register must be kept at RegsToPass
6234428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    // vector
6244428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    if (VA.isRegLoc()) {
6254428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
6264428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    } else {
6274428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      assert(VA.isMemLoc());
6284428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
629dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (!StackPtr.getNode())
6304428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SPW, getPointerTy());
6314428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
6324428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(),
6334428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                   StackPtr,
6344428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                   DAG.getIntPtrConstant(VA.getLocMemOffset()));
6354428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
6366cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      SDValue MemOp;
6376cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      ISD::ArgFlagsTy Flags = Outs[i].Flags;
6386cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov
6396cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      if (Flags.isByVal()) {
6406cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), MVT::i16);
6416cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        MemOp = DAG.getMemcpy(Chain, dl, PtrOff, Arg, SizeNode,
6426cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                              Flags.getByValAlign(),
6436cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                              /*isVolatile*/false,
6446cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                              /*AlwaysInline=*/true,
6456cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                              MachinePointerInfo(),
6466cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                              MachinePointerInfo());
6476cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      } else {
6486cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        MemOp = DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo(),
6496cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                             false, false, 0);
6506cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      }
6514428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
6526cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      MemOpChains.push_back(MemOp);
6534428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    }
6544428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
6554428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
6564428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Transform all store nodes into one single node because all store nodes are
6574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // independent of each other.
6584428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  if (!MemOpChains.empty())
659dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
6604428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
6614428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Build a sequence of copy-to-reg nodes chained together with token chain and
6624428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // flag operands which copy the outgoing args into registers.  The InFlag in
6637a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner  // necessary since all emitted instructions must be stuck together.
6644428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SDValue InFlag;
6654428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
6664428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
6674428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             RegsToPass[i].second, InFlag);
6684428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    InFlag = Chain.getValue(1);
6694428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
6704428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
6714428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // If the callee is a GlobalAddress node (quite common, every direct call is)
6724428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
6734428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Likewise ExternalSymbol -> TargetExternalSymbol.
6744428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
6750d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel    Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i16);
6764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
677825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson    Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i16);
6784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
6794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Returns a chain & a flag for retval copy to use.
680f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner  SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
6814428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<SDValue, 8> Ops;
6824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Ops.push_back(Chain);
6834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Ops.push_back(Callee);
6844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
6854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Add argument registers to the end of the list so that they are
6864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // known live into the call.
6874428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
6884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Ops.push_back(DAG.getRegister(RegsToPass[i].first,
6894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                  RegsToPass[i].second.getValueType()));
6904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
6914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  if (InFlag.getNode())
6924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Ops.push_back(InFlag);
6934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
694dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Chain = DAG.getNode(MSP430ISD::CALL, dl, NodeTys, Ops);
6954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  InFlag = Chain.getValue(1);
6964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
6974428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Create the CALLSEQ_END node.
6984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Chain = DAG.getCALLSEQ_END(Chain,
6994428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             DAG.getConstant(NumBytes, getPointerTy(), true),
7004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             DAG.getConstant(0, getPointerTy(), true),
7016e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick                             InFlag, dl);
7024428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  InFlag = Chain.getValue(1);
7034428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
7044428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Handle result values, copying them out of physregs into vregs that we
7054428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // return.
70698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl,
70798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                         DAG, InVals);
7084428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov}
7094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
71098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// LowerCallResult - Lower the result values of a call into the
71198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// appropriate copies out of appropriate physical registers.
71298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman///
71398ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
7144428885c5acfffbbdd03ad2aab23960531c47753Anton KorobeynikovMSP430TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag,
71565c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                      CallingConv::ID CallConv, bool isVarArg,
71698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                      const SmallVectorImpl<ISD::InputArg> &Ins,
717ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                      SDLoc dl, SelectionDAG &DAG,
718d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                      SmallVectorImpl<SDValue> &InVals) const {
7194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
7204428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Assign locations to each value returned by this call.
7214428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<CCValAssign, 16> RVLocs;
722471e4224809f51652c71f319532697a879a75a0dEric Christopher  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
72356cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling                 getTargetMachine(), RVLocs, *DAG.getContext());
7244428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
7253edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  AnalyzeReturnValues(CCInfo, RVLocs, Ins);
7264428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
7274428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Copy all of the result registers out of their specified physreg.
7284428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0; i != RVLocs.size(); ++i) {
7294428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(),
7304428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                               RVLocs[i].getValVT(), InFlag).getValue(1);
7314428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    InFlag = Chain.getValue(2);
73298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman    InVals.push_back(Chain.getValue(0));
7334428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
7344428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
73598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return Chain;
7364428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov}
7374428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
738d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton KorobeynikovSDValue MSP430TargetLowering::LowerShifts(SDValue Op,
739d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                          SelectionDAG &DAG) const {
740ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov  unsigned Opc = Op.getOpcode();
741d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  SDNode* N = Op.getNode();
742e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = Op.getValueType();
743ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(N);
744d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
7452625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Expand non-constant shifts to loops:
746d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  if (!isa<ConstantSDNode>(N->getOperand(1)))
7472625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    switch (Opc) {
748bc2198133a1836598b54b943420748e75d5dea94Craig Topper    default: llvm_unreachable("Invalid shift opcode!");
7492625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    case ISD::SHL:
7502625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      return DAG.getNode(MSP430ISD::SHL, dl,
7512625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                         VT, N->getOperand(0), N->getOperand(1));
7522625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    case ISD::SRA:
7532625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      return DAG.getNode(MSP430ISD::SRA, dl,
7542625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                         VT, N->getOperand(0), N->getOperand(1));
7552625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    case ISD::SRL:
7562625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      return DAG.getNode(MSP430ISD::SRL, dl,
7572625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                         VT, N->getOperand(0), N->getOperand(1));
7582625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    }
759d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
760d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
761d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
762d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  // Expand the stuff into sequence of shifts.
763d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  // FIXME: for some shift amounts this might be done better!
764d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N
765d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  SDValue Victim = N->getOperand(0);
766e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov
767e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  if (Opc == ISD::SRL && ShiftAmount) {
768e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov    // Emit a special goodness here:
769e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov    // srl A, 1 => clrc; rrc A
770bf8ef3f29de28529b5d65970af9015c41f7c809bAnton Korobeynikov    Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim);
771e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov    ShiftAmount -= 1;
772e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  }
773e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov
774d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  while (ShiftAmount--)
775aceb620de855485a4fb2eed343d880d76f6c701cAnton Korobeynikov    Victim = DAG.getNode((Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA),
776ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov                         dl, VT, Victim);
777d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
778d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  return Victim;
779d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov}
780d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
781d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerGlobalAddress(SDValue Op,
782d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                                 SelectionDAG &DAG) const {
7833513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
7843513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();
7853513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov
7863513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  // Create the TargetGlobalAddress node, folding in the constant offset.
787ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDValue Result = DAG.getTargetGlobalAddress(GV, SDLoc(Op),
7880d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel                                              getPointerTy(), Offset);
789ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  return DAG.getNode(MSP430ISD::Wrapper, SDLoc(Op),
7903513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov                     getPointerTy(), Result);
7913513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov}
7923513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov
7935d59f68ade7573175f1ace09061a94286e59076bAnton KorobeynikovSDValue MSP430TargetLowering::LowerExternalSymbol(SDValue Op,
794d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                                  SelectionDAG &DAG) const {
795ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
7965d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol();
7975d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  SDValue Result = DAG.getTargetExternalSymbol(Sym, getPointerTy());
7985d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov
79990f20044ade3712c8b0c3f4ebe47d57ad15ae6ceChad Rosier  return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result);
8005d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov}
8015d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov
80269d5b48bc31b7a443355cdf1506005804b4f63e6Anton KorobeynikovSDValue MSP430TargetLowering::LowerBlockAddress(SDValue Op,
80369d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov                                                SelectionDAG &DAG) const {
804ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
80569d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov  const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
8066c7ccaa3fd1d6e96d0bf922554b09d2b17c3b0e3Michael Liao  SDValue Result = DAG.getTargetBlockAddress(BA, getPointerTy());
80769d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov
80890f20044ade3712c8b0c3f4ebe47d57ad15ae6ceChad Rosier  return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result);
80969d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov}
81069d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov
8113926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikovstatic SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC,
8121bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov                       ISD::CondCode CC,
813ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                       SDLoc dl, SelectionDAG &DAG) {
814ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  // FIXME: Handle bittests someday
815ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet");
816ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
817ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  // FIXME: Handle jump negative someday
8183926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  MSP430CC::CondCodes TCC = MSP430CC::COND_INVALID;
819ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  switch (CC) {
820c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Invalid integer condition!");
821ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETEQ:
8223926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_E;     // aka COND_Z
823f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    // Minor optimization: if LHS is a constant, swap operands, then the
8241722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov    // constant can be folded into comparison.
825f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    if (LHS.getOpcode() == ISD::Constant)
8261722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov      std::swap(LHS, RHS);
827ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
828ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETNE:
8293926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_NE;    // aka COND_NZ
830f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    // Minor optimization: if LHS is a constant, swap operands, then the
8311722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov    // constant can be folded into comparison.
832f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    if (LHS.getOpcode() == ISD::Constant)
8331722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov      std::swap(LHS, RHS);
834ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
835ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETULE:
836ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
837ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETUGE:
8380c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // Turn lhs u>= rhs with lhs constant into rhs u< lhs+1, this allows us to
8390c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
8400c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
8410c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
8420c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
8430c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_LO;
8440c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
8450c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
8463926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_HS;    // aka COND_C
847ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
848ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETUGT:
849ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
850ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETULT:
8510c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // Turn lhs u< rhs with lhs constant into rhs u>= lhs+1, this allows us to
8520c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
8530c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
8540c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
8550c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
8560c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_HS;
8570c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
8580c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
8593926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_LO;    // aka COND_NC
860ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
861ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETLE:
862ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
863ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETGE:
8640c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // Turn lhs >= rhs with lhs constant into rhs < lhs+1, this allows us to
8650c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
8660c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
8670c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
8680c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
8690c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_L;
8700c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
8710c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
8723926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_GE;
873ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
874ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETGT:
875ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
876ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETLT:
8770c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to
8780c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
8790c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
8800c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
8810c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
8820c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_GE;
8830c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
8840c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
8853926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_L;
886ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
887ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  }
888ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
8893926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  TargetCC = DAG.getConstant(TCC, MVT::i8);
890f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner  return DAG.getNode(MSP430ISD::CMP, dl, MVT::Glue, LHS, RHS);
891ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov}
892ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
8931bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
894d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
895ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  SDValue Chain = Op.getOperand(0);
8961bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
8971bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue LHS   = Op.getOperand(2);
8981bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue RHS   = Op.getOperand(3);
8991bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue Dest  = Op.getOperand(4);
900ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl  (Op);
9011bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
9023926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  SDValue TargetCC;
9031bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
9041bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
9051bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(),
9063926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov                     Chain, Dest, TargetCC, Flag);
907ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov}
908ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
909d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
9108d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue LHS   = Op.getOperand(0);
9118d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue RHS   = Op.getOperand(1);
912ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl  (Op);
9138d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov
9148d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // If we are doing an AND and testing against zero, then the CMP
9158d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // will not be generated.  The AND (or BIT) will generate the condition codes,
9168d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // but they are different from CMP.
917cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov  // FIXME: since we're doing a post-processing, use a pseudoinstr here, so
918cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov  // lowering & isel wouldn't diverge.
9198d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool andCC = false;
9208d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) {
9218d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    if (RHSC->isNullValue() && LHS.hasOneUse() &&
9228d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov        (LHS.getOpcode() == ISD::AND ||
9238d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov         (LHS.getOpcode() == ISD::TRUNCATE &&
9248d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov          LHS.getOperand(0).getOpcode() == ISD::AND))) {
9258d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov      andCC = true;
9268d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    }
9278d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  }
9288d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
9298d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue TargetCC;
9308d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
9318d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov
9328d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // Get the condition codes directly from the status register, if its easy.
9338d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // Otherwise a branch will be generated.  Note that the AND and BIT
9348d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // instructions generate different flags than CMP, the carry bit can be used
9358d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // for NE/EQ.
9368d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool Invert = false;
9378d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool Shift = false;
9388d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool Convert = true;
9398d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  switch (cast<ConstantSDNode>(TargetCC)->getZExtValue()) {
9408d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov   default:
9418d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Convert = false;
9428d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    break;
9438d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov   case MSP430CC::COND_HS:
9448d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     // Res = SRW & 1, no processing is required
9458d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
946cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov   case MSP430CC::COND_LO:
9478d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     // Res = ~(SRW & 1)
9488d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     Invert = true;
9498d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
950cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov   case MSP430CC::COND_NE:
9518d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     if (andCC) {
9528d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov       // C = ~Z, thus Res = SRW & 1, no processing is required
9538d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     } else {
954455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov       // Res = ~((SRW >> 1) & 1)
9558d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov       Shift = true;
956455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov       Invert = true;
9578d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     }
9588d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
959cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov   case MSP430CC::COND_E:
960455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov     Shift = true;
961455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov     // C = ~Z for AND instruction, thus we can put Res = ~(SRW & 1), however,
962455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov     // Res = (SRW >> 1) & 1 is 1 word shorter.
9638d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
9648d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  }
9658d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  EVT VT = Op.getValueType();
9668d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue One  = DAG.getConstant(1, VT);
9678d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  if (Convert) {
9688d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SRW,
969cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov                                    MVT::i16, Flag);
9708d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    if (Shift)
9718d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov      // FIXME: somewhere this is turned into a SRL, lower it MSP specific?
9728d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov      SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One);
9738d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    SR = DAG.getNode(ISD::AND, dl, MVT::i16, SR, One);
9748d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    if (Invert)
9758d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov      SR = DAG.getNode(ISD::XOR, dl, MVT::i16, SR, One);
9768d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    return SR;
9778d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  } else {
9788d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    SDValue Zero = DAG.getConstant(0, VT);
979f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner    SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
9808d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    SmallVector<SDValue, 4> Ops;
9818d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Ops.push_back(One);
9828d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Ops.push_back(Zero);
9838d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Ops.push_back(TargetCC);
9848d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Ops.push_back(Flag);
985dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, Ops);
9868d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  }
9878d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov}
9888d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov
989d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op,
990d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                             SelectionDAG &DAG) const {
9911bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue LHS    = Op.getOperand(0);
9921bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue RHS    = Op.getOperand(1);
9931bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue TrueV  = Op.getOperand(2);
9941bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue FalseV = Op.getOperand(3);
9951bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
996ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl   (Op);
9971bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
9983926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  SDValue TargetCC;
9991bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
10008b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
1001f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner  SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
10028b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  SmallVector<SDValue, 4> Ops;
10038b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  Ops.push_back(TrueV);
10048b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  Ops.push_back(FalseV);
10053926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  Ops.push_back(TargetCC);
10061bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  Ops.push_back(Flag);
10078b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
1008dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, Ops);
10098b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov}
10108b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
1011b78e214274d397407b6167a293b7cd7c3b526ddeAnton KorobeynikovSDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op,
1012d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                               SelectionDAG &DAG) const {
1013b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  SDValue Val = Op.getOperand(0);
1014e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT      = Op.getValueType();
1015ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
1016b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov
1017825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  assert(VT == MVT::i16 && "Only support i16 for now!");
1018b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov
1019b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT,
1020b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov                     DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val),
1021b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov                     DAG.getValueType(Val.getValueType()));
1022b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov}
1023b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov
1024d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue
1025d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanMSP430TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) const {
102606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MachineFunction &MF = DAG.getMachineFunction();
102706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
102806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  int ReturnAddrIndex = FuncInfo->getRAIndex();
102906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
103006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  if (ReturnAddrIndex == 0) {
103106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    // Set up a frame object for the return address.
1032cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    uint64_t SlotSize = getDataLayout()->getPointerSize();
103306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(SlotSize, -SlotSize,
1034ed2ae136d29dd36122d2476801e7d7a86e8301e3Evan Cheng                                                           true);
103506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    FuncInfo->setRAIndex(ReturnAddrIndex);
103606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  }
103706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
103806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy());
103906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov}
104006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
1041d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op,
1042d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                              SelectionDAG &DAG) const {
10432457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
10442457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng  MFI->setReturnAddressIsTaken(true);
10452457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng
104636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (verifyReturnAddressArgumentIsConstant(Op, DAG))
104736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return SDValue();
104836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
104906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
1050ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
105106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
105206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  if (Depth > 0) {
105306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
105406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    SDValue Offset =
1055cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        DAG.getConstant(getDataLayout()->getPointerSize(), MVT::i16);
105606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
105706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                       DAG.getNode(ISD::ADD, dl, getPointerTy(),
105806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                                   FrameAddr, Offset),
1059d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                       MachinePointerInfo(), false, false, false, 0);
106006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  }
106106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
106206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  // Just load the return address.
106306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  SDValue RetAddrFI = getReturnAddressFrameIndex(DAG);
106406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
1065d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                     RetAddrFI, MachinePointerInfo(), false, false, false, 0);
106606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov}
106706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
1068d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op,
1069d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                             SelectionDAG &DAG) const {
107006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
107106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MFI->setFrameAddressIsTaken(true);
10722457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng
107306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  EVT VT = Op.getValueType();
1074ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);  // FIXME probably not meaningful
107506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
107606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl,
107706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                                         MSP430::FPW, VT);
107806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  while (Depth--)
1079d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner    FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
1080d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner                            MachinePointerInfo(),
1081d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                            false, false, false, 0);
108206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  return FrameAddr;
108306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov}
108406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
10850ae61240341ca76e1329f251c64d2f475fa89278Anton KorobeynikovSDValue MSP430TargetLowering::LowerVASTART(SDValue Op,
10860ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov                                           SelectionDAG &DAG) const {
10870ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  MachineFunction &MF = DAG.getMachineFunction();
10880ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
10890ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov
10900ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  // Frame index of first vararg argument
10910ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  SDValue FrameIndex = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),
10920ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov                                         getPointerTy());
10930ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
10940ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov
10950ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  // Create a store of the frame index to the location operand
1096ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  return DAG.getStore(Op.getOperand(0), SDLoc(Op), FrameIndex,
10970ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov                      Op.getOperand(1), MachinePointerInfo(SV),
10980ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov                      false, false, 0);
10990ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov}
11000ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov
110127253f5edd04791bfbd0b5dd6e228be1d8071fceAnton KorobeynikovSDValue MSP430TargetLowering::LowerJumpTable(SDValue Op,
110227253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov                                             SelectionDAG &DAG) const {
110327253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov    JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
110427253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov    SDValue Result = DAG.getTargetJumpTable(JT->getIndex(), getPointerTy());
1105a77f816c4c6e4c833ac9ab78e2e038dcfb861c73Anton Korobeynikov    return DAG.getNode(MSP430ISD::Wrapper, SDLoc(JT),
1106a77f816c4c6e4c833ac9ab78e2e038dcfb861c73Anton Korobeynikov                       getPointerTy(), Result);
110727253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov}
110827253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov
11096534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// getPostIndexedAddressParts - returns true by value, base pointer and
11106534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// offset pointer and addressing mode by reference if this node can be
11116534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// combined with a load / store to form a post-indexed load / store.
11126534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikovbool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
11136534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      SDValue &Base,
11146534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      SDValue &Offset,
11156534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      ISD::MemIndexedMode &AM,
11166534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      SelectionDAG &DAG) const {
11176534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
11186534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  LoadSDNode *LD = cast<LoadSDNode>(N);
11196534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (LD->getExtensionType() != ISD::NON_EXTLOAD)
11206534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return false;
11216534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
11226534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  EVT VT = LD->getMemoryVT();
11236534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (VT != MVT::i8 && VT != MVT::i16)
11246534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return false;
11256534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
11266534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (Op->getOpcode() != ISD::ADD)
11276534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return false;
11286534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
11296534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) {
11306534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    uint64_t RHSC = RHS->getZExtValue();
11316534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    if ((VT == MVT::i16 && RHSC != 2) ||
11326534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov        (VT == MVT::i8 && RHSC != 1))
11336534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov      return false;
11346534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
11356534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    Base = Op->getOperand(0);
11366534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    Offset = DAG.getConstant(RHSC, VT);
11376534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    AM = ISD::POST_INC;
11386534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return true;
11396534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  }
11406534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
11416534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  return false;
11426534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov}
11436534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
11446534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
1145fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikovconst char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
1146fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  switch (Opcode) {
1147dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default: return nullptr;
1148fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  case MSP430ISD::RET_FLAG:           return "MSP430ISD::RET_FLAG";
11496bfcba7e137113e5f38cc4f937ad61cc7253ec74Anton Korobeynikov  case MSP430ISD::RETI_FLAG:          return "MSP430ISD::RETI_FLAG";
1150d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  case MSP430ISD::RRA:                return "MSP430ISD::RRA";
1151e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  case MSP430ISD::RLA:                return "MSP430ISD::RLA";
1152e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  case MSP430ISD::RRC:                return "MSP430ISD::RRC";
1153b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov  case MSP430ISD::CALL:               return "MSP430ISD::CALL";
11543513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  case MSP430ISD::Wrapper:            return "MSP430ISD::Wrapper";
11551bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case MSP430ISD::BR_CC:              return "MSP430ISD::BR_CC";
1156ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case MSP430ISD::CMP:                return "MSP430ISD::CMP";
11571bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case MSP430ISD::SELECT_CC:          return "MSP430ISD::SELECT_CC";
11582625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430ISD::SHL:                return "MSP430ISD::SHL";
11592625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430ISD::SRA:                return "MSP430ISD::SRA";
1160fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  }
1161fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov}
11628b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
1163db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattnerbool MSP430TargetLowering::isTruncateFree(Type *Ty1,
1164db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner                                          Type *Ty2) const {
1165b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands  if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
11669afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov    return false;
11679afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
11689afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  return (Ty1->getPrimitiveSizeInBits() > Ty2->getPrimitiveSizeInBits());
11699afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov}
11709afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
11719afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikovbool MSP430TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
11729afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  if (!VT1.isInteger() || !VT2.isInteger())
11739afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov    return false;
11749afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
11759afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  return (VT1.getSizeInBits() > VT2.getSizeInBits());
11769afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov}
11779afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
1178db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattnerbool MSP430TargetLowering::isZExtFree(Type *Ty1, Type *Ty2) const {
11799afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
1180b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands  return 0 && Ty1->isIntegerTy(8) && Ty2->isIntegerTy(16);
11819afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov}
11829afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
11839afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikovbool MSP430TargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
11849afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
11859afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  return 0 && VT1 == MVT::i8 && VT2 == MVT::i16;
11869afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov}
11879afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
1188968b667e27d7fc9a5bf5da52191a7af629e174dcEli Benderskybool MSP430TargetLowering::isZExtFree(SDValue Val, EVT VT2) const {
1189968b667e27d7fc9a5bf5da52191a7af629e174dcEli Bendersky  return isZExtFree(Val.getValueType(), VT2);
1190968b667e27d7fc9a5bf5da52191a7af629e174dcEli Bendersky}
1191968b667e27d7fc9a5bf5da52191a7af629e174dcEli Bendersky
11928b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===//
11938b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//  Other Lowering Code
11948b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===//
11958b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
11968b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMachineBasicBlock*
11972625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMSP430TargetLowering::EmitShiftInstr(MachineInstr *MI,
1198af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman                                     MachineBasicBlock *BB) const {
11992625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineFunction *F = BB->getParent();
12002625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineRegisterInfo &RI = F->getRegInfo();
12012625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  DebugLoc dl = MI->getDebugLoc();
12022625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
12032625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
12042625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned Opc;
12052625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  const TargetRegisterClass * RC;
12062625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  switch (MI->getOpcode()) {
1207bc2198133a1836598b54b943420748e75d5dea94Craig Topper  default: llvm_unreachable("Invalid shift opcode!");
12082625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Shl8:
12092625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SHL8r1;
1210420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR8RegClass;
12112625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
12122625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Shl16:
12132625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SHL16r1;
1214420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR16RegClass;
12152625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
12162625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Sra8:
12172625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR8r1;
1218420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR8RegClass;
12192625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
12202625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Sra16:
12212625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR16r1;
1222420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR16RegClass;
12232625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
12242625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Srl8:
12252625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR8r1c;
1226420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR8RegClass;
12272625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
12282625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Srl16:
12292625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR16r1c;
1230420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR16RegClass;
12312625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
12322625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  }
12332625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
12342625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  const BasicBlock *LLVM_BB = BB->getBasicBlock();
12352625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineFunction::iterator I = BB;
12362625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  ++I;
12372625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
12382625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Create loop block
12392625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB);
12402625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineBasicBlock *RemBB  = F->CreateMachineBasicBlock(LLVM_BB);
12412625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
12422625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  F->insert(I, LoopBB);
12432625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  F->insert(I, RemBB);
12442625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
12452625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Update machine-CFG edges by transferring all successors of the current
12462625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // block to the block containing instructions after shift.
124736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  RemBB->splice(RemBB->begin(), BB, std::next(MachineBasicBlock::iterator(MI)),
124814152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman                BB->end());
124914152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  RemBB->transferSuccessorsAndUpdatePHIs(BB);
12502625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
12512625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Add adges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB
12522625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BB->addSuccessor(LoopBB);
12532625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BB->addSuccessor(RemBB);
12542625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  LoopBB->addSuccessor(RemBB);
12552625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  LoopBB->addSuccessor(LoopBB);
12562625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
1257420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper  unsigned ShiftAmtReg = RI.createVirtualRegister(&MSP430::GR8RegClass);
1258420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper  unsigned ShiftAmtReg2 = RI.createVirtualRegister(&MSP430::GR8RegClass);
12592625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned ShiftReg = RI.createVirtualRegister(RC);
12602625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned ShiftReg2 = RI.createVirtualRegister(RC);
12612625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned ShiftAmtSrcReg = MI->getOperand(2).getReg();
12622625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned SrcReg = MI->getOperand(1).getReg();
12632625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned DstReg = MI->getOperand(0).getReg();
12642625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
12652625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // BB:
12662625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // cmp 0, N
12672625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // je RemBB
1268f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov  BuildMI(BB, dl, TII.get(MSP430::CMP8ri))
1269f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    .addReg(ShiftAmtSrcReg).addImm(0);
12702625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(BB, dl, TII.get(MSP430::JCC))
12712625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addMBB(RemBB)
12722625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addImm(MSP430CC::COND_E);
12732625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
12742625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // LoopBB:
12752625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB]
12762625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // ShiftAmt = phi [%N, BB],      [%ShiftAmt2, LoopBB]
12772625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // ShiftReg2 = shift ShiftReg
12782625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // ShiftAmt2 = ShiftAmt - 1;
12792625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftReg)
12802625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(SrcReg).addMBB(BB)
12812625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftReg2).addMBB(LoopBB);
12822625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg)
12832625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftAmtSrcReg).addMBB(BB)
12842625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftAmtReg2).addMBB(LoopBB);
12852625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2)
12862625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftReg);
12872625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2)
12882625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftAmtReg).addImm(1);
12892625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::JCC))
12902625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addMBB(LoopBB)
12912625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addImm(MSP430CC::COND_NE);
12922625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
12932625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // RemBB:
12942625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB]
129514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  BuildMI(*RemBB, RemBB->begin(), dl, TII.get(MSP430::PHI), DstReg)
12962625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(SrcReg).addMBB(BB)
12972625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftReg2).addMBB(LoopBB);
12982625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
129914152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  MI->eraseFromParent();   // The pseudo instruction is gone now.
13002625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  return RemBB;
13012625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov}
13022625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
13032625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMachineBasicBlock*
13048b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
1305af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman                                                  MachineBasicBlock *BB) const {
13062625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned Opc = MI->getOpcode();
13072625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
13082625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 ||
13092625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      Opc == MSP430::Sra8 || Opc == MSP430::Sra16 ||
13102625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      Opc == MSP430::Srl8 || Opc == MSP430::Srl16)
1311af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman    return EmitShiftInstr(MI, BB);
13122625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
13138b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
13148b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  DebugLoc dl = MI->getDebugLoc();
13152625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
13162625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  assert((Opc == MSP430::Select16 || Opc == MSP430::Select8) &&
13178b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov         "Unexpected instr type to insert");
13188b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
13198b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // To "insert" a SELECT instruction, we actually have to insert the diamond
13208b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // control-flow pattern.  The incoming instruction knows the destination vreg
13218b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // to set, the condition code register to branch on, the true/false values to
13228b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // select between, and a branch opcode to use.
13238b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  const BasicBlock *LLVM_BB = BB->getBasicBlock();
13248b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineFunction::iterator I = BB;
13258b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  ++I;
13268b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
13278b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  thisMBB:
13288b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  ...
13298b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   TrueVal = ...
13308b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   cmpTY ccX, r1, r2
13318b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   jCC copy1MBB
13328b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   fallthrough --> copy0MBB
13338b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineBasicBlock *thisMBB = BB;
13348b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineFunction *F = BB->getParent();
13358b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
13368b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB);
13378b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  F->insert(I, copy0MBB);
13388b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  F->insert(I, copy1MBB);
13398b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // Update machine-CFG edges by transferring all successors of the current
13408b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // block to the new block which will contain the Phi node for the select.
134114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  copy1MBB->splice(copy1MBB->begin(), BB,
134236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                   std::next(MachineBasicBlock::iterator(MI)), BB->end());
134314152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  copy1MBB->transferSuccessorsAndUpdatePHIs(BB);
13448b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // Next, add the true and fallthrough blocks as its successors.
13458b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB->addSuccessor(copy0MBB);
13468b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB->addSuccessor(copy1MBB);
13478b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
134814152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  BuildMI(BB, dl, TII.get(MSP430::JCC))
134914152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman    .addMBB(copy1MBB)
135014152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman    .addImm(MI->getOperand(3).getImm());
135114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman
13528b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  copy0MBB:
13538b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   %FalseValue = ...
13548b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   # fallthrough to copy1MBB
13558b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB = copy0MBB;
13568b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
13578b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // Update machine-CFG edges
13588b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB->addSuccessor(copy1MBB);
13598b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
13608b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  copy1MBB:
13618b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
13628b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  ...
13638b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB = copy1MBB;
136414152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  BuildMI(*BB, BB->begin(), dl, TII.get(MSP430::PHI),
13658b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov          MI->getOperand(0).getReg())
13668b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB)
13678b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB);
13688b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
136914152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  MI->eraseFromParent();   // The pseudo instruction is gone now.
13708b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  return BB;
13718b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov}
1372