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
60ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesMSP430TargetLowering::MSP430TargetLowering(const TargetMachine &TM,
61ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                           const MSP430Subtarget &STI)
6237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    : TargetLowering(TM) {
6306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
64f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  // Set up the register classes.
65420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper  addRegisterClass(MVT::i8,  &MSP430::GR8RegClass);
66420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper  addRegisterClass(MVT::i16, &MSP430::GR16RegClass);
67f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
68f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  // Compute derived properties from the register classes
69ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  computeRegisterProperties(STI.getRegisterInfo());
70fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
711476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov  // Provide all sorts of operation actions
7237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  setStackPointerRegisterToSaveRestore(MSP430::SP);
73c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov  setBooleanContents(ZeroOrOneBooleanContent);
7428b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands  setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?
75c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov
7606ac0820a6cefa6896000054d8e4906326c0cce6Anton Korobeynikov  // We have post-incremented loads / stores.
776534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  setIndexedLoadAction(ISD::POST_INC, MVT::i8, Legal);
786534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  setIndexedLoadAction(ISD::POST_INC, MVT::i16, Legal);
796534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
80ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (MVT VT : MVT::integer_valuetypes()) {
81ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    setLoadExtAction(ISD::EXTLOAD,  VT, MVT::i1,  Promote);
82ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1,  Promote);
83ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    setLoadExtAction(ISD::ZEXTLOAD, VT, MVT::i1,  Promote);
84ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i8,  Expand);
85ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i16, Expand);
86ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
8736b6e533c1aac85452438161f7034a9f54bd1830Anton Korobeynikov
8854f30d3fc94e055f13e6744378323d05c5c050baAnton Korobeynikov  // We don't have any truncstores
89825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setTruncStoreAction(MVT::i16, MVT::i8, Expand);
90825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
91825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRA,              MVT::i8,    Custom);
92825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SHL,              MVT::i8,    Custom);
93825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRL,              MVT::i8,    Custom);
94825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRA,              MVT::i16,   Custom);
95825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SHL,              MVT::i16,   Custom);
96825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRL,              MVT::i16,   Custom);
97825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ROTL,             MVT::i8,    Expand);
98825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ROTR,             MVT::i8,    Expand);
99825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ROTL,             MVT::i16,   Expand);
100825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ROTR,             MVT::i16,   Expand);
101825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::GlobalAddress,    MVT::i16,   Custom);
102825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ExternalSymbol,   MVT::i16,   Custom);
10369d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov  setOperationAction(ISD::BlockAddress,     MVT::i16,   Custom);
104825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BR_JT,            MVT::Other, Expand);
105825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BR_CC,            MVT::i8,    Custom);
106825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BR_CC,            MVT::i16,   Custom);
107825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BRCOND,           MVT::Other, Expand);
1088d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  setOperationAction(ISD::SETCC,            MVT::i8,    Custom);
1098d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  setOperationAction(ISD::SETCC,            MVT::i16,   Custom);
110825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT,           MVT::i8,    Expand);
111825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT,           MVT::i16,   Expand);
112825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT_CC,        MVT::i8,    Custom);
113825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT_CC,        MVT::i16,   Custom);
114825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SIGN_EXTEND,      MVT::i16,   Custom);
115379a087cc7175532ff0c24c60069da5eec596879Anton Korobeynikov  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i8, Expand);
116379a087cc7175532ff0c24c60069da5eec596879Anton Korobeynikov  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i16, Expand);
117825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
118825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTTZ,             MVT::i8,    Expand);
119825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTTZ,             MVT::i16,   Expand);
12063974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth  setOperationAction(ISD::CTTZ_ZERO_UNDEF,  MVT::i8,    Expand);
12163974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth  setOperationAction(ISD::CTTZ_ZERO_UNDEF,  MVT::i16,   Expand);
122825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTLZ,             MVT::i8,    Expand);
123825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTLZ,             MVT::i16,   Expand);
12463974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth  setOperationAction(ISD::CTLZ_ZERO_UNDEF,  MVT::i8,    Expand);
12563974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth  setOperationAction(ISD::CTLZ_ZERO_UNDEF,  MVT::i16,   Expand);
126825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTPOP,            MVT::i8,    Expand);
127825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTPOP,            MVT::i16,   Expand);
128825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
129825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SHL_PARTS,        MVT::i8,    Expand);
130825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SHL_PARTS,        MVT::i16,   Expand);
131825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRL_PARTS,        MVT::i8,    Expand);
132825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRL_PARTS,        MVT::i16,   Expand);
133825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRA_PARTS,        MVT::i8,    Expand);
134825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRA_PARTS,        MVT::i16,   Expand);
135825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
136825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1,   Expand);
137e4ce880dfa340bf45ddce10bb1dbe856553677b6Eli Friedman
1388725bd22bf91c29e2351a127295c19fea996e2c7Anton Korobeynikov  // FIXME: Implement efficiently multiplication by a constant
1398983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::MUL,              MVT::i8,    Expand);
1408983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::MULHS,            MVT::i8,    Expand);
1418983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::MULHU,            MVT::i8,    Expand);
1428983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::SMUL_LOHI,        MVT::i8,    Expand);
1438983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::UMUL_LOHI,        MVT::i8,    Expand);
144825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::MUL,              MVT::i16,   Expand);
145825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::MULHS,            MVT::i16,   Expand);
146825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::MULHU,            MVT::i16,   Expand);
147825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SMUL_LOHI,        MVT::i16,   Expand);
148825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::UMUL_LOHI,        MVT::i16,   Expand);
149825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
1508983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::UDIV,             MVT::i8,    Expand);
1518983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::UDIVREM,          MVT::i8,    Expand);
1528983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::UREM,             MVT::i8,    Expand);
1538983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::SDIV,             MVT::i8,    Expand);
1548983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::SDIVREM,          MVT::i8,    Expand);
1558983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::SREM,             MVT::i8,    Expand);
156825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::UDIV,             MVT::i16,   Expand);
157825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::UDIVREM,          MVT::i16,   Expand);
158825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::UREM,             MVT::i16,   Expand);
159825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SDIV,             MVT::i16,   Expand);
160825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SDIVREM,          MVT::i16,   Expand);
161825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SREM,             MVT::i16,   Expand);
162b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov
1630ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  // varargs support
1640ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  setOperationAction(ISD::VASTART,          MVT::Other, Custom);
1650ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  setOperationAction(ISD::VAARG,            MVT::Other, Expand);
1660ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  setOperationAction(ISD::VAEND,            MVT::Other, Expand);
1670ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  setOperationAction(ISD::VACOPY,           MVT::Other, Expand);
16827253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov  setOperationAction(ISD::JumpTable,        MVT::i16,   Custom);
1690ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov
170b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  // Libcalls names.
171b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  if (HWMultMode == HWMultIntr) {
172b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I8,  "__mulqi3hw");
173b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I16, "__mulhi3hw");
174b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  } else if (HWMultMode == HWMultNoIntr) {
175b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I8,  "__mulqi3hw_noint");
176b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I16, "__mulhi3hw_noint");
177b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  }
178fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman
179fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman  setMinFunctionAlignment(1);
180fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman  setPrefFunctionAlignment(2);
181f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
182f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
183d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerOperation(SDValue Op,
184d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                             SelectionDAG &DAG) const {
185f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  switch (Op.getOpcode()) {
186ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov  case ISD::SHL: // FALLTHROUGH
187e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  case ISD::SRL:
1884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  case ISD::SRA:              return LowerShifts(Op, DAG);
1893513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  case ISD::GlobalAddress:    return LowerGlobalAddress(Op, DAG);
19069d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov  case ISD::BlockAddress:     return LowerBlockAddress(Op, DAG);
1915d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  case ISD::ExternalSymbol:   return LowerExternalSymbol(Op, DAG);
1928d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  case ISD::SETCC:            return LowerSETCC(Op, DAG);
1931bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case ISD::BR_CC:            return LowerBR_CC(Op, DAG);
1941bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case ISD::SELECT_CC:        return LowerSELECT_CC(Op, DAG);
195b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  case ISD::SIGN_EXTEND:      return LowerSIGN_EXTEND(Op, DAG);
19606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  case ISD::RETURNADDR:       return LowerRETURNADDR(Op, DAG);
19706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  case ISD::FRAMEADDR:        return LowerFRAMEADDR(Op, DAG);
1980ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  case ISD::VASTART:          return LowerVASTART(Op, DAG);
19927253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov  case ISD::JumpTable:        return LowerJumpTable(Op, DAG);
200f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  default:
201c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("unimplemented operand");
202f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  }
203f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov}
204f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
205c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===//
206cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//                       MSP430 Inline Assembly Support
207cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===//
208cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
209cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// getConstraintType - Given a constraint letter, return the type of
210cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// constraint it is for this target.
211cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovTargetLowering::ConstraintType
212cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainarMSP430TargetLowering::getConstraintType(StringRef Constraint) const {
213cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  if (Constraint.size() == 1) {
214cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    switch (Constraint[0]) {
215cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    case 'r':
216cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      return C_RegisterClass;
217cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    default:
218cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      break;
219cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    }
220cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  }
221cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  return TargetLowering::getConstraintType(Constraint);
222cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov}
223cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
224ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstd::pair<unsigned, const TargetRegisterClass *>
225ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesMSP430TargetLowering::getRegForInlineAsmConstraint(
226cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const {
227cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  if (Constraint.size() == 1) {
228cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    // GCC Constraint Letters
229cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    switch (Constraint[0]) {
230cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    default: break;
231cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    case 'r':   // GENERAL_REGS
232cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      if (VT == MVT::i8)
233420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper        return std::make_pair(0U, &MSP430::GR8RegClass);
234cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
235420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper      return std::make_pair(0U, &MSP430::GR16RegClass);
236cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    }
237cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  }
238cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
239ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
240cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov}
241cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
242cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===//
243c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//                      Calling Convention Implementation
244c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===//
245c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
246f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430GenCallingConv.inc"
247c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
2483edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman/// For each argument in a function store the number of pieces it is composed
2493edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman/// of.
2503edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormantemplate<typename ArgT>
2513edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void ParseFunctionArgs(const SmallVectorImpl<ArgT> &Args,
2523edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman                              SmallVectorImpl<unsigned> &Out) {
2533edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  unsigned CurrentArgIndex = ~0U;
2543edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  for (unsigned i = 0, e = Args.size(); i != e; i++) {
2553edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    if (CurrentArgIndex == Args[i].OrigArgIndex) {
2563edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      Out.back()++;
2573edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    } else {
2583edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      Out.push_back(1);
2593edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      CurrentArgIndex++;
2603edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    }
2613edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  }
2623edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman}
2633edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
2643edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void AnalyzeVarArgs(CCState &State,
2653edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman                           const SmallVectorImpl<ISD::OutputArg> &Outs) {
2663edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  State.AnalyzeCallOperands(Outs, CC_MSP430_AssignStack);
2673edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman}
2683edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
2693edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void AnalyzeVarArgs(CCState &State,
2703edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman                           const SmallVectorImpl<ISD::InputArg> &Ins) {
2713edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  State.AnalyzeFormalArguments(Ins, CC_MSP430_AssignStack);
2723edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman}
2733edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
2743edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman/// Analyze incoming and outgoing function arguments. We need custom C++ code
2753edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman/// to handle special constraints in the ABI like reversing the order of the
2763edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman/// pieces of splitted arguments. In addition, all pieces of a certain argument
2773edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman/// have to be passed either using registers or the stack but never mixing both.
2783edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormantemplate<typename ArgT>
2793edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void AnalyzeArguments(CCState &State,
2803edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman                             SmallVectorImpl<CCValAssign> &ArgLocs,
2813edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman                             const SmallVectorImpl<ArgT> &Args) {
282dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  static const MCPhysReg RegList[] = {
28337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MSP430::R15, MSP430::R14, MSP430::R13, MSP430::R12
2843edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  };
2853edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  static const unsigned NbRegs = array_lengthof(RegList);
2863edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
2873edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  if (State.isVarArg()) {
2883edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    AnalyzeVarArgs(State, Args);
2893edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    return;
2903edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  }
2913edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
2923edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  SmallVector<unsigned, 4> ArgsParts;
2933edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  ParseFunctionArgs(Args, ArgsParts);
2943edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
2953edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  unsigned RegsLeft = NbRegs;
2963edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  bool UseStack = false;
2973edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  unsigned ValNo = 0;
2983edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
2993edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  for (unsigned i = 0, e = ArgsParts.size(); i != e; i++) {
3003edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    MVT ArgVT = Args[ValNo].VT;
3013edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    ISD::ArgFlagsTy ArgFlags = Args[ValNo].Flags;
3023edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    MVT LocVT = ArgVT;
3033edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    CCValAssign::LocInfo LocInfo = CCValAssign::Full;
3043edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
3053edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    // Promote i8 to i16
3063edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    if (LocVT == MVT::i8) {
3073edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      LocVT = MVT::i16;
3083edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      if (ArgFlags.isSExt())
3093edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman          LocInfo = CCValAssign::SExt;
3103edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      else if (ArgFlags.isZExt())
3113edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman          LocInfo = CCValAssign::ZExt;
3123edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      else
3133edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman          LocInfo = CCValAssign::AExt;
3143edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    }
3153edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
3163edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    // Handle byval arguments
3173edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    if (ArgFlags.isByVal()) {
3183edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      State.HandleByVal(ValNo++, ArgVT, LocVT, LocInfo, 2, 2, ArgFlags);
3193edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      continue;
3203edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    }
3213edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
3223edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    unsigned Parts = ArgsParts[i];
3233edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
3243edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    if (!UseStack && Parts <= RegsLeft) {
3253edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      unsigned FirstVal = ValNo;
3263edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      for (unsigned j = 0; j < Parts; j++) {
327ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        unsigned Reg = State.AllocateReg(RegList);
3283edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman        State.addLoc(CCValAssign::getReg(ValNo++, ArgVT, Reg, LocVT, LocInfo));
3293edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman        RegsLeft--;
3303edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      }
3313edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
3323edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      // Reverse the order of the pieces to agree with the "big endian" format
3333edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      // required in the calling convention ABI.
3343edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      SmallVectorImpl<CCValAssign>::iterator B = ArgLocs.begin() + FirstVal;
3353edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      std::reverse(B, B + Parts);
3363edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    } else {
3373edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      UseStack = true;
3383edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman      for (unsigned j = 0; j < Parts; j++)
3393edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman        CC_MSP430_AssignStack(ValNo++, ArgVT, LocVT, LocInfo, ArgFlags, State);
3403edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman    }
3413edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  }
3423edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman}
3433edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
3443edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void AnalyzeRetResult(CCState &State,
3453edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman                             const SmallVectorImpl<ISD::InputArg> &Ins) {
3463edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  State.AnalyzeCallResult(Ins, RetCC_MSP430);
3473edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman}
3483edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
3493edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void AnalyzeRetResult(CCState &State,
3503edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman                             const SmallVectorImpl<ISD::OutputArg> &Outs) {
3513edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  State.AnalyzeReturn(Outs, RetCC_MSP430);
3523edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman}
3533edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
3543edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormantemplate<typename ArgT>
3553edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void AnalyzeReturnValues(CCState &State,
3563edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman                                SmallVectorImpl<CCValAssign> &RVLocs,
3573edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman                                const SmallVectorImpl<ArgT> &Args) {
3583edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  AnalyzeRetResult(State, Args);
3593edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
3603edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  // Reverse splitted return values to get the "big endian" format required
3613edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  // to agree with the calling convention ABI.
3623edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  std::reverse(RVLocs.begin(), RVLocs.end());
3633edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman}
3643edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman
36598ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
36698ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerFormalArguments(SDValue Chain,
36765c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                           CallingConv::ID CallConv,
36898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           bool isVarArg,
36998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           const SmallVectorImpl<ISD::InputArg>
37098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                             &Ins,
371ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                           SDLoc dl,
37298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           SelectionDAG &DAG,
373d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                           SmallVectorImpl<SDValue> &InVals)
374d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                             const {
37598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
37698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  switch (CallConv) {
377c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  default:
378c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Unsupported calling convention");
379c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  case CallingConv::C:
380c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  case CallingConv::Fast:
38198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman    return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals);
382e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  case CallingConv::MSP430_INTR:
3834d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    if (Ins.empty())
3844d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie      return Chain;
38575361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("ISRs cannot have arguments");
386c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  }
387c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov}
388c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
38998ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
390d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin HolewinskiMSP430TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
391d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                SmallVectorImpl<SDValue> &InVals) const {
392d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SelectionDAG &DAG                     = CLI.DAG;
393ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc &dl                             = CLI.DL;
394a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper  SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
395a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper  SmallVectorImpl<SDValue> &OutVals     = CLI.OutVals;
396a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper  SmallVectorImpl<ISD::InputArg> &Ins   = CLI.Ins;
397d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SDValue Chain                         = CLI.Chain;
398d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  SDValue Callee                        = CLI.Callee;
399d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  bool &isTailCall                      = CLI.IsTailCall;
400d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  CallingConv::ID CallConv              = CLI.CallConv;
401d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski  bool isVarArg                         = CLI.IsVarArg;
402d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski
4030c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng  // MSP430 target does not yet support tail call optimization.
4040c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng  isTailCall = false;
40598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
40698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  switch (CallConv) {
4074428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  default:
408c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Unsupported calling convention");
4094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  case CallingConv::Fast:
4104428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  case CallingConv::C:
41198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman    return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
412c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman                          Outs, OutVals, Ins, dl, DAG, InVals);
413e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  case CallingConv::MSP430_INTR:
41475361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("ISRs cannot be called directly");
4154428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
4164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov}
4174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
418c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// LowerCCCArguments - transform physical registers into virtual registers and
419c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// generate load operations for arguments places on the stack.
420c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// FIXME: struct return stuff
42198ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
42298ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCArguments(SDValue Chain,
42365c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                        CallingConv::ID CallConv,
42498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        bool isVarArg,
42598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        const SmallVectorImpl<ISD::InputArg>
42698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                          &Ins,
427ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                        SDLoc dl,
42898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        SelectionDAG &DAG,
429d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                        SmallVectorImpl<SDValue> &InVals)
430d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                          const {
431c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  MachineFunction &MF = DAG.getMachineFunction();
432c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  MachineFrameInfo *MFI = MF.getFrameInfo();
433c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  MachineRegisterInfo &RegInfo = MF.getRegInfo();
4340ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
435c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
436c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  // Assign locations to all of the incoming arguments.
437c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  SmallVector<CCValAssign, 16> ArgLocs;
43837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
43937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                 *DAG.getContext());
4403edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  AnalyzeArguments(CCInfo, ArgLocs, Ins);
441c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
4420ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  // Create frame index for the start of the first vararg value
4430ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  if (isVarArg) {
4440ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov    unsigned Offset = CCInfo.getNextStackOffset();
4450ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov    FuncInfo->setVarArgsFrameIndex(MFI->CreateFixedObject(1, Offset, true));
4460ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  }
447c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
448c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
449c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    CCValAssign &VA = ArgLocs[i];
450c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    if (VA.isRegLoc()) {
451c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      // Arguments passed in registers
452e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson      EVT RegVT = VA.getLocVT();
453825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      switch (RegVT.getSimpleVT().SimpleTy) {
45495771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson      default:
455804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin        {
456dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#ifndef NDEBUG
4574437ae213d5435390f0750213b53ec807c047f22Chris Lattner          errs() << "LowerFormalArguments Unhandled argument type: "
458825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson               << RegVT.getSimpleVT().SimpleTy << "\n";
459dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#endif
460dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          llvm_unreachable(nullptr);
461804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin        }
462825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      case MVT::i16:
463420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper        unsigned VReg = RegInfo.createVirtualRegister(&MSP430::GR16RegClass);
464c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        RegInfo.addLiveIn(VA.getLocReg(), VReg);
46598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman        SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, RegVT);
466c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
467c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        // If this is an 8-bit value, it is really passed promoted to 16
468c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        // bits. Insert an assert[sz]ext to capture this, then truncate to the
469c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        // right size.
470c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        if (VA.getLocInfo() == CCValAssign::SExt)
471c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov          ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue,
472c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov                                 DAG.getValueType(VA.getValVT()));
473c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        else if (VA.getLocInfo() == CCValAssign::ZExt)
474c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov          ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue,
475c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov                                 DAG.getValueType(VA.getValVT()));
476c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
477c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        if (VA.getLocInfo() != CCValAssign::Full)
478c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov          ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
479c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
48098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman        InVals.push_back(ArgValue);
481c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      }
482c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    } else {
483c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      // Sanity check
484c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      assert(VA.isMemLoc());
4856cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov
4866cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      SDValue InVal;
4876cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      ISD::ArgFlagsTy Flags = Ins[i].Flags;
4886cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov
4896cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      if (Flags.isByVal()) {
4906cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        int FI = MFI->CreateFixedObject(Flags.getByValSize(),
4916cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                                        VA.getLocMemOffset(), true);
492cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        InVal = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
4936cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      } else {
4946cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        // Load the argument to a virtual register
4956cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        unsigned ObjSize = VA.getLocVT().getSizeInBits()/8;
4966cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        if (ObjSize > 2) {
4976cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov            errs() << "LowerFormalArguments Unhandled argument type: "
4986cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                << EVT(VA.getLocVT()).getEVTString()
4996cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                << "\n";
5006cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        }
5016cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        // Create the frame index object for this incoming parameter...
5026cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);
5036cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov
5046cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        // Create the SelectionDAG nodes corresponding to a load
5056cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        //from this parameter
5066cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        SDValue FIN = DAG.getFrameIndex(FI, MVT::i16);
507cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        InVal = DAG.getLoad(
508cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar            VA.getLocVT(), dl, Chain, FIN,
509cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar            MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI),
510cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar            false, false, false, 0);
511c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      }
5126cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov
5136cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      InVals.push_back(InVal);
514c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    }
515c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  }
516c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
51798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return Chain;
518c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov}
519fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
52098ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
52198ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerReturn(SDValue Chain,
52265c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                  CallingConv::ID CallConv, bool isVarArg,
52398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                  const SmallVectorImpl<ISD::OutputArg> &Outs,
524c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman                                  const SmallVectorImpl<SDValue> &OutVals,
525ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                  SDLoc dl, SelectionDAG &DAG) const {
52698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
527fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // CCValAssign - represent the assignment of the return value to a location
528fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  SmallVector<CCValAssign, 16> RVLocs;
529fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
530e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  // ISRs cannot return any value.
5314d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  if (CallConv == CallingConv::MSP430_INTR && !Outs.empty())
53275361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("ISRs cannot return any value");
533e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov
534fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // CCState - Info about the registers and stack slot.
53537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
53637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                 *DAG.getContext());
537fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
53898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  // Analize return values.
5393edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  AnalyzeReturnValues(CCInfo, RVLocs, Outs);
540fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
541fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  SDValue Flag;
542294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen  SmallVector<SDValue, 4> RetOps(1, Chain);
543fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
544fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // Copy the result values into the output registers.
545fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  for (unsigned i = 0; i != RVLocs.size(); ++i) {
546fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    CCValAssign &VA = RVLocs[i];
547fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    assert(VA.isRegLoc() && "Can only return in registers!");
548fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
549fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
550c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman                             OutVals[i], Flag);
551fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
552dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov    // Guarantee that all emitted copies are stuck together,
553dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov    // avoiding something bad.
554fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    Flag = Chain.getValue(1);
555294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen    RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
556fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  }
557fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
558e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  unsigned Opc = (CallConv == CallingConv::MSP430_INTR ?
559e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov                  MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG);
560e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov
561294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen  RetOps[0] = Chain;  // Update chain.
562294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen
563294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen  // Add the flag if we have it.
564fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  if (Flag.getNode())
565294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen    RetOps.push_back(Flag);
566fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
567dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return DAG.getNode(Opc, dl, MVT::Other, RetOps);
568fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov}
569fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
5704428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// LowerCCCCallTo - functions arguments are copied from virtual regs to
5714428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
5720bf3c99886bed6796eada8f65942ee6023fc6e89Job Noorman// TODO: sret.
57398ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
57498ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee,
57565c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                     CallingConv::ID CallConv, bool isVarArg,
57698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     bool isTailCall,
57798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     const SmallVectorImpl<ISD::OutputArg>
57898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                       &Outs,
579c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman                                     const SmallVectorImpl<SDValue> &OutVals,
58098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     const SmallVectorImpl<ISD::InputArg> &Ins,
581ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                     SDLoc dl, SelectionDAG &DAG,
582d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                     SmallVectorImpl<SDValue> &InVals) const {
5834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Analyze operands of the call, assigning locations to each operand.
5844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<CCValAssign, 16> ArgLocs;
58537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
58637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                 *DAG.getContext());
5873edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  AnalyzeArguments(CCInfo, ArgLocs, Outs);
5884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Get a count of how many bytes are to be pushed on the stack.
5904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  unsigned NumBytes = CCInfo.getNextStackOffset();
591cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  auto PtrVT = getPointerTy(DAG.getDataLayout());
5924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
593cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  Chain = DAG.getCALLSEQ_START(Chain,
594cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                               DAG.getConstant(NumBytes, dl, PtrVT, true), dl);
5954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass;
5974428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<SDValue, 12> MemOpChains;
5984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SDValue StackPtr;
5994428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
6004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Walk the register/memloc assignments, inserting copies/loads.
6014428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
6024428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    CCValAssign &VA = ArgLocs[i];
6034428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
604c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman    SDValue Arg = OutVals[i];
6054428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
6064428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    // Promote the value if needed.
6074428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    switch (VA.getLocInfo()) {
608c23197a26f34f559ea9797de51e187087c039c42Torok Edwin      default: llvm_unreachable("Unknown loc info!");
6094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::Full: break;
6104428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::SExt:
6114428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
6124428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        break;
6134428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::ZExt:
6144428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
6154428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        break;
6164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::AExt:
6174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
6184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        break;
6194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    }
6204428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
6214428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    // Arguments that can be passed on register must be kept at RegsToPass
6224428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    // vector
6234428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    if (VA.isRegLoc()) {
6244428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
6254428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    } else {
6264428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      assert(VA.isMemLoc());
6274428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
628dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (!StackPtr.getNode())
629cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SP, PtrVT);
6304428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
631cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      SDValue PtrOff =
632cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar          DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr,
633cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                      DAG.getIntPtrConstant(VA.getLocMemOffset(), dl));
6344428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
6356cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      SDValue MemOp;
6366cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      ISD::ArgFlagsTy Flags = Outs[i].Flags;
6376cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov
6386cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov      if (Flags.isByVal()) {
6396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), dl, MVT::i16);
6406cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov        MemOp = DAG.getMemcpy(Chain, dl, PtrOff, Arg, SizeNode,
6416cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                              Flags.getByValAlign(),
6426cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                              /*isVolatile*/false,
6436cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov                              /*AlwaysInline=*/true,
6440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                              /*isTailCall=*/false,
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.
698cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  Chain = DAG.getCALLSEQ_END(Chain, DAG.getConstant(NumBytes, dl, PtrVT, true),
699cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                             DAG.getConstant(0, dl, PtrVT, true), InFlag, dl);
7004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  InFlag = Chain.getValue(1);
7014428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
7024428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Handle result values, copying them out of physregs into vregs that we
7034428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // return.
70498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl,
70598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                         DAG, InVals);
7064428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov}
7074428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
70898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// LowerCallResult - Lower the result values of a call into the
70998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// appropriate copies out of appropriate physical registers.
71098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman///
71198ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
7124428885c5acfffbbdd03ad2aab23960531c47753Anton KorobeynikovMSP430TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag,
71365c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                      CallingConv::ID CallConv, bool isVarArg,
71498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                      const SmallVectorImpl<ISD::InputArg> &Ins,
715ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                                      SDLoc dl, SelectionDAG &DAG,
716d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                      SmallVectorImpl<SDValue> &InVals) const {
7174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
7184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Assign locations to each value returned by this call.
7194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<CCValAssign, 16> RVLocs;
72037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
72137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                 *DAG.getContext());
7224428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
7233edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman  AnalyzeReturnValues(CCInfo, RVLocs, Ins);
7244428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
7254428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Copy all of the result registers out of their specified physreg.
7264428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0; i != RVLocs.size(); ++i) {
7274428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(),
7284428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                               RVLocs[i].getValVT(), InFlag).getValue(1);
7294428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    InFlag = Chain.getValue(2);
73098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman    InVals.push_back(Chain.getValue(0));
7314428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
7324428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
73398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return Chain;
7344428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov}
7354428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
736d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton KorobeynikovSDValue MSP430TargetLowering::LowerShifts(SDValue Op,
737d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                          SelectionDAG &DAG) const {
738ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov  unsigned Opc = Op.getOpcode();
739d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  SDNode* N = Op.getNode();
740e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT = Op.getValueType();
741ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(N);
742d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
7432625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Expand non-constant shifts to loops:
744d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  if (!isa<ConstantSDNode>(N->getOperand(1)))
7452625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    switch (Opc) {
746bc2198133a1836598b54b943420748e75d5dea94Craig Topper    default: llvm_unreachable("Invalid shift opcode!");
7472625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    case ISD::SHL:
7482625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      return DAG.getNode(MSP430ISD::SHL, dl,
7492625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                         VT, N->getOperand(0), N->getOperand(1));
7502625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    case ISD::SRA:
7512625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      return DAG.getNode(MSP430ISD::SRA, dl,
7522625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                         VT, N->getOperand(0), N->getOperand(1));
7532625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    case ISD::SRL:
7542625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      return DAG.getNode(MSP430ISD::SRL, dl,
7552625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                         VT, N->getOperand(0), N->getOperand(1));
7562625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    }
757d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
758d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
759d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
760d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  // Expand the stuff into sequence of shifts.
761d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  // FIXME: for some shift amounts this might be done better!
762d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N
763d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  SDValue Victim = N->getOperand(0);
764e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov
765e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  if (Opc == ISD::SRL && ShiftAmount) {
766e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov    // Emit a special goodness here:
767e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov    // srl A, 1 => clrc; rrc A
768bf8ef3f29de28529b5d65970af9015c41f7c809bAnton Korobeynikov    Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim);
769e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov    ShiftAmount -= 1;
770e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  }
771e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov
772d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  while (ShiftAmount--)
773aceb620de855485a4fb2eed343d880d76f6c701cAnton Korobeynikov    Victim = DAG.getNode((Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA),
774ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov                         dl, VT, Victim);
775d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
776d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  return Victim;
777d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov}
778d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
779d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerGlobalAddress(SDValue Op,
780d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                                 SelectionDAG &DAG) const {
7813513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
7823513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();
783cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  auto PtrVT = getPointerTy(DAG.getDataLayout());
7843513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov
7853513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  // Create the TargetGlobalAddress node, folding in the constant offset.
786cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  SDValue Result = DAG.getTargetGlobalAddress(GV, SDLoc(Op), PtrVT, Offset);
787cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return DAG.getNode(MSP430ISD::Wrapper, SDLoc(Op), PtrVT, Result);
7883513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov}
7893513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov
7905d59f68ade7573175f1ace09061a94286e59076bAnton KorobeynikovSDValue MSP430TargetLowering::LowerExternalSymbol(SDValue Op,
791d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                                  SelectionDAG &DAG) const {
792ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
7935d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol();
794cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  auto PtrVT = getPointerTy(DAG.getDataLayout());
795cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  SDValue Result = DAG.getTargetExternalSymbol(Sym, PtrVT);
7965d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov
797cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return DAG.getNode(MSP430ISD::Wrapper, dl, PtrVT, Result);
7985d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov}
7995d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov
80069d5b48bc31b7a443355cdf1506005804b4f63e6Anton KorobeynikovSDValue MSP430TargetLowering::LowerBlockAddress(SDValue Op,
80169d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov                                                SelectionDAG &DAG) const {
802ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
803cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  auto PtrVT = getPointerTy(DAG.getDataLayout());
80469d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov  const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
805cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  SDValue Result = DAG.getTargetBlockAddress(BA, PtrVT);
80669d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov
807cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return DAG.getNode(MSP430ISD::Wrapper, dl, PtrVT, Result);
80869d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov}
80969d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov
8103926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikovstatic SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC,
8111bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov                       ISD::CondCode CC,
812ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick                       SDLoc dl, SelectionDAG &DAG) {
813ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  // FIXME: Handle bittests someday
814ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet");
815ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
816ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  // FIXME: Handle jump negative someday
8173926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  MSP430CC::CondCodes TCC = MSP430CC::COND_INVALID;
818ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  switch (CC) {
819c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Invalid integer condition!");
820ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETEQ:
8213926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_E;     // aka COND_Z
822f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    // Minor optimization: if LHS is a constant, swap operands, then the
8231722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov    // constant can be folded into comparison.
824f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    if (LHS.getOpcode() == ISD::Constant)
8251722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov      std::swap(LHS, RHS);
826ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
827ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETNE:
8283926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_NE;    // aka COND_NZ
829f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    // Minor optimization: if LHS is a constant, swap operands, then the
8301722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov    // constant can be folded into comparison.
831f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    if (LHS.getOpcode() == ISD::Constant)
8321722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov      std::swap(LHS, RHS);
833ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
834ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETULE:
835ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
836ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETUGE:
8370c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // Turn lhs u>= rhs with lhs constant into rhs u< lhs+1, this allows us to
8380c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
8390c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
8400c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
8416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      RHS = DAG.getConstant(C->getSExtValue() + 1, dl, C->getValueType(0));
8420c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_LO;
8430c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
8440c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
8453926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_HS;    // aka COND_C
846ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
847ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETUGT:
848ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
849ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETULT:
8500c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // Turn lhs u< rhs with lhs constant into rhs u>= lhs+1, this allows us to
8510c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
8520c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
8530c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
8546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      RHS = DAG.getConstant(C->getSExtValue() + 1, dl, C->getValueType(0));
8550c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_HS;
8560c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
8570c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
8583926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_LO;    // aka COND_NC
859ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
860ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETLE:
861ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
862ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETGE:
8630c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // Turn lhs >= rhs with lhs constant into rhs < lhs+1, this allows us to
8640c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
8650c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
8660c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
8676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      RHS = DAG.getConstant(C->getSExtValue() + 1, dl, C->getValueType(0));
8680c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_L;
8690c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
8700c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
8713926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_GE;
872ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
873ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETGT:
874ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
875ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETLT:
8760c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to
8770c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
8780c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
8790c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
8806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      RHS = DAG.getConstant(C->getSExtValue() + 1, dl, C->getValueType(0));
8810c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_GE;
8820c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
8830c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
8843926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    TCC = MSP430CC::COND_L;
885ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    break;
886ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  }
887ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
8886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  TargetCC = DAG.getConstant(TCC, dl, MVT::i8);
889f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner  return DAG.getNode(MSP430ISD::CMP, dl, MVT::Glue, LHS, RHS);
890ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov}
891ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
8921bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
893d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
894ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  SDValue Chain = Op.getOperand(0);
8951bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
8961bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue LHS   = Op.getOperand(2);
8971bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue RHS   = Op.getOperand(3);
8981bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue Dest  = Op.getOperand(4);
899ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl  (Op);
9001bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
9013926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  SDValue TargetCC;
9021bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
9031bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
9041bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(),
9053926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov                     Chain, Dest, TargetCC, Flag);
906ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov}
907ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
908d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
9098d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue LHS   = Op.getOperand(0);
9108d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue RHS   = Op.getOperand(1);
911ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl  (Op);
9128d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov
9138d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // If we are doing an AND and testing against zero, then the CMP
9148d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // will not be generated.  The AND (or BIT) will generate the condition codes,
9158d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // but they are different from CMP.
916cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov  // FIXME: since we're doing a post-processing, use a pseudoinstr here, so
917cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov  // lowering & isel wouldn't diverge.
9188d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool andCC = false;
9198d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) {
9208d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    if (RHSC->isNullValue() && LHS.hasOneUse() &&
9218d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov        (LHS.getOpcode() == ISD::AND ||
9228d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov         (LHS.getOpcode() == ISD::TRUNCATE &&
9238d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov          LHS.getOperand(0).getOpcode() == ISD::AND))) {
9248d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov      andCC = true;
9258d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    }
9268d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  }
9278d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
9288d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue TargetCC;
9298d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
9308d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov
9318d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // Get the condition codes directly from the status register, if its easy.
9328d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // Otherwise a branch will be generated.  Note that the AND and BIT
9338d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // instructions generate different flags than CMP, the carry bit can be used
9348d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // for NE/EQ.
9358d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool Invert = false;
9368d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool Shift = false;
9378d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool Convert = true;
9388d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  switch (cast<ConstantSDNode>(TargetCC)->getZExtValue()) {
9398d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov   default:
9408d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Convert = false;
9418d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    break;
9428d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov   case MSP430CC::COND_HS:
94337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines     // Res = SR & 1, no processing is required
9448d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
945cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov   case MSP430CC::COND_LO:
94637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines     // Res = ~(SR & 1)
9478d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     Invert = true;
9488d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
949cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov   case MSP430CC::COND_NE:
9508d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     if (andCC) {
95137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines       // C = ~Z, thus Res = SR & 1, no processing is required
9528d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     } else {
95337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines       // Res = ~((SR >> 1) & 1)
9548d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov       Shift = true;
955455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov       Invert = true;
9568d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     }
9578d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
958cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov   case MSP430CC::COND_E:
959455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov     Shift = true;
96037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines     // C = ~Z for AND instruction, thus we can put Res = ~(SR & 1), however,
96137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines     // Res = (SR >> 1) & 1 is 1 word shorter.
9628d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
9638d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  }
9648d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  EVT VT = Op.getValueType();
9656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  SDValue One  = DAG.getConstant(1, dl, VT);
9668d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  if (Convert) {
96737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SR,
968cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov                                    MVT::i16, Flag);
9698d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    if (Shift)
9708d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov      // FIXME: somewhere this is turned into a SRL, lower it MSP specific?
9718d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov      SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One);
9728d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    SR = DAG.getNode(ISD::AND, dl, MVT::i16, SR, One);
9738d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    if (Invert)
9748d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov      SR = DAG.getNode(ISD::XOR, dl, MVT::i16, SR, One);
9758d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    return SR;
9768d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  } else {
9776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    SDValue Zero = DAG.getConstant(0, dl, VT);
978f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner    SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
979ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    SDValue Ops[] = {One, Zero, TargetCC, Flag};
980dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, Ops);
9818d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  }
9828d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov}
9838d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov
984d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op,
985d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                             SelectionDAG &DAG) const {
9861bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue LHS    = Op.getOperand(0);
9871bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue RHS    = Op.getOperand(1);
9881bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue TrueV  = Op.getOperand(2);
9891bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue FalseV = Op.getOperand(3);
9901bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
991ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl   (Op);
9921bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov
9933926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  SDValue TargetCC;
9941bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
9958b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
996f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner  SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
997ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  SDValue Ops[] = {TrueV, FalseV, TargetCC, Flag};
9988b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
999dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, Ops);
10008b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov}
10018b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
1002b78e214274d397407b6167a293b7cd7c3b526ddeAnton KorobeynikovSDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op,
1003d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                               SelectionDAG &DAG) const {
1004b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  SDValue Val = Op.getOperand(0);
1005e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson  EVT VT      = Op.getValueType();
1006ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
1007b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov
1008825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  assert(VT == MVT::i16 && "Only support i16 for now!");
1009b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov
1010b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT,
1011b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov                     DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val),
1012b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov                     DAG.getValueType(Val.getValueType()));
1013b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov}
1014b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov
1015d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue
1016d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanMSP430TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) const {
101706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MachineFunction &MF = DAG.getMachineFunction();
101806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
101906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  int ReturnAddrIndex = FuncInfo->getRAIndex();
1020cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  auto PtrVT = getPointerTy(MF.getDataLayout());
102106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
102206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  if (ReturnAddrIndex == 0) {
102306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    // Set up a frame object for the return address.
1024cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    uint64_t SlotSize = MF.getDataLayout().getPointerSize();
102506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(SlotSize, -SlotSize,
1026ed2ae136d29dd36122d2476801e7d7a86e8301e3Evan Cheng                                                           true);
102706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    FuncInfo->setRAIndex(ReturnAddrIndex);
102806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  }
102906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
1030cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return DAG.getFrameIndex(ReturnAddrIndex, PtrVT);
103106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov}
103206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
1033d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op,
1034d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                              SelectionDAG &DAG) const {
10352457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
10362457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng  MFI->setReturnAddressIsTaken(true);
10372457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng
103836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (verifyReturnAddressArgumentIsConstant(Op, DAG))
103936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return SDValue();
104036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
104106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
1042ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);
1043cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  auto PtrVT = getPointerTy(DAG.getDataLayout());
104406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
104506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  if (Depth > 0) {
104606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
104706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    SDValue Offset =
1048cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        DAG.getConstant(DAG.getDataLayout().getPointerSize(), dl, MVT::i16);
1049cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(),
1050cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                       DAG.getNode(ISD::ADD, dl, PtrVT, FrameAddr, Offset),
1051d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                       MachinePointerInfo(), false, false, false, 0);
105206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  }
105306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
105406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  // Just load the return address.
105506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  SDValue RetAddrFI = getReturnAddressFrameIndex(DAG);
1056cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), RetAddrFI,
1057cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                     MachinePointerInfo(), false, false, false, 0);
105806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov}
105906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
1060d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op,
1061d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                             SelectionDAG &DAG) const {
106206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
106306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MFI->setFrameAddressIsTaken(true);
10642457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng
106506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  EVT VT = Op.getValueType();
1066ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  SDLoc dl(Op);  // FIXME probably not meaningful
106706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
106806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl,
106937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                         MSP430::FP, VT);
107006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  while (Depth--)
1071d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner    FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
1072d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner                            MachinePointerInfo(),
1073d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper                            false, false, false, 0);
107406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  return FrameAddr;
107506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov}
107606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
10770ae61240341ca76e1329f251c64d2f475fa89278Anton KorobeynikovSDValue MSP430TargetLowering::LowerVASTART(SDValue Op,
10780ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov                                           SelectionDAG &DAG) const {
10790ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  MachineFunction &MF = DAG.getMachineFunction();
10800ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
1081cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  auto PtrVT = getPointerTy(DAG.getDataLayout());
10820ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov
10830ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  // Frame index of first vararg argument
1084cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  SDValue FrameIndex =
1085cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);
10860ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
10870ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov
10880ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov  // Create a store of the frame index to the location operand
1089ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick  return DAG.getStore(Op.getOperand(0), SDLoc(Op), FrameIndex,
10900ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov                      Op.getOperand(1), MachinePointerInfo(SV),
10910ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov                      false, false, 0);
10920ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov}
10930ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov
109427253f5edd04791bfbd0b5dd6e228be1d8071fceAnton KorobeynikovSDValue MSP430TargetLowering::LowerJumpTable(SDValue Op,
109527253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov                                             SelectionDAG &DAG) const {
109627253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov    JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
1097cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    auto PtrVT = getPointerTy(DAG.getDataLayout());
1098cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    SDValue Result = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
1099cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    return DAG.getNode(MSP430ISD::Wrapper, SDLoc(JT), PtrVT, Result);
110027253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov}
110127253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov
11026534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// getPostIndexedAddressParts - returns true by value, base pointer and
11036534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// offset pointer and addressing mode by reference if this node can be
11046534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// combined with a load / store to form a post-indexed load / store.
11056534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikovbool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
11066534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      SDValue &Base,
11076534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      SDValue &Offset,
11086534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      ISD::MemIndexedMode &AM,
11096534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                                      SelectionDAG &DAG) const {
11106534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
11116534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  LoadSDNode *LD = cast<LoadSDNode>(N);
11126534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (LD->getExtensionType() != ISD::NON_EXTLOAD)
11136534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return false;
11146534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
11156534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  EVT VT = LD->getMemoryVT();
11166534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (VT != MVT::i8 && VT != MVT::i16)
11176534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return false;
11186534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
11196534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (Op->getOpcode() != ISD::ADD)
11206534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return false;
11216534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
11226534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) {
11236534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    uint64_t RHSC = RHS->getZExtValue();
11246534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    if ((VT == MVT::i16 && RHSC != 2) ||
11256534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov        (VT == MVT::i8 && RHSC != 1))
11266534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov      return false;
11276534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
11286534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    Base = Op->getOperand(0);
11296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Offset = DAG.getConstant(RHSC, SDLoc(N), VT);
11306534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    AM = ISD::POST_INC;
11316534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    return true;
11326534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  }
11336534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
11346534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  return false;
11356534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov}
11366534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
11376534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
1138fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikovconst char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
11396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  switch ((MSP430ISD::NodeType)Opcode) {
11406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case MSP430ISD::FIRST_NUMBER:       break;
1141fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  case MSP430ISD::RET_FLAG:           return "MSP430ISD::RET_FLAG";
11426bfcba7e137113e5f38cc4f937ad61cc7253ec74Anton Korobeynikov  case MSP430ISD::RETI_FLAG:          return "MSP430ISD::RETI_FLAG";
1143d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  case MSP430ISD::RRA:                return "MSP430ISD::RRA";
1144e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  case MSP430ISD::RLA:                return "MSP430ISD::RLA";
1145e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  case MSP430ISD::RRC:                return "MSP430ISD::RRC";
1146b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov  case MSP430ISD::CALL:               return "MSP430ISD::CALL";
11473513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  case MSP430ISD::Wrapper:            return "MSP430ISD::Wrapper";
11481bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case MSP430ISD::BR_CC:              return "MSP430ISD::BR_CC";
1149ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case MSP430ISD::CMP:                return "MSP430ISD::CMP";
11506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case MSP430ISD::SETCC:              return "MSP430ISD::SETCC";
11511bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case MSP430ISD::SELECT_CC:          return "MSP430ISD::SELECT_CC";
11522625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430ISD::SHL:                return "MSP430ISD::SHL";
11532625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430ISD::SRA:                return "MSP430ISD::SRA";
11546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case MSP430ISD::SRL:                return "MSP430ISD::SRL";
1155fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  }
11566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return nullptr;
1157fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov}
11588b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
1159db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattnerbool MSP430TargetLowering::isTruncateFree(Type *Ty1,
1160db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner                                          Type *Ty2) const {
1161b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands  if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
11629afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov    return false;
11639afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
11649afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  return (Ty1->getPrimitiveSizeInBits() > Ty2->getPrimitiveSizeInBits());
11659afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov}
11669afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
11679afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikovbool MSP430TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
11689afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  if (!VT1.isInteger() || !VT2.isInteger())
11699afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov    return false;
11709afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
11719afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  return (VT1.getSizeInBits() > VT2.getSizeInBits());
11729afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov}
11739afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
1174db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattnerbool MSP430TargetLowering::isZExtFree(Type *Ty1, Type *Ty2) const {
11759afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
1176b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands  return 0 && Ty1->isIntegerTy(8) && Ty2->isIntegerTy(16);
11779afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov}
11789afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
11799afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikovbool MSP430TargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
11809afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
11819afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  return 0 && VT1 == MVT::i8 && VT2 == MVT::i16;
11829afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov}
11839afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
1184968b667e27d7fc9a5bf5da52191a7af629e174dcEli Benderskybool MSP430TargetLowering::isZExtFree(SDValue Val, EVT VT2) const {
1185968b667e27d7fc9a5bf5da52191a7af629e174dcEli Bendersky  return isZExtFree(Val.getValueType(), VT2);
1186968b667e27d7fc9a5bf5da52191a7af629e174dcEli Bendersky}
1187968b667e27d7fc9a5bf5da52191a7af629e174dcEli Bendersky
11888b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===//
11898b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//  Other Lowering Code
11908b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===//
11918b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
11928b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMachineBasicBlock*
11932625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMSP430TargetLowering::EmitShiftInstr(MachineInstr *MI,
1194af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman                                     MachineBasicBlock *BB) const {
11952625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineFunction *F = BB->getParent();
11962625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineRegisterInfo &RI = F->getRegInfo();
11972625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  DebugLoc dl = MI->getDebugLoc();
1198ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  const TargetInstrInfo &TII = *F->getSubtarget().getInstrInfo();
11992625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
12002625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned Opc;
12012625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  const TargetRegisterClass * RC;
12022625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  switch (MI->getOpcode()) {
1203bc2198133a1836598b54b943420748e75d5dea94Craig Topper  default: llvm_unreachable("Invalid shift opcode!");
12042625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Shl8:
12052625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SHL8r1;
1206420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR8RegClass;
12072625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
12082625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Shl16:
12092625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SHL16r1;
1210420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR16RegClass;
12112625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
12122625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Sra8:
12132625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR8r1;
1214420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR8RegClass;
12152625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
12162625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Sra16:
12172625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR16r1;
1218420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR16RegClass;
12192625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
12202625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Srl8:
12212625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR8r1c;
1222420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR8RegClass;
12232625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
12242625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Srl16:
12252625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR16r1c;
1226420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper   RC = &MSP430::GR16RegClass;
12272625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
12282625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  }
12292625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
12302625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  const BasicBlock *LLVM_BB = BB->getBasicBlock();
1231cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  MachineFunction::iterator I = ++BB->getIterator();
12322625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
12332625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Create loop block
12342625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB);
12352625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineBasicBlock *RemBB  = F->CreateMachineBasicBlock(LLVM_BB);
12362625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
12372625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  F->insert(I, LoopBB);
12382625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  F->insert(I, RemBB);
12392625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
12402625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Update machine-CFG edges by transferring all successors of the current
12412625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // block to the block containing instructions after shift.
124236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  RemBB->splice(RemBB->begin(), BB, std::next(MachineBasicBlock::iterator(MI)),
124314152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman                BB->end());
124414152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  RemBB->transferSuccessorsAndUpdatePHIs(BB);
12452625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
12462625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Add adges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB
12472625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BB->addSuccessor(LoopBB);
12482625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BB->addSuccessor(RemBB);
12492625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  LoopBB->addSuccessor(RemBB);
12502625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  LoopBB->addSuccessor(LoopBB);
12512625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
1252420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper  unsigned ShiftAmtReg = RI.createVirtualRegister(&MSP430::GR8RegClass);
1253420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper  unsigned ShiftAmtReg2 = RI.createVirtualRegister(&MSP430::GR8RegClass);
12542625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned ShiftReg = RI.createVirtualRegister(RC);
12552625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned ShiftReg2 = RI.createVirtualRegister(RC);
12562625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned ShiftAmtSrcReg = MI->getOperand(2).getReg();
12572625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned SrcReg = MI->getOperand(1).getReg();
12582625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned DstReg = MI->getOperand(0).getReg();
12592625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
12602625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // BB:
12612625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // cmp 0, N
12622625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // je RemBB
1263f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov  BuildMI(BB, dl, TII.get(MSP430::CMP8ri))
1264f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov    .addReg(ShiftAmtSrcReg).addImm(0);
12652625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(BB, dl, TII.get(MSP430::JCC))
12662625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addMBB(RemBB)
12672625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addImm(MSP430CC::COND_E);
12682625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
12692625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // LoopBB:
12702625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB]
12712625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // ShiftAmt = phi [%N, BB],      [%ShiftAmt2, LoopBB]
12722625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // ShiftReg2 = shift ShiftReg
12732625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // ShiftAmt2 = ShiftAmt - 1;
12742625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftReg)
12752625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(SrcReg).addMBB(BB)
12762625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftReg2).addMBB(LoopBB);
12772625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg)
12782625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftAmtSrcReg).addMBB(BB)
12792625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftAmtReg2).addMBB(LoopBB);
12802625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2)
12812625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftReg);
12822625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2)
12832625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftAmtReg).addImm(1);
12842625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::JCC))
12852625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addMBB(LoopBB)
12862625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addImm(MSP430CC::COND_NE);
12872625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
12882625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // RemBB:
12892625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB]
129014152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  BuildMI(*RemBB, RemBB->begin(), dl, TII.get(MSP430::PHI), DstReg)
12912625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(SrcReg).addMBB(BB)
12922625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addReg(ShiftReg2).addMBB(LoopBB);
12932625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
129414152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  MI->eraseFromParent();   // The pseudo instruction is gone now.
12952625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  return RemBB;
12962625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov}
12972625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
12982625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMachineBasicBlock*
12998b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
1300af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman                                                  MachineBasicBlock *BB) const {
13012625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned Opc = MI->getOpcode();
13022625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
13032625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 ||
13042625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      Opc == MSP430::Sra8 || Opc == MSP430::Sra16 ||
13052625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov      Opc == MSP430::Srl8 || Opc == MSP430::Srl16)
1306af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman    return EmitShiftInstr(MI, BB);
13072625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
1308ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  const TargetInstrInfo &TII = *BB->getParent()->getSubtarget().getInstrInfo();
13098b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  DebugLoc dl = MI->getDebugLoc();
13102625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
13112625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  assert((Opc == MSP430::Select16 || Opc == MSP430::Select8) &&
13128b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov         "Unexpected instr type to insert");
13138b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
13148b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // To "insert" a SELECT instruction, we actually have to insert the diamond
13158b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // control-flow pattern.  The incoming instruction knows the destination vreg
13168b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // to set, the condition code register to branch on, the true/false values to
13178b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // select between, and a branch opcode to use.
13188b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  const BasicBlock *LLVM_BB = BB->getBasicBlock();
1319cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  MachineFunction::iterator I = ++BB->getIterator();
13208b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
13218b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  thisMBB:
13228b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  ...
13238b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   TrueVal = ...
13248b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   cmpTY ccX, r1, r2
13258b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   jCC copy1MBB
13268b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   fallthrough --> copy0MBB
13278b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineBasicBlock *thisMBB = BB;
13288b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineFunction *F = BB->getParent();
13298b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
13308b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB);
13318b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  F->insert(I, copy0MBB);
13328b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  F->insert(I, copy1MBB);
13338b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // Update machine-CFG edges by transferring all successors of the current
13348b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // block to the new block which will contain the Phi node for the select.
133514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  copy1MBB->splice(copy1MBB->begin(), BB,
133636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                   std::next(MachineBasicBlock::iterator(MI)), BB->end());
133714152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  copy1MBB->transferSuccessorsAndUpdatePHIs(BB);
13388b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // Next, add the true and fallthrough blocks as its successors.
13398b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB->addSuccessor(copy0MBB);
13408b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB->addSuccessor(copy1MBB);
13418b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
134214152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  BuildMI(BB, dl, TII.get(MSP430::JCC))
134314152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman    .addMBB(copy1MBB)
134414152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman    .addImm(MI->getOperand(3).getImm());
134514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman
13468b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  copy0MBB:
13478b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   %FalseValue = ...
13488b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   # fallthrough to copy1MBB
13498b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB = copy0MBB;
13508b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
13518b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // Update machine-CFG edges
13528b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB->addSuccessor(copy1MBB);
13538b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
13548b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  copy1MBB:
13558b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
13568b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  ...
13578b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BB = copy1MBB;
135814152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  BuildMI(*BB, BB->begin(), dl, TII.get(MSP430::PHI),
13598b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov          MI->getOperand(0).getReg())
13608b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB)
13618b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB);
13628b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
136314152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  MI->eraseFromParent();   // The pseudo instruction is gone now.
13648b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  return BB;
13658b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov}
1366