MSP430ISelLowering.cpp revision 06ccca5f70ef5f9c3e4add60b6fc842916705029
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 "MSP430TargetMachine.h" 20f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430Subtarget.h" 21f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/DerivedTypes.h" 22f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/Function.h" 23f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/Intrinsics.h" 24f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CallingConv.h" 25f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/GlobalVariable.h" 26f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/GlobalAlias.h" 27f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/CallingConvLower.h" 28f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h" 29f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineFunction.h" 30f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h" 31f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineRegisterInfo.h" 32c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov#include "llvm/CodeGen/PseudoSourceValue.h" 33f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/SelectionDAGISel.h" 34f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/ValueTypes.h" 35f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner#include "llvm/Target/TargetLoweringObjectFile.h" 36b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov#include "llvm/Support/CommandLine.h" 37f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/Support/Debug.h" 38804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin#include "llvm/Support/ErrorHandling.h" 394437ae213d5435390f0750213b53ec807c047f22Chris Lattner#include "llvm/Support/raw_ostream.h" 40f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/ADT/VectorExtras.h" 41f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovusing namespace llvm; 42f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 43b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikovtypedef enum { 44b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov NoHWMult, 45b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov HWMultIntr, 46b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov HWMultNoIntr 47b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov} HWMultUseMode; 48b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov 49b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikovstatic cl::opt<HWMultUseMode> 50b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton KorobeynikovHWMultMode("msp430-hwmult-mode", 51b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov cl::desc("Hardware multiplier use mode"), 52b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov cl::init(HWMultNoIntr), 53b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov cl::values( 54b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov clEnumValN(NoHWMult, "no", 55b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov "Do not use hardware multiplier"), 56b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov clEnumValN(HWMultIntr, "interrupts", 57b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov "Assume hardware multiplier can be used inside interrupts"), 58b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov clEnumValN(HWMultNoIntr, "use", 59b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov "Assume hardware multiplier cannot be used inside interrupts"), 60b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov clEnumValEnd)); 61b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov 62f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovMSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) : 63f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner TargetLowering(tm, new TargetLoweringObjectFileELF()), 64f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner Subtarget(*tm.getSubtargetImpl()), TM(tm) { 65f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 6606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov TD = getTargetData(); 6706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 68f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov // Set up the register classes. 69825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson addRegisterClass(MVT::i8, MSP430::GR8RegisterClass); 70825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson addRegisterClass(MVT::i16, MSP430::GR16RegisterClass); 71f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 72f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov // Compute derived properties from the register classes 73f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov computeRegisterProperties(); 74fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 751476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov // Provide all sorts of operation actions 761476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov 771476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov // Division is expensive 781476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov setIntDivIsCheap(false); 791476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov 80d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // Even if we have only 1 bit shift here, we can perform 81d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // shifts of the whole bitwidth 1 bit per step. 82825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setShiftAmountType(MVT::i8); 83d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 84c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov setStackPointerRegisterToSaveRestore(MSP430::SPW); 85c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov setBooleanContents(ZeroOrOneBooleanContent); 86c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov setSchedulingPreference(SchedulingForLatency); 87c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov 8806ac0820a6cefa6896000054d8e4906326c0cce6Anton Korobeynikov // We have post-incremented loads / stores. 896534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setIndexedLoadAction(ISD::POST_INC, MVT::i8, Legal); 906534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setIndexedLoadAction(ISD::POST_INC, MVT::i16, Legal); 916534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 926534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); 936534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); 946534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); 956534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Expand); 96825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Expand); 9736b6e533c1aac85452438161f7034a9f54bd1830Anton Korobeynikov 9854f30d3fc94e055f13e6744378323d05c5c050baAnton Korobeynikov // We don't have any truncstores 99825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setTruncStoreAction(MVT::i16, MVT::i8, Expand); 100825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 101825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRA, MVT::i8, Custom); 102825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SHL, MVT::i8, Custom); 103825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRL, MVT::i8, Custom); 104825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRA, MVT::i16, Custom); 105825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SHL, MVT::i16, Custom); 106825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRL, MVT::i16, Custom); 107825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ROTL, MVT::i8, Expand); 108825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ROTR, MVT::i8, Expand); 109825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ROTL, MVT::i16, Expand); 110825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ROTR, MVT::i16, Expand); 111825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::GlobalAddress, MVT::i16, Custom); 112825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ExternalSymbol, MVT::i16, Custom); 113825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BR_JT, MVT::Other, Expand); 114825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BRIND, MVT::Other, Expand); 115825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BR_CC, MVT::i8, Custom); 116825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BR_CC, MVT::i16, Custom); 117825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BRCOND, MVT::Other, Expand); 118825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SETCC, MVT::i8, Expand); 119825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SETCC, MVT::i16, Expand); 120825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT, MVT::i8, Expand); 121825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT, MVT::i16, Expand); 122825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT_CC, MVT::i8, Custom); 123825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT_CC, MVT::i16, Custom); 124825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SIGN_EXTEND, MVT::i16, Custom); 125379a087cc7175532ff0c24c60069da5eec596879Anton Korobeynikov setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i8, Expand); 126379a087cc7175532ff0c24c60069da5eec596879Anton Korobeynikov setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i16, Expand); 127825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 128825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTTZ, MVT::i8, Expand); 129825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTTZ, MVT::i16, Expand); 130825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTLZ, MVT::i8, Expand); 131825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTLZ, MVT::i16, Expand); 132825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTPOP, MVT::i8, Expand); 133825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTPOP, MVT::i16, Expand); 134825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 135825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SHL_PARTS, MVT::i8, Expand); 136825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SHL_PARTS, MVT::i16, Expand); 137825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRL_PARTS, MVT::i8, Expand); 138825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRL_PARTS, MVT::i16, Expand); 139825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRA_PARTS, MVT::i8, Expand); 140825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRA_PARTS, MVT::i16, Expand); 141825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 142825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); 143e4ce880dfa340bf45ddce10bb1dbe856553677b6Eli Friedman 1448725bd22bf91c29e2351a127295c19fea996e2c7Anton Korobeynikov // FIXME: Implement efficiently multiplication by a constant 1458983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::MUL, MVT::i8, Expand); 1468983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::MULHS, MVT::i8, Expand); 1478983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::MULHU, MVT::i8, Expand); 1488983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::SMUL_LOHI, MVT::i8, Expand); 1498983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::UMUL_LOHI, MVT::i8, Expand); 150825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::MUL, MVT::i16, Expand); 151825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::MULHS, MVT::i16, Expand); 152825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::MULHU, MVT::i16, Expand); 153825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SMUL_LOHI, MVT::i16, Expand); 154825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UMUL_LOHI, MVT::i16, Expand); 155825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 1568983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::UDIV, MVT::i8, Expand); 1578983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::UDIVREM, MVT::i8, Expand); 1588983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::UREM, MVT::i8, Expand); 1598983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::SDIV, MVT::i8, Expand); 1608983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::SDIVREM, MVT::i8, Expand); 1618983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::SREM, MVT::i8, Expand); 162825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UDIV, MVT::i16, Expand); 163825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UDIVREM, MVT::i16, Expand); 164825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UREM, MVT::i16, Expand); 165825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SDIV, MVT::i16, Expand); 166825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SDIVREM, MVT::i16, Expand); 167825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SREM, MVT::i16, Expand); 168b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov 169b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov // Libcalls names. 170b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov if (HWMultMode == HWMultIntr) { 171b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I8, "__mulqi3hw"); 172b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I16, "__mulhi3hw"); 173b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov } else if (HWMultMode == HWMultNoIntr) { 174b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I8, "__mulqi3hw_noint"); 175b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I16, "__mulhi3hw_noint"); 176b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov } 177f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 178f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 179b8639f52143c99a3902b83555db4c54766c783caAnton KorobeynikovSDValue MSP430TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { 180f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov switch (Op.getOpcode()) { 181ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov case ISD::SHL: // FALLTHROUGH 182e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case ISD::SRL: 1834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case ISD::SRA: return LowerShifts(Op, DAG); 1843513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); 1855d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG); 1861bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case ISD::BR_CC: return LowerBR_CC(Op, DAG); 1871bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); 188b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov case ISD::SIGN_EXTEND: return LowerSIGN_EXTEND(Op, DAG); 18906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); 19006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); 191f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov default: 192c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("unimplemented operand"); 193f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov return SDValue(); 194f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov } 195f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 196f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 197b4202b84d7e54efe5e144885c7da63e6cc465f80Bill Wendling/// getFunctionAlignment - Return the Log2 alignment of this function. 19820c568f366be211323eeaf0e45ef053278ec9ddcBill Wendlingunsigned MSP430TargetLowering::getFunctionAlignment(const Function *F) const { 1993741be39f98795a841a4d8c35bf54928769ac3cdAnton Korobeynikov return F->hasFnAttr(Attribute::OptimizeForSize) ? 1 : 2; 20020c568f366be211323eeaf0e45ef053278ec9ddcBill Wendling} 20120c568f366be211323eeaf0e45ef053278ec9ddcBill Wendling 202c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===// 203cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov// MSP430 Inline Assembly Support 204cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===// 205cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 206cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// getConstraintType - Given a constraint letter, return the type of 207cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// constraint it is for this target. 208cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovTargetLowering::ConstraintType 209cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering::getConstraintType(const std::string &Constraint) const { 210cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov if (Constraint.size() == 1) { 211cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov switch (Constraint[0]) { 212cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov case 'r': 213cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return C_RegisterClass; 214cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov default: 215cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov break; 216cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 217cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 218cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return TargetLowering::getConstraintType(Constraint); 219cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov} 220cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 221cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikovstd::pair<unsigned, const TargetRegisterClass*> 222cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering:: 223cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovgetRegForInlineAsmConstraint(const std::string &Constraint, 224cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov EVT VT) const { 225cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov if (Constraint.size() == 1) { 226cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov // GCC Constraint Letters 227cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov switch (Constraint[0]) { 228cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov default: break; 229cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov case 'r': // GENERAL_REGS 230cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov if (VT == MVT::i8) 231cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return std::make_pair(0U, MSP430::GR8RegisterClass); 232cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 233cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return std::make_pair(0U, MSP430::GR16RegisterClass); 234cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 235cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 236cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 237cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); 238cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov} 239cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 240cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===// 241c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// Calling Convention Implementation 242c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===// 243c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 244f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430GenCallingConv.inc" 245c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 24698ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 24798ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerFormalArguments(SDValue Chain, 24865c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, 24998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isVarArg, 25098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> 25198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Ins, 25298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DebugLoc dl, 25398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SelectionDAG &DAG, 25498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SmallVectorImpl<SDValue> &InVals) { 25598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 25698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman switch (CallConv) { 257c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov default: 258c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Unsupported calling convention"); 259c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov case CallingConv::C: 260c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov case CallingConv::Fast: 26198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals); 262e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov case CallingConv::MSP430_INTR: 263e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov if (Ins.empty()) 264e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov return Chain; 265e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov else { 266e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov llvm_report_error("ISRs cannot have arguments"); 267e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov return SDValue(); 268e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov } 269c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 270c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov} 271c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 27298ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 27398ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCall(SDValue Chain, SDValue Callee, 27465c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 27598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isTailCall, 27698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::OutputArg> &Outs, 27798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> &Ins, 27898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DebugLoc dl, SelectionDAG &DAG, 27998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SmallVectorImpl<SDValue> &InVals) { 28098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 28198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman switch (CallConv) { 2824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov default: 283c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Unsupported calling convention"); 2844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CallingConv::Fast: 2854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CallingConv::C: 28698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall, 28798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman Outs, Ins, dl, DAG, InVals); 288e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov case CallingConv::MSP430_INTR: 289e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov llvm_report_error("ISRs cannot be called directly"); 290e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov return SDValue(); 2914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 2924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 2934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 294c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// LowerCCCArguments - transform physical registers into virtual registers and 295c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// generate load operations for arguments places on the stack. 296c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// FIXME: struct return stuff 297c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// FIXME: varargs 29898ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 29998ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCArguments(SDValue Chain, 30065c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, 30198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isVarArg, 30298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> 30398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Ins, 30498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DebugLoc dl, 30598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SelectionDAG &DAG, 30698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SmallVectorImpl<SDValue> &InVals) { 307c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineFunction &MF = DAG.getMachineFunction(); 308c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 309c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineRegisterInfo &RegInfo = MF.getRegInfo(); 310c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 311c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Assign locations to all of the incoming arguments. 312c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov SmallVector<CCValAssign, 16> ArgLocs; 31398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCState CCInfo(CallConv, isVarArg, getTargetMachine(), 31498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman ArgLocs, *DAG.getContext()); 31598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeFormalArguments(Ins, CC_MSP430); 316c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 317c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov assert(!isVarArg && "Varargs not supported yet"); 318c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 319c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 320c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov CCValAssign &VA = ArgLocs[i]; 321c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.isRegLoc()) { 322c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Arguments passed in registers 323e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT RegVT = VA.getLocVT(); 324825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson switch (RegVT.getSimpleVT().SimpleTy) { 325804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin default: 326804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin { 327dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#ifndef NDEBUG 3284437ae213d5435390f0750213b53ec807c047f22Chris Lattner errs() << "LowerFormalArguments Unhandled argument type: " 329825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson << RegVT.getSimpleVT().SimpleTy << "\n"; 330dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#endif 331c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable(0); 332804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin } 333825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i16: 334c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov unsigned VReg = 3351df221f2bb8e8380e255d1bec73ab07b388d01a2Anton Korobeynikov RegInfo.createVirtualRegister(MSP430::GR16RegisterClass); 336c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov RegInfo.addLiveIn(VA.getLocReg(), VReg); 33798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, RegVT); 338c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 339c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // If this is an 8-bit value, it is really passed promoted to 16 340c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // bits. Insert an assert[sz]ext to capture this, then truncate to the 341c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // right size. 342c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.getLocInfo() == CCValAssign::SExt) 343c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue, 344c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov DAG.getValueType(VA.getValVT())); 345c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov else if (VA.getLocInfo() == CCValAssign::ZExt) 346c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue, 347c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov DAG.getValueType(VA.getValVT())); 348c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 349c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.getLocInfo() != CCValAssign::Full) 350c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); 351c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 35298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman InVals.push_back(ArgValue); 353c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 354c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } else { 355c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Sanity check 356c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov assert(VA.isMemLoc()); 357c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Load the argument to a virtual register 358c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov unsigned ObjSize = VA.getLocVT().getSizeInBits()/8; 359c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (ObjSize > 2) { 3604437ae213d5435390f0750213b53ec807c047f22Chris Lattner errs() << "LowerFormalArguments Unhandled argument type: " 361825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson << VA.getLocVT().getSimpleVT().SimpleTy 362c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov << "\n"; 363c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 364c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Create the frame index object for this incoming parameter... 3653f2bf85d14759cc4b28a86805f566ac805a54d00David Greene int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true, false); 366c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 367c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Create the SelectionDAG nodes corresponding to a load 368c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov //from this parameter 369825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue FIN = DAG.getFrameIndex(FI, MVT::i16); 37098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, 3716553155172a2e74feff1253837daa608123de54aEvan Cheng PseudoSourceValue::getFixedStack(FI), 0)); 372c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 373c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 374c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 37598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return Chain; 376c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov} 377fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 37898ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 37998ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerReturn(SDValue Chain, 38065c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 38198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::OutputArg> &Outs, 38298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DebugLoc dl, SelectionDAG &DAG) { 38398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 384fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // CCValAssign - represent the assignment of the return value to a location 385fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov SmallVector<CCValAssign, 16> RVLocs; 386fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 387e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov // ISRs cannot return any value. 388e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov if (CallConv == CallingConv::MSP430_INTR && !Outs.empty()) { 389e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov llvm_report_error("ISRs cannot return any value"); 390e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov return SDValue(); 391e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov } 392e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov 393fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // CCState - Info about the registers and stack slot. 39498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCState CCInfo(CallConv, isVarArg, getTargetMachine(), 39598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman RVLocs, *DAG.getContext()); 396fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 39798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman // Analize return values. 39898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeReturn(Outs, RetCC_MSP430); 399fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 400fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // If this is the first return lowered for this function, add the regs to the 401fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // liveout set for the function. 402fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (DAG.getMachineFunction().getRegInfo().liveout_empty()) { 403fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov for (unsigned i = 0; i != RVLocs.size(); ++i) 404fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (RVLocs[i].isRegLoc()) 405fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); 406fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 407fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 408fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov SDValue Flag; 409fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 410fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // Copy the result values into the output registers. 411fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov for (unsigned i = 0; i != RVLocs.size(); ++i) { 412fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov CCValAssign &VA = RVLocs[i]; 413fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov assert(VA.isRegLoc() && "Can only return in registers!"); 414fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 415fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), 41698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman Outs[i].Val, Flag); 417fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 418dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov // Guarantee that all emitted copies are stuck together, 419dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov // avoiding something bad. 420fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov Flag = Chain.getValue(1); 421fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 422fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 423e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov unsigned Opc = (CallConv == CallingConv::MSP430_INTR ? 424e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG); 425e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov 426fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (Flag.getNode()) 427e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov return DAG.getNode(Opc, dl, MVT::Other, Chain, Flag); 428fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 429fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // Return Void 430e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov return DAG.getNode(Opc, dl, MVT::Other, Chain); 431fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov} 432fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 4334428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// LowerCCCCallTo - functions arguments are copied from virtual regs to 4344428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted. 4354428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// TODO: sret. 43698ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 43798ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, 43865c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 43998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isTailCall, 44098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::OutputArg> 44198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Outs, 44298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> &Ins, 44398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DebugLoc dl, SelectionDAG &DAG, 44498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SmallVectorImpl<SDValue> &InVals) { 4454428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Analyze operands of the call, assigning locations to each operand. 4464428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<CCValAssign, 16> ArgLocs; 44798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCState CCInfo(CallConv, isVarArg, getTargetMachine(), 44898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman ArgLocs, *DAG.getContext()); 4494428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 45098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeCallOperands(Outs, CC_MSP430); 4514428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4524428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Get a count of how many bytes are to be pushed on the stack. 4534428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov unsigned NumBytes = CCInfo.getNextStackOffset(); 4544428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4554428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCALLSEQ_START(Chain ,DAG.getConstant(NumBytes, 4564428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov getPointerTy(), true)); 4574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4584428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass; 4594428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<SDValue, 12> MemOpChains; 4604428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue StackPtr; 4614428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4624428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Walk the register/memloc assignments, inserting copies/loads. 4634428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 4644428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov CCValAssign &VA = ArgLocs[i]; 4654428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 46698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SDValue Arg = Outs[i].Val; 4674428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4684428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Promote the value if needed. 4694428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov switch (VA.getLocInfo()) { 470c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Unknown loc info!"); 4714428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::Full: break; 4724428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::SExt: 4734428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); 4744428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 4754428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::ZExt: 4764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg); 4774428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 4784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::AExt: 4794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); 4804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 4814428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 4824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Arguments that can be passed on register must be kept at RegsToPass 4844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // vector 4854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (VA.isRegLoc()) { 4864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 4874428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } else { 4884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov assert(VA.isMemLoc()); 4894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (StackPtr.getNode() == 0) 4914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SPW, getPointerTy()); 4924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), 4944428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov StackPtr, 4954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG.getIntPtrConstant(VA.getLocMemOffset())); 4964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4974428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, 4994428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov PseudoSourceValue::getStack(), 5004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov VA.getLocMemOffset())); 5014428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 5024428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 5034428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5044428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Transform all store nodes into one single node because all store nodes are 5054428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // independent of each other. 5064428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (!MemOpChains.empty()) 507825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 5084428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov &MemOpChains[0], MemOpChains.size()); 5094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5104428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Build a sequence of copy-to-reg nodes chained together with token chain and 5114428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // flag operands which copy the outgoing args into registers. The InFlag in 5124428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // necessary since all emited instructions must be stuck together. 5134428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue InFlag; 5144428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 5154428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, 5164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RegsToPass[i].second, InFlag); 5174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(1); 5184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 5194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5204428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // If the callee is a GlobalAddress node (quite common, every direct call is) 5214428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 5224428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Likewise ExternalSymbol -> TargetExternalSymbol. 5234428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 524825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Callee = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i16); 5254428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) 526825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i16); 5274428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5284428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Returns a chain & a flag for retval copy to use. 529825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); 5304428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<SDValue, 8> Ops; 5314428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(Chain); 5324428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(Callee); 5334428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5344428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Add argument registers to the end of the list so that they are 5354428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // known live into the call. 5364428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 5374428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(DAG.getRegister(RegsToPass[i].first, 5384428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RegsToPass[i].second.getValueType())); 5394428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5404428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (InFlag.getNode()) 5414428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(InFlag); 5424428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5434428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getNode(MSP430ISD::CALL, dl, NodeTys, &Ops[0], Ops.size()); 5444428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(1); 5454428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5464428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Create the CALLSEQ_END node. 5474428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCALLSEQ_END(Chain, 5484428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG.getConstant(NumBytes, getPointerTy(), true), 5494428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG.getConstant(0, getPointerTy(), true), 5504428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag); 5514428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(1); 5524428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5534428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Handle result values, copying them out of physregs into vregs that we 5544428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // return. 55598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl, 55698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DAG, InVals); 5574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 5584428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 55998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// LowerCallResult - Lower the result values of a call into the 56098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// appropriate copies out of appropriate physical registers. 56198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// 56298ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 5634428885c5acfffbbdd03ad2aab23960531c47753Anton KorobeynikovMSP430TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, 56465c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 56598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> &Ins, 56698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DebugLoc dl, SelectionDAG &DAG, 56798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SmallVectorImpl<SDValue> &InVals) { 5684428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5694428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Assign locations to each value returned by this call. 5704428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<CCValAssign, 16> RVLocs; 57198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCState CCInfo(CallConv, isVarArg, getTargetMachine(), 572e922c0201916e0b980ab3cfe91e1413e68d55647Owen Anderson RVLocs, *DAG.getContext()); 5734428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 57498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeCallResult(Ins, RetCC_MSP430); 5754428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Copy all of the result registers out of their specified physreg. 5774428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0; i != RVLocs.size(); ++i) { 5784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(), 5794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RVLocs[i].getValVT(), InFlag).getValue(1); 5804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(2); 58198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman InVals.push_back(Chain.getValue(0)); 5824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 5834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 58498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return Chain; 5854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 5864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 587d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton KorobeynikovSDValue MSP430TargetLowering::LowerShifts(SDValue Op, 588d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov SelectionDAG &DAG) { 589ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov unsigned Opc = Op.getOpcode(); 590d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov SDNode* N = Op.getNode(); 591e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Op.getValueType(); 592d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov DebugLoc dl = N->getDebugLoc(); 593d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 594ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov // We currently only lower shifts of constant argument. 595d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov if (!isa<ConstantSDNode>(N->getOperand(1))) 596d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov return SDValue(); 597d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 598d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue(); 599d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 600d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // Expand the stuff into sequence of shifts. 601d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // FIXME: for some shift amounts this might be done better! 602d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N 603d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov SDValue Victim = N->getOperand(0); 604e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov 605e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov if (Opc == ISD::SRL && ShiftAmount) { 606e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov // Emit a special goodness here: 607e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov // srl A, 1 => clrc; rrc A 608bf8ef3f29de28529b5d65970af9015c41f7c809bAnton Korobeynikov Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim); 609e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov ShiftAmount -= 1; 610e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov } 611e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov 612d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov while (ShiftAmount--) 613aceb620de855485a4fb2eed343d880d76f6c701cAnton Korobeynikov Victim = DAG.getNode((Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA), 614ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov dl, VT, Victim); 615d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 616d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov return Victim; 617d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov} 618d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 6193513ca81c6beda087a281a66f1b0e612879c0aadAnton KorobeynikovSDValue MSP430TargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) { 6203513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); 6213513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset(); 6223513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov 6233513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov // Create the TargetGlobalAddress node, folding in the constant offset. 6243513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov SDValue Result = DAG.getTargetGlobalAddress(GV, getPointerTy(), Offset); 6253513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov return DAG.getNode(MSP430ISD::Wrapper, Op.getDebugLoc(), 6263513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov getPointerTy(), Result); 6273513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov} 6283513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov 6295d59f68ade7573175f1ace09061a94286e59076bAnton KorobeynikovSDValue MSP430TargetLowering::LowerExternalSymbol(SDValue Op, 6305d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov SelectionDAG &DAG) { 6315d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 6325d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol(); 6335d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov SDValue Result = DAG.getTargetExternalSymbol(Sym, getPointerTy()); 6345d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov 6355d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result);; 6365d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov} 6375d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov 6383926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikovstatic SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC, 6391bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC, 6401bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov DebugLoc dl, SelectionDAG &DAG) { 641ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov // FIXME: Handle bittests someday 642ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet"); 643ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 644ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov // FIXME: Handle jump negative someday 6453926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov MSP430CC::CondCodes TCC = MSP430CC::COND_INVALID; 646ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov switch (CC) { 647c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Invalid integer condition!"); 648ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETEQ: 6493926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_E; // aka COND_Z 6501722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov // Minor optimization: if RHS is a constant, swap operands, then the 6511722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov // constant can be folded into comparison. 6521722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov if (RHS.getOpcode() == ISD::Constant) 6531722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov std::swap(LHS, RHS); 654ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 655ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETNE: 6563926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_NE; // aka COND_NZ 6571722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov // Minor optimization: if RHS is a constant, swap operands, then the 6581722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov // constant can be folded into comparison. 6591722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov if (RHS.getOpcode() == ISD::Constant) 6601722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov std::swap(LHS, RHS); 661ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 662ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETULE: 663ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 664ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETUGE: 6653926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_HS; // aka COND_C 666ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 667ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETUGT: 668ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 669ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETULT: 6703926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_LO; // aka COND_NC 671ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 672ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETLE: 673ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 674ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETGE: 6753926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_GE; 676ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 677ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETGT: 678ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 679ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETLT: 6803926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_L; 681ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 682ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov } 683ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 6843926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TargetCC = DAG.getConstant(TCC, MVT::i8); 685825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson return DAG.getNode(MSP430ISD::CMP, dl, MVT::Flag, LHS, RHS); 686ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov} 687ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 6881bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 6891bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton KorobeynikovSDValue MSP430TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) { 690ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov SDValue Chain = Op.getOperand(0); 6911bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); 6921bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue LHS = Op.getOperand(2); 6931bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue RHS = Op.getOperand(3); 6941bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Dest = Op.getOperand(4); 6951bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 6961bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 6973926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov SDValue TargetCC; 6981bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 6991bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 7001bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(), 7013926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov Chain, Dest, TargetCC, Flag); 702ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov} 703ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 7041bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton KorobeynikovSDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) { 7051bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue LHS = Op.getOperand(0); 7061bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue RHS = Op.getOperand(1); 7071bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue TrueV = Op.getOperand(2); 7081bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue FalseV = Op.getOperand(3); 7091bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); 7108b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 7111bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 7123926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov SDValue TargetCC; 7131bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 7148b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 715825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Flag); 7168b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov SmallVector<SDValue, 4> Ops; 7178b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov Ops.push_back(TrueV); 7188b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov Ops.push_back(FalseV); 7193926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov Ops.push_back(TargetCC); 7201bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov Ops.push_back(Flag); 7218b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 7221bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size()); 7238b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov} 7248b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 725b78e214274d397407b6167a293b7cd7c3b526ddeAnton KorobeynikovSDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op, 726b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov SelectionDAG &DAG) { 727b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov SDValue Val = Op.getOperand(0); 728e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Op.getValueType(); 729b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 730b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 731825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson assert(VT == MVT::i16 && "Only support i16 for now!"); 732b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 733b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT, 734b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val), 735b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov DAG.getValueType(Val.getValueType())); 736b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov} 737b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 73806ccca5f70ef5f9c3e4add60b6fc842916705029Anton KorobeynikovSDValue MSP430TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) { 73906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MachineFunction &MF = DAG.getMachineFunction(); 74006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>(); 74106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov int ReturnAddrIndex = FuncInfo->getRAIndex(); 74206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 74306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov if (ReturnAddrIndex == 0) { 74406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov // Set up a frame object for the return address. 74506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov uint64_t SlotSize = TD->getPointerSize(); 74606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(SlotSize, -SlotSize, 74706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov true, false); 74806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov FuncInfo->setRAIndex(ReturnAddrIndex); 74906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov } 75006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 75106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy()); 75206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov} 75306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 75406ccca5f70ef5f9c3e4add60b6fc842916705029Anton KorobeynikovSDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) { 75506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); 75606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 75706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 75806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov if (Depth > 0) { 75906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue FrameAddr = LowerFRAMEADDR(Op, DAG); 76006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue Offset = 76106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov DAG.getConstant(TD->getPointerSize(), MVT::i16); 76206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), 76306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov DAG.getNode(ISD::ADD, dl, getPointerTy(), 76406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov FrameAddr, Offset), 76506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov NULL, 0); 76606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov } 76706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 76806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov // Just load the return address. 76906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue RetAddrFI = getReturnAddressFrameIndex(DAG); 77006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), 77106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov RetAddrFI, NULL, 0); 77206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov} 77306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 77406ccca5f70ef5f9c3e4add60b6fc842916705029Anton KorobeynikovSDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) { 77506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 77606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MFI->setFrameAddressIsTaken(true); 77706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov EVT VT = Op.getValueType(); 77806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov DebugLoc dl = Op.getDebugLoc(); // FIXME probably not meaningful 77906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); 78006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, 78106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MSP430::FPW, VT); 78206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov while (Depth--) 78306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr, NULL, 0); 78406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return FrameAddr; 78506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov} 78606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 7876534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// getPostIndexedAddressParts - returns true by value, base pointer and 7886534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// offset pointer and addressing mode by reference if this node can be 7896534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// combined with a load / store to form a post-indexed load / store. 7906534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikovbool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op, 7916534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SDValue &Base, 7926534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SDValue &Offset, 7936534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov ISD::MemIndexedMode &AM, 7946534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SelectionDAG &DAG) const { 7956534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 7966534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov LoadSDNode *LD = cast<LoadSDNode>(N); 7976534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (LD->getExtensionType() != ISD::NON_EXTLOAD) 7986534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 7996534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 8006534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov EVT VT = LD->getMemoryVT(); 8016534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (VT != MVT::i8 && VT != MVT::i16) 8026534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 8036534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 8046534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (Op->getOpcode() != ISD::ADD) 8056534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 8066534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 8076534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) { 8086534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov uint64_t RHSC = RHS->getZExtValue(); 8096534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if ((VT == MVT::i16 && RHSC != 2) || 8106534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov (VT == MVT::i8 && RHSC != 1)) 8116534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 8126534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 8136534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov Base = Op->getOperand(0); 8146534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov Offset = DAG.getConstant(RHSC, VT); 8156534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov AM = ISD::POST_INC; 8166534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return true; 8176534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov } 8186534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 8196534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 8206534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov} 8216534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 8226534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 823fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikovconst char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const { 824fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov switch (Opcode) { 825fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov default: return NULL; 826fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov case MSP430ISD::RET_FLAG: return "MSP430ISD::RET_FLAG"; 827d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov case MSP430ISD::RRA: return "MSP430ISD::RRA"; 828e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case MSP430ISD::RLA: return "MSP430ISD::RLA"; 829e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case MSP430ISD::RRC: return "MSP430ISD::RRC"; 830b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov case MSP430ISD::CALL: return "MSP430ISD::CALL"; 8313513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov case MSP430ISD::Wrapper: return "MSP430ISD::Wrapper"; 8321bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case MSP430ISD::BR_CC: return "MSP430ISD::BR_CC"; 833ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case MSP430ISD::CMP: return "MSP430ISD::CMP"; 8341bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case MSP430ISD::SELECT_CC: return "MSP430ISD::SELECT_CC"; 835fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 836fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov} 8378b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 8388b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===// 8398b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov// Other Lowering Code 8408b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===// 8418b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 8428b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMachineBasicBlock* 8438b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 844fb2e752e4175920d0531f2afc93a23d0cdf4db14Evan Cheng MachineBasicBlock *BB, 845fb2e752e4175920d0531f2afc93a23d0cdf4db14Evan Cheng DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const { 8468b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); 8478b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov DebugLoc dl = MI->getDebugLoc(); 848da4d2f63d8b138569ec732d970bb452a0403a3abAnton Korobeynikov assert((MI->getOpcode() == MSP430::Select16 || 849da4d2f63d8b138569ec732d970bb452a0403a3abAnton Korobeynikov MI->getOpcode() == MSP430::Select8) && 8508b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov "Unexpected instr type to insert"); 8518b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 8528b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // To "insert" a SELECT instruction, we actually have to insert the diamond 8538b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // control-flow pattern. The incoming instruction knows the destination vreg 8548b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // to set, the condition code register to branch on, the true/false values to 8558b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // select between, and a branch opcode to use. 8568b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov const BasicBlock *LLVM_BB = BB->getBasicBlock(); 8578b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineFunction::iterator I = BB; 8588b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov ++I; 8598b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 8608b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // thisMBB: 8618b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // ... 8628b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // TrueVal = ... 8638b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // cmpTY ccX, r1, r2 8648b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // jCC copy1MBB 8658b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // fallthrough --> copy0MBB 8668b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *thisMBB = BB; 8678b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineFunction *F = BB->getParent(); 8688b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); 8698b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB); 8708b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BuildMI(BB, dl, TII.get(MSP430::JCC)) 8718b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addMBB(copy1MBB) 8728b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addImm(MI->getOperand(3).getImm()); 8738b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov F->insert(I, copy0MBB); 8748b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov F->insert(I, copy1MBB); 875ce31910eae5bd4896fa6c27798e7b26885691d3bEvan Cheng // Inform sdisel of the edge changes. 876ce31910eae5bd4896fa6c27798e7b26885691d3bEvan Cheng for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), 877ce31910eae5bd4896fa6c27798e7b26885691d3bEvan Cheng SE = BB->succ_end(); SI != SE; ++SI) 878ce31910eae5bd4896fa6c27798e7b26885691d3bEvan Cheng EM->insert(std::make_pair(*SI, copy1MBB)); 8798b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Update machine-CFG edges by transferring all successors of the current 8808b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // block to the new block which will contain the Phi node for the select. 8818b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov copy1MBB->transferSuccessors(BB); 8828b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Next, add the true and fallthrough blocks as its successors. 8838b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy0MBB); 8848b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy1MBB); 8858b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 8868b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // copy0MBB: 8878b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // %FalseValue = ... 8888b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // # fallthrough to copy1MBB 8898b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB = copy0MBB; 8908b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 8918b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Update machine-CFG edges 8928b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy1MBB); 8938b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 8948b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // copy1MBB: 8958b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] 8968b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // ... 8978b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB = copy1MBB; 8988b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BuildMI(BB, dl, TII.get(MSP430::PHI), 8998b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MI->getOperand(0).getReg()) 9008b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB) 9018b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB); 9028b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 9038b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov F->DeleteMachineInstr(MI); // The pseudo instruction is gone now. 9048b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov return BB; 9058b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov} 906