MSP430ISelLowering.cpp revision ac6d9bec671252dd1e596fa71180ff6b39d06b5d
1f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//===-- MSP430ISelLowering.cpp - MSP430 DAG Lowering Implementation  ------===//
2f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//
3f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//                     The LLVM Compiler Infrastructure
4f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//
5f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// This file is distributed under the University of Illinois Open Source
6f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// License. See LICENSE.TXT for details.
7f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//
8f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//===----------------------------------------------------------------------===//
9f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//
10f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// This file implements the MSP430TargetLowering class.
11f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//
12f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//===----------------------------------------------------------------------===//
13f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
14f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#define DEBUG_TYPE "msp430-lower"
15f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
16f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430ISelLowering.h"
17f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430.h"
1806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov#include "MSP430MachineFunctionInfo.h"
19f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430Subtarget.h"
20f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430TargetMachine.h"
21f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/CallingConvLower.h"
22f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h"
23f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineFunction.h"
24f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h"
25f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineRegisterInfo.h"
26f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/SelectionDAGISel.h"
27f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
28f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/ValueTypes.h"
29f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/IR/CallingConv.h"
30f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/IR/DerivedTypes.h"
31f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/IR/Function.h"
32c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov#include "llvm/IR/GlobalAlias.h"
33f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/IR/GlobalVariable.h"
34362dd0bef5437f85586c046bc53287b6fbe9c099Anton Korobeynikov#include "llvm/IR/Intrinsics.h"
35f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/Support/CommandLine.h"
36b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov#include "llvm/Support/Debug.h"
37f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/Support/ErrorHandling.h"
38804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin#include "llvm/Support/raw_ostream.h"
394437ae213d5435390f0750213b53ec807c047f22Chris Lattnerusing namespace llvm;
40f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
41f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovtypedef enum {
42f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  NoHWMult,
43b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  HWMultIntr,
44b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  HWMultNoIntr
45b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov} HWMultUseMode;
46b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov
47b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikovstatic cl::opt<HWMultUseMode>
48b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton KorobeynikovHWMultMode("msp430-hwmult-mode",
49b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov           cl::desc("Hardware multiplier use mode"),
50b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov           cl::init(HWMultNoIntr),
51b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov           cl::values(
52b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov             clEnumValN(NoHWMult, "no",
53b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov                "Do not use hardware multiplier"),
54b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov             clEnumValN(HWMultIntr, "interrupts",
55b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov                "Assume hardware multiplier can be used inside interrupts"),
56b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov             clEnumValN(HWMultNoIntr, "use",
57b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov                "Assume hardware multiplier cannot be used inside interrupts"),
58b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov             clEnumValEnd));
59b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov
60b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton KorobeynikovMSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) :
61b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  TargetLowering(tm, new TargetLoweringObjectFileELF()),
62f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  Subtarget(*tm.getSubtargetImpl()) {
63f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner
64f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner  TD = getDataLayout();
65f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
6606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  // Set up the register classes.
6706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  addRegisterClass(MVT::i8,  &MSP430::GR8RegClass);
68f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  addRegisterClass(MVT::i16, &MSP430::GR16RegClass);
69825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
70825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  // Compute derived properties from the register classes
71f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  computeRegisterProperties();
72f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
73f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  // Provide all sorts of operation actions
74fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
751476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov  // Division is expensive
761476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov  setIntDivIsCheap(false);
771476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov
781476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov  setStackPointerRegisterToSaveRestore(MSP430::SPW);
791476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov  setBooleanContents(ZeroOrOneBooleanContent);
80d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?
81d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
82825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  // We have post-incremented loads / stores.
83d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  setIndexedLoadAction(ISD::POST_INC, MVT::i8, Legal);
84c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov  setIndexedLoadAction(ISD::POST_INC, MVT::i16, Legal);
85c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov
86211ffa13519cadfb7f9baf4c8447fa055bf38fe8Evan Cheng  setLoadExtAction(ISD::EXTLOAD,  MVT::i1,  Promote);
87c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov  setLoadExtAction(ISD::SEXTLOAD, MVT::i1,  Promote);
8806ac0820a6cefa6896000054d8e4906326c0cce6Anton Korobeynikov  setLoadExtAction(ISD::ZEXTLOAD, MVT::i1,  Promote);
896534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  setLoadExtAction(ISD::SEXTLOAD, MVT::i8,  Expand);
906534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Expand);
916534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
926534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  // We don't have any truncstores
936534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  setTruncStoreAction(MVT::i16, MVT::i8, Expand);
946534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
956534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  setOperationAction(ISD::SRA,              MVT::i8,    Custom);
96825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SHL,              MVT::i8,    Custom);
9736b6e533c1aac85452438161f7034a9f54bd1830Anton Korobeynikov  setOperationAction(ISD::SRL,              MVT::i8,    Custom);
9854f30d3fc94e055f13e6744378323d05c5c050baAnton Korobeynikov  setOperationAction(ISD::SRA,              MVT::i16,   Custom);
99825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SHL,              MVT::i16,   Custom);
100825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRL,              MVT::i16,   Custom);
101825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ROTL,             MVT::i8,    Expand);
102825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ROTR,             MVT::i8,    Expand);
103825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ROTL,             MVT::i16,   Expand);
104825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ROTR,             MVT::i16,   Expand);
105825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::GlobalAddress,    MVT::i16,   Custom);
106825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::ExternalSymbol,   MVT::i16,   Custom);
107825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BlockAddress,     MVT::i16,   Custom);
108825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BR_JT,            MVT::Other, Expand);
109825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BR_CC,            MVT::i8,    Custom);
110825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BR_CC,            MVT::i16,   Custom);
111825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::BRCOND,           MVT::Other, Expand);
112825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SETCC,            MVT::i8,    Custom);
11369d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov  setOperationAction(ISD::SETCC,            MVT::i16,   Custom);
114825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT,           MVT::i8,    Expand);
115825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT,           MVT::i16,   Expand);
116825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT_CC,        MVT::i8,    Custom);
117825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SELECT_CC,        MVT::i16,   Custom);
1188d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  setOperationAction(ISD::SIGN_EXTEND,      MVT::i16,   Custom);
1198d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i8, Expand);
120825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i16, Expand);
121825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
122825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTTZ,             MVT::i8,    Expand);
123825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTTZ,             MVT::i16,   Expand);
124825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTTZ_ZERO_UNDEF,  MVT::i8,    Expand);
125379a087cc7175532ff0c24c60069da5eec596879Anton Korobeynikov  setOperationAction(ISD::CTTZ_ZERO_UNDEF,  MVT::i16,   Expand);
126379a087cc7175532ff0c24c60069da5eec596879Anton Korobeynikov  setOperationAction(ISD::CTLZ,             MVT::i8,    Expand);
127825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTLZ,             MVT::i16,   Expand);
128825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTLZ_ZERO_UNDEF,  MVT::i8,    Expand);
129825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTLZ_ZERO_UNDEF,  MVT::i16,   Expand);
130825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTPOP,            MVT::i8,    Expand);
131825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::CTPOP,            MVT::i16,   Expand);
132825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
133825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SHL_PARTS,        MVT::i8,    Expand);
134825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SHL_PARTS,        MVT::i16,   Expand);
135825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRL_PARTS,        MVT::i8,    Expand);
136825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRL_PARTS,        MVT::i16,   Expand);
137825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRA_PARTS,        MVT::i8,    Expand);
138825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SRA_PARTS,        MVT::i16,   Expand);
139825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
140825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1,   Expand);
141825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
142825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  // FIXME: Implement efficiently multiplication by a constant
143e4ce880dfa340bf45ddce10bb1dbe856553677b6Eli Friedman  setOperationAction(ISD::MUL,              MVT::i8,    Expand);
1448725bd22bf91c29e2351a127295c19fea996e2c7Anton Korobeynikov  setOperationAction(ISD::MULHS,            MVT::i8,    Expand);
1458983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::MULHU,            MVT::i8,    Expand);
1468983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::SMUL_LOHI,        MVT::i8,    Expand);
1478983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::UMUL_LOHI,        MVT::i8,    Expand);
1488983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::MUL,              MVT::i16,   Expand);
1498983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::MULHS,            MVT::i16,   Expand);
150825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::MULHU,            MVT::i16,   Expand);
151825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SMUL_LOHI,        MVT::i16,   Expand);
152825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::UMUL_LOHI,        MVT::i16,   Expand);
153825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
154825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::UDIV,             MVT::i8,    Expand);
155825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::UDIVREM,          MVT::i8,    Expand);
1568983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::UREM,             MVT::i8,    Expand);
1578983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::SDIV,             MVT::i8,    Expand);
1588983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::SDIVREM,          MVT::i8,    Expand);
1598983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::SREM,             MVT::i8,    Expand);
1608983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::UDIV,             MVT::i16,   Expand);
1618983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov  setOperationAction(ISD::UDIVREM,          MVT::i16,   Expand);
162825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::UREM,             MVT::i16,   Expand);
163825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SDIV,             MVT::i16,   Expand);
164825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SDIVREM,          MVT::i16,   Expand);
165825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  setOperationAction(ISD::SREM,             MVT::i16,   Expand);
166825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson
167825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  // varargs support
168b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  setOperationAction(ISD::VASTART,          MVT::Other, Custom);
169b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  setOperationAction(ISD::VAARG,            MVT::Other, Expand);
170b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  setOperationAction(ISD::VAEND,            MVT::Other, Expand);
171b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  setOperationAction(ISD::VACOPY,           MVT::Other, Expand);
172b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov
173b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  // Libcalls names.
174b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov  if (HWMultMode == HWMultIntr) {
175b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I8,  "__mulqi3hw");
176b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov    setLibcallName(RTLIB::MUL_I16, "__mulhi3hw");
177f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  } else if (HWMultMode == HWMultNoIntr) {
178f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov    setLibcallName(RTLIB::MUL_I8,  "__mulqi3hw_noint");
179d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman    setLibcallName(RTLIB::MUL_I16, "__mulhi3hw_noint");
180d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman  }
181f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov
182ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov  setMinFunctionAlignment(1);
183e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  setPrefFunctionAlignment(2);
1844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov}
1853513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov
18669d5b48bc31b7a443355cdf1506005804b4f63e6Anton KorobeynikovSDValue MSP430TargetLowering::LowerOperation(SDValue Op,
1875d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov                                             SelectionDAG &DAG) const {
1888d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  switch (Op.getOpcode()) {
1891bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case ISD::SHL: // FALLTHROUGH
1901bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case ISD::SRL:
191b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  case ISD::SRA:              return LowerShifts(Op, DAG);
19206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  case ISD::GlobalAddress:    return LowerGlobalAddress(Op, DAG);
19306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  case ISD::BlockAddress:     return LowerBlockAddress(Op, DAG);
194f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  case ISD::ExternalSymbol:   return LowerExternalSymbol(Op, DAG);
195c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  case ISD::SETCC:            return LowerSETCC(Op, DAG);
196f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  case ISD::BR_CC:            return LowerBR_CC(Op, DAG);
197f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  case ISD::SELECT_CC:        return LowerSELECT_CC(Op, DAG);
198f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  case ISD::SIGN_EXTEND:      return LowerSIGN_EXTEND(Op, DAG);
199f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov  case ISD::RETURNADDR:       return LowerRETURNADDR(Op, DAG);
200b4202b84d7e54efe5e144885c7da63e6cc465f80Bill Wendling  case ISD::FRAMEADDR:        return LowerFRAMEADDR(Op, DAG);
20120c568f366be211323eeaf0e45ef053278ec9ddcBill Wendling  case ISD::VASTART:          return LowerVASTART(Op, DAG);
2023741be39f98795a841a4d8c35bf54928769ac3cdAnton Korobeynikov  default:
20320c568f366be211323eeaf0e45ef053278ec9ddcBill Wendling    llvm_unreachable("unimplemented operand");
20420c568f366be211323eeaf0e45ef053278ec9ddcBill Wendling  }
205c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov}
206cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
207cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===//
208cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//                       MSP430 Inline Assembly Support
209cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===//
210cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
211cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// getConstraintType - Given a constraint letter, return the type of
212cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// constraint it is for this target.
213cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovTargetLowering::ConstraintType
214cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering::getConstraintType(const std::string &Constraint) const {
215cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  if (Constraint.size() == 1) {
216cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    switch (Constraint[0]) {
217cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    case 'r':
218cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      return C_RegisterClass;
219cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    default:
220cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      break;
221cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    }
222cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  }
223cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  return TargetLowering::getConstraintType(Constraint);
224cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov}
225cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
226cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikovstd::pair<unsigned, const TargetRegisterClass*>
227cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering::
228cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovgetRegForInlineAsmConstraint(const std::string &Constraint,
229cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov                             EVT VT) const {
230cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  if (Constraint.size() == 1) {
231cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    // GCC Constraint Letters
232cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    switch (Constraint[0]) {
233cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    default: break;
234cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    case 'r':   // GENERAL_REGS
235cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      if (VT == MVT::i8)
236cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov        return std::make_pair(0U, &MSP430::GR8RegClass);
237cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
238cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov      return std::make_pair(0U, &MSP430::GR16RegClass);
239cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov    }
240cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  }
241cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov
242cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov  return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
243cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov}
244c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
245c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===//
246c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//                      Calling Convention Implementation
247f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//===----------------------------------------------------------------------===//
248c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
24998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman#include "MSP430GenCallingConv.inc"
25098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
25165c3c8f323198b99b88b109654194540cf9b3fa5Sandeep PatelSDValue
25298ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerFormalArguments(SDValue Chain,
25398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           CallingConv::ID CallConv,
25498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           bool isVarArg,
25598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           const SmallVectorImpl<ISD::InputArg>
25698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                             &Ins,
257d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                           SDLoc dl,
258d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                           SelectionDAG &DAG,
25998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                           SmallVectorImpl<SDValue> &InVals)
26098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                             const {
261c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
262c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  switch (CallConv) {
263c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  default:
264c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    llvm_unreachable("Unsupported calling convention");
26598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  case CallingConv::C:
266e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  case CallingConv::Fast:
267e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals);
268e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  case CallingConv::MSP430_INTR:
269e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    if (Ins.empty())
27075361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner      return Chain;
271e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    report_fatal_error("ISRs cannot have arguments");
272e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  }
273c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov}
274c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
275c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton KorobeynikovSDValue
27698ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
277022d9e1cef7586a80a96446ae8691a37def9bbf4Evan Cheng                                SmallVectorImpl<SDValue> &InVals) const {
27865c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel  SelectionDAG &DAG                     = CLI.DAG;
2790c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng  SDLoc &dl                             = CLI.DL;
28098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs;
281c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman  SmallVector<SDValue, 32> &OutVals     = CLI.OutVals;
28298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  SmallVector<ISD::InputArg, 32> &Ins   = CLI.Ins;
28398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  SDValue Chain                         = CLI.Chain;
284d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman  SDValue Callee                        = CLI.Callee;
2850c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng  bool &isTailCall                      = CLI.IsTailCall;
2860c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng  CallingConv::ID CallConv              = CLI.CallConv;
28798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  bool isVarArg                         = CLI.IsVarArg;
28898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
2894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // MSP430 target does not yet support tail call optimization.
290c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  isTailCall = false;
2914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
2924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  switch (CallConv) {
29398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  default:
294c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman    llvm_unreachable("Unsupported calling convention");
295e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  case CallingConv::Fast:
29675361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner  case CallingConv::C:
297e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
2984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                          Outs, OutVals, Ins, dl, DAG, InVals);
2994428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  case CallingConv::MSP430_INTR:
3004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    report_fatal_error("ISRs cannot be called directly");
301c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  }
302c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov}
303c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
304c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// LowerCCCArguments - transform physical registers into virtual registers and
30598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// generate load operations for arguments places on the stack.
30698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman// FIXME: struct return stuff
30765c3c8f323198b99b88b109654194540cf9b3fa5Sandeep PatelSDValue
30898ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCArguments(SDValue Chain,
30998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        CallingConv::ID CallConv,
31098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        bool isVarArg,
31198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                        const SmallVectorImpl<ISD::InputArg>
31298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                          &Ins,
313d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                        SDLoc dl,
314d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                                        SelectionDAG &DAG,
315c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov                                        SmallVectorImpl<SDValue> &InVals)
316c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov                                          const {
317c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  MachineFunction &MF = DAG.getMachineFunction();
318c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  MachineFrameInfo *MFI = MF.getFrameInfo();
319c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  MachineRegisterInfo &RegInfo = MF.getRegInfo();
320c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
32198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
32298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  // Assign locations to all of the incoming arguments.
32398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  SmallVector<CCValAssign, 16> ArgLocs;
324c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
325c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov                 getTargetMachine(), ArgLocs, *DAG.getContext());
326c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  CCInfo.AnalyzeFormalArguments(Ins, CC_MSP430);
327c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
328c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  // Create frame index for the start of the first vararg value
329c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov  if (isVarArg) {
330c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov    unsigned Offset = CCInfo.getNextStackOffset();
331e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson    FuncInfo->setVarArgsFrameIndex(MFI->CreateFixedObject(1, Offset, true));
332825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  }
333804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin
334804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
335dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin    CCValAssign &VA = ArgLocs[i];
3364437ae213d5435390f0750213b53ec807c047f22Chris Lattner    if (VA.isRegLoc()) {
337825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      // Arguments passed in registers
338dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin      EVT RegVT = VA.getLocVT();
339c23197a26f34f559ea9797de51e187087c039c42Torok Edwin      switch (RegVT.getSimpleVT().SimpleTy) {
340804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin      default:
341825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson        {
342c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov#ifndef NDEBUG
3431df221f2bb8e8380e255d1bec73ab07b388d01a2Anton Korobeynikov          errs() << "LowerFormalArguments Unhandled argument type: "
344c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov               << RegVT.getSimpleVT().SimpleTy << "\n";
34598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman#endif
346c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov          llvm_unreachable(0);
347c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        }
348c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      case MVT::i16:
349c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        unsigned VReg = RegInfo.createVirtualRegister(&MSP430::GR16RegClass);
350c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        RegInfo.addLiveIn(VA.getLocReg(), VReg);
351c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, RegVT);
352c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
353c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        // If this is an 8-bit value, it is really passed promoted to 16
354c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        // bits. Insert an assert[sz]ext to capture this, then truncate to the
355c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        // right size.
356c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        if (VA.getLocInfo() == CCValAssign::SExt)
357c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov          ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue,
358c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov                                 DAG.getValueType(VA.getValVT()));
359c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        else if (VA.getLocInfo() == CCValAssign::ZExt)
36098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman          ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue,
361c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov                                 DAG.getValueType(VA.getValVT()));
362c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
363c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        if (VA.getLocInfo() != CCValAssign::Full)
364c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov          ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
365c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
366c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        InVals.push_back(ArgValue);
367c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      }
3684437ae213d5435390f0750213b53ec807c047f22Chris Lattner    } else {
3691440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands      // Sanity check
370c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      assert(VA.isMemLoc());
371c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
372c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      SDValue InVal;
373ed2ae136d29dd36122d2476801e7d7a86e8301e3Evan Cheng      ISD::ArgFlagsTy Flags = Ins[i].Flags;
374c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov
375c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov      if (Flags.isByVal()) {
376c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        int FI = MFI->CreateFixedObject(Flags.getByValSize(),
377825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                        VA.getLocMemOffset(), true);
37898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman        InVal = DAG.getFrameIndex(FI, getPointerTy());
379d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner      } else {
3804d58b641251f28bf34609ba5f389ba6ae0bf9641David Greene        // Load the argument to a virtual register
381c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        unsigned ObjSize = VA.getLocVT().getSizeInBits()/8;
382c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov        if (ObjSize > 2) {
383c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov            errs() << "LowerFormalArguments Unhandled argument type: "
38498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                << EVT(VA.getLocVT()).getEVTString()
385c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov                << "\n";
386fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov        }
38798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman        // Create the frame index object for this incoming parameter...
38898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman        int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);
38965c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel
39098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman        // Create the SelectionDAG nodes corresponding to a load
391c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman        //from this parameter
392d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman        SDValue FIN = DAG.getFrameIndex(FI, MVT::i16);
39398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman        InVal = DAG.getLoad(VA.getLocVT(), dl, Chain, FIN,
394fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov                            MachinePointerInfo::getFixedStack(FI),
395fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov                            false, false, false, 0);
396fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov      }
397e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov
398e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov      InVals.push_back(InVal);
39975361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    }
400e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  }
401e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov
402e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov  return Chain;
403fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov}
40498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
40598ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
406fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton KorobeynikovMSP430TargetLowering::LowerReturn(SDValue Chain,
40798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                  CallingConv::ID CallConv, bool isVarArg,
40898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                  const SmallVectorImpl<ISD::OutputArg> &Outs,
409fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov                                  const SmallVectorImpl<SDValue> &OutVals,
410fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov                                  SDLoc dl, SelectionDAG &DAG) const {
411fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
412fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // CCValAssign - represent the assignment of the return value to a location
413fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  SmallVector<CCValAssign, 16> RVLocs;
414fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
415fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // ISRs cannot return any value.
416fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  if (CallConv == CallingConv::MSP430_INTR && !Outs.empty())
417fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    report_fatal_error("ISRs cannot return any value");
418fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
419fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // CCState - Info about the registers and stack slot.
420fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
421fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov                 getTargetMachine(), RVLocs, *DAG.getContext());
422fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
423fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  // Analize return values.
424fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  CCInfo.AnalyzeReturn(Outs, RetCC_MSP430);
425fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
426c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman  SDValue Flag;
427fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  SmallVector<SDValue, 4> RetOps(1, Chain);
428dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov
429dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov  // Copy the result values into the output registers.
430fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  for (unsigned i = 0; i != RVLocs.size(); ++i) {
431fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    CCValAssign &VA = RVLocs[i];
432fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    assert(VA.isRegLoc() && "Can only return in registers!");
433e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov
434e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
435e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov                             OutVals[i], Flag);
436fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
437e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    // Guarantee that all emitted copies are stuck together,
438fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    // avoiding something bad.
439fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    Flag = Chain.getValue(1);
440e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov    RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
441fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  }
442fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov
4434428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  unsigned Opc = (CallConv == CallingConv::MSP430_INTR ?
4444428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                  MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG);
4454428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
44698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  RetOps[0] = Chain;  // Update chain.
44798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
44865c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel  // Add the flag if we have it.
44998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  if (Flag.getNode())
45098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman    RetOps.push_back(Flag);
45198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
452c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman  return DAG.getNode(Opc, dl, MVT::Other, &RetOps[0], RetOps.size());
45398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman}
45498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
455d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman/// LowerCCCCallTo - functions arguments are copied from virtual regs to
4564428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
4574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// TODO: sret.
45898ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue
45998ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee,
4604428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                     CallingConv::ID CallConv, bool isVarArg,
46198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                                     bool isTailCall,
4624428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                     const SmallVectorImpl<ISD::OutputArg>
4634428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                       &Outs,
4644428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                     const SmallVectorImpl<SDValue> &OutVals,
4654428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                     const SmallVectorImpl<ISD::InputArg> &Ins,
4664428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                     SDLoc dl, SelectionDAG &DAG,
4674428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                     SmallVectorImpl<SDValue> &InVals) const {
4684428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Analyze operands of the call, assigning locations to each operand.
4694428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<CCValAssign, 16> ArgLocs;
4704428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
4714428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                 getTargetMachine(), ArgLocs, *DAG.getContext());
4724428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4734428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  CCInfo.AnalyzeCallOperands(Outs, CC_MSP430);
4744428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4754428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Get a count of how many bytes are to be pushed on the stack.
4764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  unsigned NumBytes = CCInfo.getNextStackOffset();
477c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman
4784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Chain = DAG.getCALLSEQ_START(Chain ,DAG.getConstant(NumBytes,
4794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                                      getPointerTy(), true));
4804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
481c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass;
4824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SmallVector<SDValue, 12> MemOpChains;
4834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SDValue StackPtr;
4844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Walk the register/memloc assignments, inserting copies/loads.
4864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
4874428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    CCValAssign &VA = ArgLocs[i];
4884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    SDValue Arg = OutVals[i];
4904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
4914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    // Promote the value if needed.
4924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    switch (VA.getLocInfo()) {
4934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      default: llvm_unreachable("Unknown loc info!");
4944428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::Full: break;
4954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::SExt:
4964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
4974428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        break;
4984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::ZExt:
4994428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
5004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        break;
5014428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      case CCValAssign::AExt:
5024428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
5034428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        break;
5044428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    }
5054428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5064428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    // Arguments that can be passed on register must be kept at RegsToPass
5074428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    // vector
5084428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    if (VA.isRegLoc()) {
5094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
5106229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner    } else {
5114428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      assert(VA.isMemLoc());
5124428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5134428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      if (StackPtr.getNode() == 0)
5144428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SPW, getPointerTy());
5154428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(),
517825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson                                   StackPtr,
5184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                                   DAG.getIntPtrConstant(VA.getLocMemOffset()));
5194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5204428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      SDValue MemOp;
5214428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      ISD::ArgFlagsTy Flags = Outs[i].Flags;
5224428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5234428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      if (Flags.isByVal()) {
5244428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), MVT::i16);
5254428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        MemOp = DAG.getMemcpy(Chain, dl, PtrOff, Arg, SizeNode,
5264428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                              Flags.getByValAlign(),
5274428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                              /*isVolatile*/false,
5284428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                              /*AlwaysInline=*/true,
5294428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                              MachinePointerInfo(),
5304428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                              MachinePointerInfo());
5314428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov      } else {
5324428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov        MemOp = DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo(),
5334428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             false, false, 0);
5340d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel      }
5354428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
536825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson      MemOpChains.push_back(MemOp);
5374428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    }
5384428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
539f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner
5404428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Transform all store nodes into one single node because all store nodes are
5414428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // independent of each other.
5424428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  if (!MemOpChains.empty())
5434428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
5444428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                        &MemOpChains[0], MemOpChains.size());
5454428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5464428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Build a sequence of copy-to-reg nodes chained together with token chain and
5474428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // flag operands which copy the outgoing args into registers.  The InFlag in
5484428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // necessary since all emitted instructions must be stuck together.
5494428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  SDValue InFlag;
5504428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
5514428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
5524428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             RegsToPass[i].second, InFlag);
5534428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    InFlag = Chain.getValue(1);
5544428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  }
5554428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5564428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // If the callee is a GlobalAddress node (quite common, every direct call is)
5574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
5584428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Likewise ExternalSymbol -> TargetExternalSymbol.
5594428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
5604428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i16);
5614428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
5624428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i16);
5634428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5644428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Returns a chain & a flag for retval copy to use.
56598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
56698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  SmallVector<SDValue, 8> Ops;
5674428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Ops.push_back(Chain);
5684428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Ops.push_back(Callee);
56998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
57098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  // Add argument registers to the end of the list so that they are
57198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  // known live into the call.
57298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
5734428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov    Ops.push_back(DAG.getRegister(RegsToPass[i].first,
57465c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel                                  RegsToPass[i].second.getValueType()));
57598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
57698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  if (InFlag.getNode())
577d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman    Ops.push_back(InFlag);
5784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Chain = DAG.getNode(MSP430ISD::CALL, dl, NodeTys, &Ops[0], Ops.size());
5804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  InFlag = Chain.getValue(1);
58198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
582e922c0201916e0b980ab3cfe91e1413e68d55647Owen Anderson  // Create the CALLSEQ_END node.
5834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  Chain = DAG.getCALLSEQ_END(Chain,
58498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman                             DAG.getConstant(NumBytes, getPointerTy(), true),
5854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             DAG.getConstant(0, getPointerTy(), true),
5864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                             InFlag);
5874428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  InFlag = Chain.getValue(1);
5884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov
5894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // Handle result values, copying them out of physregs into vregs that we
5904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov  // return.
59198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman  return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl,
5924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov                         DAG, InVals);
5934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov}
59498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman
5954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// LowerCallResult - Lower the result values of a call into the
5964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// appropriate copies out of appropriate physical registers.
597d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov///
598d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue
599ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton KorobeynikovMSP430TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag,
600d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov                                      CallingConv::ID CallConv, bool isVarArg,
601e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson                                      const SmallVectorImpl<ISD::InputArg> &Ins,
602d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov                                      SDLoc dl, SelectionDAG &DAG,
603d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov                                      SmallVectorImpl<SDValue> &InVals) const {
6042625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
605d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  // Assign locations to each value returned by this call.
6062625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  SmallVector<CCValAssign, 16> RVLocs;
6072625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
6082625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                 getTargetMachine(), RVLocs, *DAG.getContext());
6092625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
6102625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  CCInfo.AnalyzeCallResult(Ins, RetCC_MSP430);
6112625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
6122625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Copy all of the result registers out of their specified physreg.
6132625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  for (unsigned i = 0; i != RVLocs.size(); ++i) {
6142625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(),
6152625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                               RVLocs[i].getValVT(), InFlag).getValue(1);
6162625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    InFlag = Chain.getValue(2);
6172625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    InVals.push_back(Chain.getValue(0));
6182625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  }
619d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
620d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  return Chain;
621d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov}
622d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov
623d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton KorobeynikovSDValue MSP430TargetLowering::LowerShifts(SDValue Op,
624d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov                                          SelectionDAG &DAG) const {
625d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov  unsigned Opc = Op.getOpcode();
626e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  SDNode* N = Op.getNode();
627e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  EVT VT = Op.getValueType();
628e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  SDLoc dl(N);
629e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov
630bf8ef3f29de28529b5d65970af9015c41f7c809bAnton Korobeynikov  // Expand non-constant shifts to loops:
631e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov  if (!isa<ConstantSDNode>(N->getOperand(1)))
632e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov    switch (Opc) {
633e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov    default: llvm_unreachable("Invalid shift opcode!");
634d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov    case ISD::SHL:
635aceb620de855485a4fb2eed343d880d76f6c701cAnton Korobeynikov      return DAG.getNode(MSP430ISD::SHL, dl,
636ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov                         VT, N->getOperand(0), N->getOperand(1));
637d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov    case ISD::SRA:
638d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov      return DAG.getNode(MSP430ISD::SRA, dl,
639d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov                         VT, N->getOperand(0), N->getOperand(1));
640d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov    case ISD::SRL:
641d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman      return DAG.getNode(MSP430ISD::SRL, dl,
642d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman                         VT, N->getOperand(0), N->getOperand(1));
6433513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov    }
6443513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov
6453513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
6463513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov
6470d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel  // Expand the stuff into sequence of shifts.
6480d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel  // FIXME: for some shift amounts this might be done better!
6493513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N
6503513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  SDValue Victim = N->getOperand(0);
6513513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov
6523513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov  if (Opc == ISD::SRL && ShiftAmount) {
6535d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov    // Emit a special goodness here:
654d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman    // srl A, 1 => clrc; rrc A
6555d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov    Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim);
6565d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov    ShiftAmount -= 1;
6575d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  }
6585d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov
6595d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov  while (ShiftAmount--)
6605d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov    Victim = DAG.getNode((Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA),
6615d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov                         dl, VT, Victim);
66269d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov
66369d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov  return Victim;
66469d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov}
66569d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov
66669d5b48bc31b7a443355cdf1506005804b4f63e6Anton KorobeynikovSDValue MSP430TargetLowering::LowerGlobalAddress(SDValue Op,
66769d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov                                                 SelectionDAG &DAG) const {
66869d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov  const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
66969d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov  int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();
67069d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov
6713926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  // Create the TargetGlobalAddress node, folding in the constant offset.
6721bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue Result = DAG.getTargetGlobalAddress(GV, SDLoc(Op),
6731bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov                                              getPointerTy(), Offset);
674ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  return DAG.getNode(MSP430ISD::Wrapper, SDLoc(Op),
675ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov                     getPointerTy(), Result);
676ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov}
677ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
6783926fb63c24ceeefc0215b8e14eb81c85403639eAnton KorobeynikovSDValue MSP430TargetLowering::LowerExternalSymbol(SDValue Op,
679ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov                                                  SelectionDAG &DAG) const {
680c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  SDLoc dl(Op);
681ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol();
6823926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  SDValue Result = DAG.getTargetExternalSymbol(Sym, getPointerTy());
683f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov
6841722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov  return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result);
685f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov}
6861722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov
687ed1a51af376b9027db60ff060e0a2572493df07bAnton KorobeynikovSDValue MSP430TargetLowering::LowerBlockAddress(SDValue Op,
688ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov                                                SelectionDAG &DAG) const {
6893926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  SDLoc dl(Op);
690f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov  const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
6911722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov  SDValue Result = DAG.getTargetBlockAddress(BA, getPointerTy());
692f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov
6931722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov  return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result);
694ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov}
695ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov
696ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikovstatic SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC,
697ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov                       ISD::CondCode CC,
6980c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov                       SDLoc dl, SelectionDAG &DAG) {
6990c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov  // FIXME: Handle bittests someday
7000c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov  assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet");
7010c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov
7020c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov  // FIXME: Handle jump negative someday
7030c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov  MSP430CC::CondCodes TCC = MSP430CC::COND_INVALID;
7040c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov  switch (CC) {
7050c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov  default: llvm_unreachable("Invalid integer condition!");
7063926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov  case ISD::SETEQ:
707ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    TCC = MSP430CC::COND_E;     // aka COND_Z
708ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    // Minor optimization: if LHS is a constant, swap operands, then the
709ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    // constant can be folded into comparison.
710ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    if (LHS.getOpcode() == ISD::Constant)
7110c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      std::swap(LHS, RHS);
7120c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    break;
7130c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov  case ISD::SETNE:
7140c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    TCC = MSP430CC::COND_NE;    // aka COND_NZ
7150c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // Minor optimization: if LHS is a constant, swap operands, then the
7160c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // constant can be folded into comparison.
7170c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (LHS.getOpcode() == ISD::Constant)
7180c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      std::swap(LHS, RHS);
7193926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    break;
720ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETULE:
721ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
722ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETUGE:
723ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    // Turn lhs u>= rhs with lhs constant into rhs u< lhs+1, this allows us to
7240c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
7250c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
7260c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
7270c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
7280c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_LO;
7290c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
7300c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
7310c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    TCC = MSP430CC::COND_HS;    // aka COND_C
7323926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    break;
733ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETUGT:
734ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
735ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETULT:
736ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    // Turn lhs u< rhs with lhs constant into rhs u>= lhs+1, this allows us to
7370c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    // fold constant into instruction.
7380c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
7390c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      LHS = RHS;
7400c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
7410c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      TCC = MSP430CC::COND_HS;
7420c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov      break;
7430c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    }
7440c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov    TCC = MSP430CC::COND_LO;    // aka COND_NC
7453926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    break;
746ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETLE:
747ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
748ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov  case ISD::SETGE:
7493926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    // Turn lhs >= rhs with lhs constant into rhs < lhs+1, this allows us to
750f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner    // fold constant into instruction.
751ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
752ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov      LHS = RHS;
7531bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
754d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman      TCC = MSP430CC::COND_L;
755ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov      break;
7561bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov    }
7571bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov    TCC = MSP430CC::COND_GE;
7581bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov    break;
7591bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case ISD::SETGT:
7601bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov    std::swap(LHS, RHS);        // FALLTHROUGH
7611bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  case ISD::SETLT:
7623926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to
7631bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov    // fold constant into instruction.
7641bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov    if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) {
7651bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov      LHS = RHS;
7663926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov      RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0));
767ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov      TCC = MSP430CC::COND_GE;
768ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov      break;
769d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman    }
7708d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    TCC = MSP430CC::COND_L;
7718d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    break;
7728d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  }
7738d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov
7748d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  TargetCC = DAG.getConstant(TCC, MVT::i8);
7758d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  return DAG.getNode(MSP430ISD::CMP, dl, MVT::Glue, LHS, RHS);
7768d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov}
777cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov
778cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov
7798d1ffbd1adad453fe330be4951400bfd25fab666Anton KorobeynikovSDValue MSP430TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
7808d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue Chain = Op.getOperand(0);
7818d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
7828d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue LHS   = Op.getOperand(2);
7838d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue RHS   = Op.getOperand(3);
7848d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue Dest  = Op.getOperand(4);
7858d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDLoc dl  (Op);
7868d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov
7878d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue TargetCC;
7888d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
7898d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov
7908d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(),
7918d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov                     Chain, Dest, TargetCC, Flag);
7928d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov}
7938d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov
7948d1ffbd1adad453fe330be4951400bfd25fab666Anton KorobeynikovSDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
7958d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue LHS   = Op.getOperand(0);
7968d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue RHS   = Op.getOperand(1);
7978d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDLoc dl  (Op);
7988d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov
7998d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // If we are doing an AND and testing against zero, then the CMP
8008d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // will not be generated.  The AND (or BIT) will generate the condition codes,
8018d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // but they are different from CMP.
8028d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // FIXME: since we're doing a post-processing, use a pseudoinstr here, so
8038d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // lowering & isel wouldn't diverge.
8048d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool andCC = false;
8058d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) {
806cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov    if (RHSC->isNullValue() && LHS.hasOneUse() &&
8078d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov        (LHS.getOpcode() == ISD::AND ||
8088d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov         (LHS.getOpcode() == ISD::TRUNCATE &&
8098d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov          LHS.getOperand(0).getOpcode() == ISD::AND))) {
810cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov      andCC = true;
8118d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    }
8128d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  }
8138d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
814455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov  SDValue TargetCC;
8158d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
816455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov
8178d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // Get the condition codes directly from the status register, if its easy.
8188d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  // Otherwise a branch will be generated.  Note that the AND and BIT
819cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov  // instructions generate different flags than CMP, the carry bit can be used
820455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov  // for NE/EQ.
821455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov  bool Invert = false;
822455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov  bool Shift = false;
8238d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  bool Convert = true;
8248d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov  switch (cast<ConstantSDNode>(TargetCC)->getZExtValue()) {
8258d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov   default:
8268d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    Convert = false;
8278d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov    break;
8288d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov   case MSP430CC::COND_HS:
829cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov     // Res = SRW & 1, no processing is required
8308d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
8318d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov   case MSP430CC::COND_LO:
8328d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     // Res = ~(SRW & 1)
8338d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     Invert = true;
8348d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
8358d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov   case MSP430CC::COND_NE:
8368d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     if (andCC) {
8378d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov       // C = ~Z, thus Res = SRW & 1, no processing is required
8388d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     } else {
839f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner       // Res = ~((SRW >> 1) & 1)
8408d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov       Shift = true;
8418d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov       Invert = true;
8428d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     }
8438d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
8448d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov   case MSP430CC::COND_E:
8458d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     Shift = true;
8468d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     // C = ~Z for AND instruction, thus we can put Res = ~(SRW & 1), however,
8478d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     // Res = (SRW >> 1) & 1 is 1 word shorter.
8488d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov     break;
849d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman  }
850d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman  EVT VT = Op.getValueType();
8511bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  SDValue One  = DAG.getConstant(1, VT);
8521bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov  if (Convert) {
8531bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov    SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SRW,
8541bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov                                    MVT::i16, Flag);
8551bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov    if (Shift)
8568b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov      // FIXME: somewhere this is turned into a SRL, lower it MSP specific?
8571bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov      SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One);
8583926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    SR = DAG.getNode(ISD::AND, dl, MVT::i16, SR, One);
8591bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov    if (Invert)
8608b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov      SR = DAG.getNode(ISD::XOR, dl, MVT::i16, SR, One);
861f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner    return SR;
8628b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  } else {
8638b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    SDValue Zero = DAG.getConstant(0, VT);
8648b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
8653926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov    SmallVector<SDValue, 4> Ops;
8661bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov    Ops.push_back(One);
8678b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    Ops.push_back(Zero);
8681bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov    Ops.push_back(TargetCC);
8698b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    Ops.push_back(Flag);
8708b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size());
871b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  }
872d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman}
873b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov
874e50ed30282bb5b4a9ed952580523f2dda16215acOwen AndersonSDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op,
875b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov                                             SelectionDAG &DAG) const {
876b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  SDValue LHS    = Op.getOperand(0);
877825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson  SDValue RHS    = Op.getOperand(1);
878b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  SDValue TrueV  = Op.getOperand(2);
879b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  SDValue FalseV = Op.getOperand(3);
880b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
881b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  SDLoc dl   (Op);
882b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov
883b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov  SDValue TargetCC;
884d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman  SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
885d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman
88606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
88706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  SmallVector<SDValue, 4> Ops;
88806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  Ops.push_back(TrueV);
88906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  Ops.push_back(FalseV);
89006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  Ops.push_back(TargetCC);
89106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  Ops.push_back(Flag);
89206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
89306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size());
894ed2ae136d29dd36122d2476801e7d7a86e8301e3Evan Cheng}
89506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
89606ccca5f70ef5f9c3e4add60b6fc842916705029Anton KorobeynikovSDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op,
89706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                                               SelectionDAG &DAG) const {
89806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  SDValue Val = Op.getOperand(0);
89906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  EVT VT      = Op.getValueType();
90006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  SDLoc dl(Op);
901d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman
902d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman  assert(VT == MVT::i16 && "Only support i16 for now!");
9032457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng
9042457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng  return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT,
9052457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng                     DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val),
90606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                     DAG.getValueType(Val.getValueType()));
90706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov}
90806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
90906ccca5f70ef5f9c3e4add60b6fc842916705029Anton KorobeynikovSDValue
91006ccca5f70ef5f9c3e4add60b6fc842916705029Anton KorobeynikovMSP430TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) const {
91106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MachineFunction &MF = DAG.getMachineFunction();
91206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
91306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  int ReturnAddrIndex = FuncInfo->getRAIndex();
91406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
91506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  if (ReturnAddrIndex == 0) {
916d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner    // Set up a frame object for the return address.
91706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    uint64_t SlotSize = TD->getPointerSize();
91806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(SlotSize, -SlotSize,
91906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                                                           true);
92006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    FuncInfo->setRAIndex(ReturnAddrIndex);
92106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  }
922d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner
92306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy());
92406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov}
925d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman
926d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op,
92706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                                              SelectionDAG &DAG) const {
92806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
9292457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng  MFI->setReturnAddressIsTaken(true);
93006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
93106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
93206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  SDLoc dl(Op);
93306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov
93406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov  if (Depth > 0) {
93506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov    SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
936d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner    SDValue Offset =
937d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner      DAG.getConstant(TD->getPointerSize(), MVT::i16);
9384d58b641251f28bf34609ba5f389ba6ae0bf9641David Greene    return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
93906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                       DAG.getNode(ISD::ADD, dl, getPointerTy(),
94006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                                   FrameAddr, Offset),
94106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov                       MachinePointerInfo(), false, false, false, 0);
9426534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  }
9436534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
9446534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  // Just load the return address.
9456534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  SDValue RetAddrFI = getReturnAddressFrameIndex(DAG);
9466534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
9476534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                     RetAddrFI, MachinePointerInfo(), false, false, false, 0);
9486534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov}
9496534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
9506534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton KorobeynikovSDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op,
9516534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                             SelectionDAG &DAG) const {
9526534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
9536534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  MFI->setFrameAddressIsTaken(true);
9546534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
9556534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  EVT VT = Op.getValueType();
9566534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  SDLoc dl(Op);  // FIXME probably not meaningful
9576534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
9586534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl,
9596534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                         MSP430::FPW, VT);
9606534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  while (Depth--)
9616534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov    FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
9626534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                            MachinePointerInfo(),
9636534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                            false, false, false, 0);
9646534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  return FrameAddr;
9656534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov}
9666534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
9676534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton KorobeynikovSDValue MSP430TargetLowering::LowerVASTART(SDValue Op,
9686534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                           SelectionDAG &DAG) const {
9696534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  MachineFunction &MF = DAG.getMachineFunction();
9706534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
9716534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
9726534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  // Frame index of first vararg argument
9736534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  SDValue FrameIndex = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),
9746534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov                                         getPointerTy());
9756534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
9766534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov
9776534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov  // Create a store of the frame index to the location operand
978fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  return DAG.getStore(Op.getOperand(0), SDLoc(Op), FrameIndex,
979fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov                      Op.getOperand(1), MachinePointerInfo(SV),
980fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov                      false, false, 0);
981fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov}
9826bfcba7e137113e5f38cc4f937ad61cc7253ec74Anton Korobeynikov
983d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov/// getPostIndexedAddressParts - returns true by value, base pointer and
984e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov/// offset pointer and addressing mode by reference if this node can be
985e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov/// combined with a load / store to form a post-indexed load / store.
986b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikovbool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
9873513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov                                                      SDValue &Base,
9881bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov                                                      SDValue &Offset,
989ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov                                                      ISD::MemIndexedMode &AM,
9901bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov                                                      SelectionDAG &DAG) const {
9912625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
9922625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  LoadSDNode *LD = cast<LoadSDNode>(N);
993fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov  if (LD->getExtensionType() != ISD::NON_EXTLOAD)
994fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov    return false;
9958b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
9969afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  EVT VT = LD->getMemoryVT();
9979afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  if (VT != MVT::i8 && VT != MVT::i16)
998b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands    return false;
9999afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
10009afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  if (Op->getOpcode() != ISD::ADD)
10019afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov    return false;
10029afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
10039afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) {
10049afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov    uint64_t RHSC = RHS->getZExtValue();
10059afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov    if ((VT == MVT::i16 && RHSC != 2) ||
10069afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov        (VT == MVT::i8 && RHSC != 1))
10079afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov      return false;
10089afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
10099afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov    Base = Op->getOperand(0);
10109afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov    Offset = DAG.getConstant(RHSC, VT);
10119afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov    AM = ISD::POST_INC;
10129afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov    return true;
1013b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands  }
10149afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
10159afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  return false;
10169afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov}
10179afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
10189afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov
10199afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikovconst char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
10209afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov  switch (Opcode) {
10218b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  default: return NULL;
10228b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  case MSP430ISD::RET_FLAG:           return "MSP430ISD::RET_FLAG";
10238b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  case MSP430ISD::RETI_FLAG:          return "MSP430ISD::RETI_FLAG";
10248b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  case MSP430ISD::RRA:                return "MSP430ISD::RRA";
10258b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  case MSP430ISD::RLA:                return "MSP430ISD::RLA";
10262625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430ISD::RRC:                return "MSP430ISD::RRC";
1027af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman  case MSP430ISD::CALL:               return "MSP430ISD::CALL";
10282625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430ISD::Wrapper:            return "MSP430ISD::Wrapper";
10292625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430ISD::BR_CC:              return "MSP430ISD::BR_CC";
10302625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430ISD::CMP:                return "MSP430ISD::CMP";
10312625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430ISD::SELECT_CC:          return "MSP430ISD::SELECT_CC";
10322625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430ISD::SHL:                return "MSP430ISD::SHL";
10332625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430ISD::SRA:                return "MSP430ISD::SRA";
10342625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  }
10352625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov}
10362625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10372625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikovbool MSP430TargetLowering::isTruncateFree(Type *Ty1,
10382625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                                          Type *Ty2) const {
10392625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy())
10402625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    return false;
10412625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10422625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  return (Ty1->getPrimitiveSizeInBits() > Ty2->getPrimitiveSizeInBits());
10432625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov}
10442625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10452625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikovbool MSP430TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const {
10462625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  if (!VT1.isInteger() || !VT2.isInteger())
10472625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    return false;
10482625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10492625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  return (VT1.getSizeInBits() > VT2.getSizeInBits());
10502625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov}
10512625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10522625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikovbool MSP430TargetLowering::isZExtFree(Type *Ty1, Type *Ty2) const {
10532625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
10542625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  return 0 && Ty1->isIntegerTy(8) && Ty2->isIntegerTy(16);
10552625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov}
10562625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10572625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikovbool MSP430TargetLowering::isZExtFree(EVT VT1, EVT VT2) const {
10582625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // MSP430 implicitly zero-extends 8-bit results in 16-bit registers.
10592625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  return 0 && VT1 == MVT::i8 && VT2 == MVT::i16;
10602625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov}
10612625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10622625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikovbool MSP430TargetLowering::isZExtFree(SDValue Val, EVT VT2) const {
10632625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  return isZExtFree(Val.getValueType(), VT2);
10642625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov}
10652625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10662625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov//===----------------------------------------------------------------------===//
10672625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov//  Other Lowering Code
10682625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov//===----------------------------------------------------------------------===//
10692625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
10702625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMachineBasicBlock*
10712625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMSP430TargetLowering::EmitShiftInstr(MachineInstr *MI,
10722625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                                     MachineBasicBlock *BB) const {
10732625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineFunction *F = BB->getParent();
10742625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineRegisterInfo &RI = F->getRegInfo();
10752625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  DebugLoc dl = MI->getDebugLoc();
10762625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
107714152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman
107814152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  unsigned Opc;
107914152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  const TargetRegisterClass * RC;
108014152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  switch (MI->getOpcode()) {
10812625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  default: llvm_unreachable("Invalid shift opcode!");
10822625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Shl8:
10832625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SHL8r1;
10842625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   RC = &MSP430::GR8RegClass;
10852625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
10862625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Shl16:
10872625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SHL16r1;
10882625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   RC = &MSP430::GR16RegClass;
10892625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
10902625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Sra8:
10912625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR8r1;
10922625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   RC = &MSP430::GR8RegClass;
10932625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
10942625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Sra16:
10952625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR16r1;
10962625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   RC = &MSP430::GR16RegClass;
10972625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
10982625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Srl8:
1099f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov   Opc = MSP430::SAR8r1c;
1100f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov   RC = &MSP430::GR8RegClass;
11012625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
11022625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  case MSP430::Srl16:
11032625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   Opc = MSP430::SAR16r1c;
11042625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   RC = &MSP430::GR16RegClass;
11052625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov   break;
11062625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  }
11072625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11082625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  const BasicBlock *LLVM_BB = BB->getBasicBlock();
11092625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineFunction::iterator I = BB;
11102625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  ++I;
11112625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11122625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Create loop block
11132625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB);
11142625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  MachineBasicBlock *RemBB  = F->CreateMachineBasicBlock(LLVM_BB);
11152625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11162625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  F->insert(I, LoopBB);
11172625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  F->insert(I, RemBB);
11182625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11192625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // Update machine-CFG edges by transferring all successors of the current
11202625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // block to the block containing instructions after shift.
11212625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  RemBB->splice(RemBB->begin(), BB,
11222625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                llvm::next(MachineBasicBlock::iterator(MI)),
11232625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov                BB->end());
11242625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  RemBB->transferSuccessorsAndUpdatePHIs(BB);
11252625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
112614152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  // Add adges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB
11272625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BB->addSuccessor(LoopBB);
11282625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BB->addSuccessor(RemBB);
11292625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  LoopBB->addSuccessor(RemBB);
113014152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  LoopBB->addSuccessor(LoopBB);
11312625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11322625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned ShiftAmtReg = RI.createVirtualRegister(&MSP430::GR8RegClass);
11332625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned ShiftAmtReg2 = RI.createVirtualRegister(&MSP430::GR8RegClass);
11342625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned ShiftReg = RI.createVirtualRegister(RC);
11358b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  unsigned ShiftReg2 = RI.createVirtualRegister(RC);
1136af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman  unsigned ShiftAmtSrcReg = MI->getOperand(2).getReg();
11372625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned SrcReg = MI->getOperand(1).getReg();
11382625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  unsigned DstReg = MI->getOperand(0).getReg();
11392625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov
11402625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // BB:
11412625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  // cmp 0, N
1142af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman  // je RemBB
11432625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov  BuildMI(BB, dl, TII.get(MSP430::CMP8ri))
11448b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addReg(ShiftAmtSrcReg).addImm(0);
11458b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BuildMI(BB, dl, TII.get(MSP430::JCC))
11462625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addMBB(RemBB)
11472625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov    .addImm(MSP430CC::COND_E);
11488b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
11498b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // LoopBB:
11508b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB]
11518b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // ShiftAmt = phi [%N, BB],      [%ShiftAmt2, LoopBB]
11528b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // ShiftReg2 = shift ShiftReg
11538b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // ShiftAmt2 = ShiftAmt - 1;
11548b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftReg)
11558b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addReg(SrcReg).addMBB(BB)
11568b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addReg(ShiftReg2).addMBB(LoopBB);
11578b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg)
11588b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addReg(ShiftAmtSrcReg).addMBB(BB)
11598b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addReg(ShiftAmtReg2).addMBB(LoopBB);
11608b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2)
11618b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addReg(ShiftReg);
11628b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2)
11638b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addReg(ShiftAmtReg).addImm(1);
11648b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BuildMI(LoopBB, dl, TII.get(MSP430::JCC))
11658b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addMBB(LoopBB)
11668b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addImm(MSP430CC::COND_NE);
11678b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
11688b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // RemBB:
11698b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB]
11708b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  BuildMI(*RemBB, RemBB->begin(), dl, TII.get(MSP430::PHI), DstReg)
11718b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    .addReg(SrcReg).addMBB(BB)
117214152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman    .addReg(ShiftReg2).addMBB(LoopBB);
117314152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman
117414152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  MI->eraseFromParent();   // The pseudo instruction is gone now.
117514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  return RemBB;
11768b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov}
11778b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
11788b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMachineBasicBlock*
11798b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
118014152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman                                                  MachineBasicBlock *BB) const {
118114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  unsigned Opc = MI->getOpcode();
118214152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman
118314152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 ||
11848b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov      Opc == MSP430::Sra8 || Opc == MSP430::Sra16 ||
11858b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov      Opc == MSP430::Srl8 || Opc == MSP430::Srl16)
11868b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov    return EmitShiftInstr(MI, BB);
11878b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
11888b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
11898b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  DebugLoc dl = MI->getDebugLoc();
11908b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
11918b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  assert((Opc == MSP430::Select16 || Opc == MSP430::Select8) &&
11928b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov         "Unexpected instr type to insert");
11938b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov
11948b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // To "insert" a SELECT instruction, we actually have to insert the diamond
11958b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // control-flow pattern.  The incoming instruction knows the destination vreg
119614152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman  // to set, the condition code register to branch on, the true/false values to
11978b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  // select between, and a branch opcode to use.
11988b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  const BasicBlock *LLVM_BB = BB->getBasicBlock();
11998b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  MachineFunction::iterator I = BB;
12008b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  ++I;
120114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman
12028b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  thisMBB:
12038b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov  //  ...
1204  //   TrueVal = ...
1205  //   cmpTY ccX, r1, r2
1206  //   jCC copy1MBB
1207  //   fallthrough --> copy0MBB
1208  MachineBasicBlock *thisMBB = BB;
1209  MachineFunction *F = BB->getParent();
1210  MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
1211  MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB);
1212  F->insert(I, copy0MBB);
1213  F->insert(I, copy1MBB);
1214  // Update machine-CFG edges by transferring all successors of the current
1215  // block to the new block which will contain the Phi node for the select.
1216  copy1MBB->splice(copy1MBB->begin(), BB,
1217                   llvm::next(MachineBasicBlock::iterator(MI)),
1218                   BB->end());
1219  copy1MBB->transferSuccessorsAndUpdatePHIs(BB);
1220  // Next, add the true and fallthrough blocks as its successors.
1221  BB->addSuccessor(copy0MBB);
1222  BB->addSuccessor(copy1MBB);
1223
1224  BuildMI(BB, dl, TII.get(MSP430::JCC))
1225    .addMBB(copy1MBB)
1226    .addImm(MI->getOperand(3).getImm());
1227
1228  //  copy0MBB:
1229  //   %FalseValue = ...
1230  //   # fallthrough to copy1MBB
1231  BB = copy0MBB;
1232
1233  // Update machine-CFG edges
1234  BB->addSuccessor(copy1MBB);
1235
1236  //  copy1MBB:
1237  //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
1238  //  ...
1239  BB = copy1MBB;
1240  BuildMI(*BB, BB->begin(), dl, TII.get(MSP430::PHI),
1241          MI->getOperand(0).getReg())
1242    .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB)
1243    .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB);
1244
1245  MI->eraseFromParent();   // The pseudo instruction is gone now.
1246  return BB;
1247}
1248