MSP430ISelLowering.cpp revision 0c1ba91a54e7088fab3a3b9820f8b8366be0e11b
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); 1188d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov setOperationAction(ISD::SETCC, MVT::i8, Custom); 1198d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov setOperationAction(ISD::SETCC, MVT::i16, Custom); 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); 1868d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov case ISD::SETCC: return LowerSETCC(Op, DAG); 1871bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case ISD::BR_CC: return LowerBR_CC(Op, DAG); 1881bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); 189b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov case ISD::SIGN_EXTEND: return LowerSIGN_EXTEND(Op, DAG); 19006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); 19106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); 192f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov default: 193c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("unimplemented operand"); 194f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov return SDValue(); 195f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov } 196f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 197f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 198b4202b84d7e54efe5e144885c7da63e6cc465f80Bill Wendling/// getFunctionAlignment - Return the Log2 alignment of this function. 19920c568f366be211323eeaf0e45ef053278ec9ddcBill Wendlingunsigned MSP430TargetLowering::getFunctionAlignment(const Function *F) const { 2003741be39f98795a841a4d8c35bf54928769ac3cdAnton Korobeynikov return F->hasFnAttr(Attribute::OptimizeForSize) ? 1 : 2; 20120c568f366be211323eeaf0e45ef053278ec9ddcBill Wendling} 20220c568f366be211323eeaf0e45ef053278ec9ddcBill Wendling 203c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===// 204cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov// MSP430 Inline Assembly Support 205cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===// 206cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 207cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// getConstraintType - Given a constraint letter, return the type of 208cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// constraint it is for this target. 209cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovTargetLowering::ConstraintType 210cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering::getConstraintType(const std::string &Constraint) const { 211cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov if (Constraint.size() == 1) { 212cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov switch (Constraint[0]) { 213cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov case 'r': 214cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return C_RegisterClass; 215cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov default: 216cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov break; 217cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 218cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 219cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return TargetLowering::getConstraintType(Constraint); 220cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov} 221cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 222cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikovstd::pair<unsigned, const TargetRegisterClass*> 223cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering:: 224cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovgetRegForInlineAsmConstraint(const std::string &Constraint, 225cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov EVT VT) const { 226cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov if (Constraint.size() == 1) { 227cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov // GCC Constraint Letters 228cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov switch (Constraint[0]) { 229cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov default: break; 230cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov case 'r': // GENERAL_REGS 231cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov if (VT == MVT::i8) 232cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return std::make_pair(0U, MSP430::GR8RegisterClass); 233cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 234cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return std::make_pair(0U, MSP430::GR16RegisterClass); 235cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 236cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 237cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 238cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); 239cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov} 240cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 241cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===// 242c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// Calling Convention Implementation 243c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===// 244c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 245f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430GenCallingConv.inc" 246c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 24798ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 24898ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerFormalArguments(SDValue Chain, 24965c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, 25098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isVarArg, 25198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> 25298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Ins, 25398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DebugLoc dl, 25498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SelectionDAG &DAG, 25598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SmallVectorImpl<SDValue> &InVals) { 25698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 25798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman switch (CallConv) { 258c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov default: 259c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Unsupported calling convention"); 260c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov case CallingConv::C: 261c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov case CallingConv::Fast: 26298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals); 263e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov case CallingConv::MSP430_INTR: 264e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov if (Ins.empty()) 265e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov return Chain; 266e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov else { 267e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov llvm_report_error("ISRs cannot have arguments"); 268e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov return SDValue(); 269e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov } 270c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 271c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov} 272c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 27398ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 27498ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCall(SDValue Chain, SDValue Callee, 27565c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 27698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isTailCall, 27798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::OutputArg> &Outs, 27898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> &Ins, 27998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DebugLoc dl, SelectionDAG &DAG, 28098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SmallVectorImpl<SDValue> &InVals) { 28198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 28298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman switch (CallConv) { 2834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov default: 284c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Unsupported calling convention"); 2854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CallingConv::Fast: 2864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CallingConv::C: 28798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall, 28898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman Outs, Ins, dl, DAG, InVals); 289e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov case CallingConv::MSP430_INTR: 290e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov llvm_report_error("ISRs cannot be called directly"); 291e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov return SDValue(); 2924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 2934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 2944428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 295c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// LowerCCCArguments - transform physical registers into virtual registers and 296c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// generate load operations for arguments places on the stack. 297c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// FIXME: struct return stuff 298c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// FIXME: varargs 29998ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 30098ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCArguments(SDValue Chain, 30165c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, 30298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isVarArg, 30398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> 30498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Ins, 30598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DebugLoc dl, 30698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SelectionDAG &DAG, 30798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SmallVectorImpl<SDValue> &InVals) { 308c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineFunction &MF = DAG.getMachineFunction(); 309c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 310c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineRegisterInfo &RegInfo = MF.getRegInfo(); 311c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 312c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Assign locations to all of the incoming arguments. 313c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov SmallVector<CCValAssign, 16> ArgLocs; 31498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCState CCInfo(CallConv, isVarArg, getTargetMachine(), 31598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman ArgLocs, *DAG.getContext()); 31698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeFormalArguments(Ins, CC_MSP430); 317c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 318c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov assert(!isVarArg && "Varargs not supported yet"); 319c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 320c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 321c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov CCValAssign &VA = ArgLocs[i]; 322c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.isRegLoc()) { 323c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Arguments passed in registers 324e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT RegVT = VA.getLocVT(); 325825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson switch (RegVT.getSimpleVT().SimpleTy) { 326804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin default: 327804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin { 328dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#ifndef NDEBUG 3294437ae213d5435390f0750213b53ec807c047f22Chris Lattner errs() << "LowerFormalArguments Unhandled argument type: " 330825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson << RegVT.getSimpleVT().SimpleTy << "\n"; 331dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#endif 332c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable(0); 333804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin } 334825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i16: 335c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov unsigned VReg = 3361df221f2bb8e8380e255d1bec73ab07b388d01a2Anton Korobeynikov RegInfo.createVirtualRegister(MSP430::GR16RegisterClass); 337c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov RegInfo.addLiveIn(VA.getLocReg(), VReg); 33898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, RegVT); 339c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 340c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // If this is an 8-bit value, it is really passed promoted to 16 341c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // bits. Insert an assert[sz]ext to capture this, then truncate to the 342c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // right size. 343c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.getLocInfo() == CCValAssign::SExt) 344c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue, 345c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov DAG.getValueType(VA.getValVT())); 346c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov else if (VA.getLocInfo() == CCValAssign::ZExt) 347c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue, 348c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov DAG.getValueType(VA.getValVT())); 349c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 350c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.getLocInfo() != CCValAssign::Full) 351c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); 352c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 35398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman InVals.push_back(ArgValue); 354c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 355c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } else { 356c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Sanity check 357c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov assert(VA.isMemLoc()); 358c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Load the argument to a virtual register 359c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov unsigned ObjSize = VA.getLocVT().getSizeInBits()/8; 360c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (ObjSize > 2) { 3614437ae213d5435390f0750213b53ec807c047f22Chris Lattner errs() << "LowerFormalArguments Unhandled argument type: " 362825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson << VA.getLocVT().getSimpleVT().SimpleTy 363c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov << "\n"; 364c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 365c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Create the frame index object for this incoming parameter... 3663f2bf85d14759cc4b28a86805f566ac805a54d00David Greene int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true, false); 367c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 368c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Create the SelectionDAG nodes corresponding to a load 369c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov //from this parameter 370825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue FIN = DAG.getFrameIndex(FI, MVT::i16); 37198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, 3726553155172a2e74feff1253837daa608123de54aEvan Cheng PseudoSourceValue::getFixedStack(FI), 0)); 373c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 374c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 375c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 37698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return Chain; 377c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov} 378fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 37998ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 38098ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerReturn(SDValue Chain, 38165c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 38298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::OutputArg> &Outs, 38398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DebugLoc dl, SelectionDAG &DAG) { 38498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 385fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // CCValAssign - represent the assignment of the return value to a location 386fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov SmallVector<CCValAssign, 16> RVLocs; 387fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 388e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov // ISRs cannot return any value. 389e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov if (CallConv == CallingConv::MSP430_INTR && !Outs.empty()) { 390e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov llvm_report_error("ISRs cannot return any value"); 391e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov return SDValue(); 392e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov } 393e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov 394fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // CCState - Info about the registers and stack slot. 39598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCState CCInfo(CallConv, isVarArg, getTargetMachine(), 39698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman RVLocs, *DAG.getContext()); 397fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 39898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman // Analize return values. 39998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeReturn(Outs, RetCC_MSP430); 400fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 401fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // If this is the first return lowered for this function, add the regs to the 402fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // liveout set for the function. 403fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (DAG.getMachineFunction().getRegInfo().liveout_empty()) { 404fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov for (unsigned i = 0; i != RVLocs.size(); ++i) 405fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (RVLocs[i].isRegLoc()) 406fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); 407fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 408fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 409fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov SDValue Flag; 410fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 411fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // Copy the result values into the output registers. 412fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov for (unsigned i = 0; i != RVLocs.size(); ++i) { 413fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov CCValAssign &VA = RVLocs[i]; 414fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov assert(VA.isRegLoc() && "Can only return in registers!"); 415fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 416fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), 41798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman Outs[i].Val, Flag); 418fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 419dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov // Guarantee that all emitted copies are stuck together, 420dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov // avoiding something bad. 421fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov Flag = Chain.getValue(1); 422fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 423fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 424e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov unsigned Opc = (CallConv == CallingConv::MSP430_INTR ? 425e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG); 426e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov 427fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (Flag.getNode()) 428e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov return DAG.getNode(Opc, dl, MVT::Other, Chain, Flag); 429fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 430fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // Return Void 431e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov return DAG.getNode(Opc, dl, MVT::Other, Chain); 432fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov} 433fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 4344428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// LowerCCCCallTo - functions arguments are copied from virtual regs to 4354428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted. 4364428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// TODO: sret. 43798ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 43898ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, 43965c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 44098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isTailCall, 44198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::OutputArg> 44298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Outs, 44398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> &Ins, 44498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DebugLoc dl, SelectionDAG &DAG, 44598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SmallVectorImpl<SDValue> &InVals) { 4464428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Analyze operands of the call, assigning locations to each operand. 4474428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<CCValAssign, 16> ArgLocs; 44898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCState CCInfo(CallConv, isVarArg, getTargetMachine(), 44998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman ArgLocs, *DAG.getContext()); 4504428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 45198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeCallOperands(Outs, CC_MSP430); 4524428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4534428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Get a count of how many bytes are to be pushed on the stack. 4544428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov unsigned NumBytes = CCInfo.getNextStackOffset(); 4554428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4564428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCALLSEQ_START(Chain ,DAG.getConstant(NumBytes, 4574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov getPointerTy(), true)); 4584428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4594428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass; 4604428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<SDValue, 12> MemOpChains; 4614428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue StackPtr; 4624428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4634428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Walk the register/memloc assignments, inserting copies/loads. 4644428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 4654428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov CCValAssign &VA = ArgLocs[i]; 4664428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 46798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SDValue Arg = Outs[i].Val; 4684428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4694428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Promote the value if needed. 4704428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov switch (VA.getLocInfo()) { 471c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Unknown loc info!"); 4724428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::Full: break; 4734428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::SExt: 4744428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); 4754428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 4764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::ZExt: 4774428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg); 4784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 4794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::AExt: 4804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); 4814428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 4824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 4834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Arguments that can be passed on register must be kept at RegsToPass 4854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // vector 4864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (VA.isRegLoc()) { 4874428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 4884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } else { 4894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov assert(VA.isMemLoc()); 4904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (StackPtr.getNode() == 0) 4924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SPW, getPointerTy()); 4934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4944428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), 4954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov StackPtr, 4964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG.getIntPtrConstant(VA.getLocMemOffset())); 4974428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4994428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, 5004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov PseudoSourceValue::getStack(), 5014428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov VA.getLocMemOffset())); 5024428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 5034428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 5044428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5054428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Transform all store nodes into one single node because all store nodes are 5064428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // independent of each other. 5074428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (!MemOpChains.empty()) 508825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 5094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov &MemOpChains[0], MemOpChains.size()); 5104428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5114428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Build a sequence of copy-to-reg nodes chained together with token chain and 5124428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // flag operands which copy the outgoing args into registers. The InFlag in 5134428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // necessary since all emited instructions must be stuck together. 5144428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue InFlag; 5154428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 5164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, 5174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RegsToPass[i].second, InFlag); 5184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(1); 5194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 5204428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5214428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // If the callee is a GlobalAddress node (quite common, every direct call is) 5224428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 5234428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Likewise ExternalSymbol -> TargetExternalSymbol. 5244428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 525825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Callee = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i16); 5264428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) 527825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i16); 5284428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5294428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Returns a chain & a flag for retval copy to use. 530825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); 5314428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<SDValue, 8> Ops; 5324428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(Chain); 5334428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(Callee); 5344428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5354428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Add argument registers to the end of the list so that they are 5364428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // known live into the call. 5374428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 5384428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(DAG.getRegister(RegsToPass[i].first, 5394428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RegsToPass[i].second.getValueType())); 5404428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5414428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (InFlag.getNode()) 5424428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(InFlag); 5434428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5444428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getNode(MSP430ISD::CALL, dl, NodeTys, &Ops[0], Ops.size()); 5454428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(1); 5464428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5474428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Create the CALLSEQ_END node. 5484428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCALLSEQ_END(Chain, 5494428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG.getConstant(NumBytes, getPointerTy(), true), 5504428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG.getConstant(0, getPointerTy(), true), 5514428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag); 5524428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(1); 5534428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5544428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Handle result values, copying them out of physregs into vregs that we 5554428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // return. 55698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl, 55798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DAG, InVals); 5584428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 5594428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 56098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// LowerCallResult - Lower the result values of a call into the 56198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// appropriate copies out of appropriate physical registers. 56298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// 56398ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 5644428885c5acfffbbdd03ad2aab23960531c47753Anton KorobeynikovMSP430TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, 56565c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 56698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> &Ins, 56798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DebugLoc dl, SelectionDAG &DAG, 56898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SmallVectorImpl<SDValue> &InVals) { 5694428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5704428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Assign locations to each value returned by this call. 5714428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<CCValAssign, 16> RVLocs; 57298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCState CCInfo(CallConv, isVarArg, getTargetMachine(), 573e922c0201916e0b980ab3cfe91e1413e68d55647Owen Anderson RVLocs, *DAG.getContext()); 5744428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 57598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeCallResult(Ins, RetCC_MSP430); 5764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5774428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Copy all of the result registers out of their specified physreg. 5784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0; i != RVLocs.size(); ++i) { 5794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(), 5804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RVLocs[i].getValVT(), InFlag).getValue(1); 5814428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(2); 58298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman InVals.push_back(Chain.getValue(0)); 5834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 5844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 58598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return Chain; 5864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 5874428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 588d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton KorobeynikovSDValue MSP430TargetLowering::LowerShifts(SDValue Op, 589d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov SelectionDAG &DAG) { 590ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov unsigned Opc = Op.getOpcode(); 591d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov SDNode* N = Op.getNode(); 592e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Op.getValueType(); 593d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov DebugLoc dl = N->getDebugLoc(); 594d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 5952625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Expand non-constant shifts to loops: 596d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov if (!isa<ConstantSDNode>(N->getOperand(1))) 5972625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov switch (Opc) { 5982625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov default: 5992625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov assert(0 && "Invalid shift opcode!"); 6002625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case ISD::SHL: 6012625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return DAG.getNode(MSP430ISD::SHL, dl, 6022625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov VT, N->getOperand(0), N->getOperand(1)); 6032625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case ISD::SRA: 6042625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return DAG.getNode(MSP430ISD::SRA, dl, 6052625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov VT, N->getOperand(0), N->getOperand(1)); 6062625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case ISD::SRL: 6072625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return DAG.getNode(MSP430ISD::SRL, dl, 6082625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov VT, N->getOperand(0), N->getOperand(1)); 6092625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov } 610d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 611d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue(); 612d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 613d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // Expand the stuff into sequence of shifts. 614d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // FIXME: for some shift amounts this might be done better! 615d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N 616d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov SDValue Victim = N->getOperand(0); 617e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov 618e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov if (Opc == ISD::SRL && ShiftAmount) { 619e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov // Emit a special goodness here: 620e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov // srl A, 1 => clrc; rrc A 621bf8ef3f29de28529b5d65970af9015c41f7c809bAnton Korobeynikov Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim); 622e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov ShiftAmount -= 1; 623e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov } 624e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov 625d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov while (ShiftAmount--) 626aceb620de855485a4fb2eed343d880d76f6c701cAnton Korobeynikov Victim = DAG.getNode((Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA), 627ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov dl, VT, Victim); 628d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 629d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov return Victim; 630d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov} 631d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 6323513ca81c6beda087a281a66f1b0e612879c0aadAnton KorobeynikovSDValue MSP430TargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) { 6333513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); 6343513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset(); 6353513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov 6363513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov // Create the TargetGlobalAddress node, folding in the constant offset. 6373513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov SDValue Result = DAG.getTargetGlobalAddress(GV, getPointerTy(), Offset); 6383513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov return DAG.getNode(MSP430ISD::Wrapper, Op.getDebugLoc(), 6393513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov getPointerTy(), Result); 6403513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov} 6413513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov 6425d59f68ade7573175f1ace09061a94286e59076bAnton KorobeynikovSDValue MSP430TargetLowering::LowerExternalSymbol(SDValue Op, 6435d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov SelectionDAG &DAG) { 6445d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 6455d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol(); 6465d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov SDValue Result = DAG.getTargetExternalSymbol(Sym, getPointerTy()); 6475d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov 6485d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result);; 6495d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov} 6505d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov 6513926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikovstatic SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC, 6521bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC, 6531bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov DebugLoc dl, SelectionDAG &DAG) { 654ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov // FIXME: Handle bittests someday 655ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet"); 656ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 657ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov // FIXME: Handle jump negative someday 6583926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov MSP430CC::CondCodes TCC = MSP430CC::COND_INVALID; 659ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov switch (CC) { 660c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Invalid integer condition!"); 661ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETEQ: 6623926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_E; // aka COND_Z 663f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov // Minor optimization: if LHS is a constant, swap operands, then the 6641722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov // constant can be folded into comparison. 665f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov if (LHS.getOpcode() == ISD::Constant) 6661722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov std::swap(LHS, RHS); 667ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 668ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETNE: 6693926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_NE; // aka COND_NZ 670f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov // Minor optimization: if LHS is a constant, swap operands, then the 6711722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov // constant can be folded into comparison. 672f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov if (LHS.getOpcode() == ISD::Constant) 6731722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov std::swap(LHS, RHS); 674ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 675ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETULE: 676ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 677ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETUGE: 6780c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // Turn lhs u>= rhs with lhs constant into rhs u< lhs+1, this allows us to 6790c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // fold constant into instruction. 6800c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 6810c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov LHS = RHS; 6820c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 6830c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_LO; 6840c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov break; 6850c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov } 6863926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_HS; // aka COND_C 687ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 688ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETUGT: 689ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 690ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETULT: 6910c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // Turn lhs u< rhs with lhs constant into rhs u>= lhs+1, this allows us to 6920c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // fold constant into instruction. 6930c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 6940c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov LHS = RHS; 6950c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 6960c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_HS; 6970c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov break; 6980c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov } 6993926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_LO; // aka COND_NC 700ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 701ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETLE: 702ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 703ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETGE: 7040c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // Turn lhs >= rhs with lhs constant into rhs < lhs+1, this allows us to 7050c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // fold constant into instruction. 7060c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 7070c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov LHS = RHS; 7080c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 7090c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_L; 7100c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov break; 7110c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov } 7123926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_GE; 713ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 714ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETGT: 715ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 716ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETLT: 7170c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to 7180c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // fold constant into instruction. 7190c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 7200c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov LHS = RHS; 7210c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 7220c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_GE; 7230c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov break; 7240c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov } 7253926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_L; 726ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 727ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov } 728ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 7293926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TargetCC = DAG.getConstant(TCC, MVT::i8); 730825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson return DAG.getNode(MSP430ISD::CMP, dl, MVT::Flag, LHS, RHS); 731ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov} 732ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 7331bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 7341bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton KorobeynikovSDValue MSP430TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) { 735ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov SDValue Chain = Op.getOperand(0); 7361bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); 7371bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue LHS = Op.getOperand(2); 7381bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue RHS = Op.getOperand(3); 7391bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Dest = Op.getOperand(4); 7401bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 7411bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 7423926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov SDValue TargetCC; 7431bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 7441bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 7451bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(), 7463926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov Chain, Dest, TargetCC, Flag); 747ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov} 748ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 7498d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov 7508d1ffbd1adad453fe330be4951400bfd25fab666Anton KorobeynikovSDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) { 7518d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue LHS = Op.getOperand(0); 7528d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue RHS = Op.getOperand(1); 7538d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 7548d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov 7558d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // If we are doing an AND and testing against zero, then the CMP 7568d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // will not be generated. The AND (or BIT) will generate the condition codes, 7578d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // but they are different from CMP. 7588d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov bool andCC = false; 7598d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) { 7608d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (RHSC->isNullValue() && LHS.hasOneUse() && 7618d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov (LHS.getOpcode() == ISD::AND || 7628d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov (LHS.getOpcode() == ISD::TRUNCATE && 7638d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov LHS.getOperand(0).getOpcode() == ISD::AND))) { 7648d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov andCC = true; 7658d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 7668d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 7678d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get(); 7688d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue TargetCC; 7698d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 7708d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov 7718d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Get the condition codes directly from the status register, if its easy. 7728d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Otherwise a branch will be generated. Note that the AND and BIT 7738d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // instructions generate different flags than CMP, the carry bit can be used 7748d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // for NE/EQ. 7758d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov bool Invert = false; 7768d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov bool Shift = false; 7778d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov bool Convert = true; 7788d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov switch (cast<ConstantSDNode>(TargetCC)->getZExtValue()) { 7798d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov default: 7808d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Convert = false; 7818d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 7828d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov case MSP430CC::COND_HS: 7838d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Res = SRW & 1, no processing is required 7848d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 7858d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov case MSP430CC::COND_LO: 7868d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Res = ~(SRW & 1) 7878d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Invert = true; 7888d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 7898d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov case MSP430CC::COND_NE: 7908d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (andCC) { 7918d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // C = ~Z, thus Res = SRW & 1, no processing is required 7928d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } else { 7938d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Res = (SRW >> 1) & 1 7948d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Shift = true; 7958d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 7968d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 7978d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov case MSP430CC::COND_E: 7988d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (andCC) { 7998d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // C = ~Z, thus Res = ~(SRW & 1) 8008d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } else { 8018d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Res = ~((SRW >> 1) & 1) 8028d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Shift = true; 8038d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 8048d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Invert = true; 8058d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 8068d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 8078d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov EVT VT = Op.getValueType(); 8088d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue One = DAG.getConstant(1, VT); 8098d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (Convert) { 8108d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SRW, 8118d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov MVT::i16, Flag); 8128d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (Shift) 8138d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // FIXME: somewhere this is turned into a SRL, lower it MSP specific? 8148d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One); 8158d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SR = DAG.getNode(ISD::AND, dl, MVT::i16, SR, One); 8168d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (Invert) 8178d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SR = DAG.getNode(ISD::XOR, dl, MVT::i16, SR, One); 8188d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov return SR; 8198d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } else { 8208d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue Zero = DAG.getConstant(0, VT); 8218d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Flag); 8228d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SmallVector<SDValue, 4> Ops; 8238d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Ops.push_back(One); 8248d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Ops.push_back(Zero); 8258d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Ops.push_back(TargetCC); 8268d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Ops.push_back(Flag); 8278d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size()); 8288d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 8298d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov} 8308d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov 8311bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton KorobeynikovSDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) { 8321bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue LHS = Op.getOperand(0); 8331bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue RHS = Op.getOperand(1); 8341bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue TrueV = Op.getOperand(2); 8351bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue FalseV = Op.getOperand(3); 8361bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); 8378b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 8381bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 8393926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov SDValue TargetCC; 8401bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 8418b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 842825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Flag); 8438b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov SmallVector<SDValue, 4> Ops; 8448b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov Ops.push_back(TrueV); 8458b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov Ops.push_back(FalseV); 8463926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov Ops.push_back(TargetCC); 8471bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov Ops.push_back(Flag); 8488b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 8491bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size()); 8508b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov} 8518b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 852b78e214274d397407b6167a293b7cd7c3b526ddeAnton KorobeynikovSDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op, 853b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov SelectionDAG &DAG) { 854b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov SDValue Val = Op.getOperand(0); 855e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Op.getValueType(); 856b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 857b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 858825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson assert(VT == MVT::i16 && "Only support i16 for now!"); 859b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 860b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT, 861b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val), 862b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov DAG.getValueType(Val.getValueType())); 863b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov} 864b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 86506ccca5f70ef5f9c3e4add60b6fc842916705029Anton KorobeynikovSDValue MSP430TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) { 86606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MachineFunction &MF = DAG.getMachineFunction(); 86706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>(); 86806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov int ReturnAddrIndex = FuncInfo->getRAIndex(); 86906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 87006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov if (ReturnAddrIndex == 0) { 87106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov // Set up a frame object for the return address. 87206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov uint64_t SlotSize = TD->getPointerSize(); 87306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(SlotSize, -SlotSize, 87406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov true, false); 87506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov FuncInfo->setRAIndex(ReturnAddrIndex); 87606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov } 87706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 87806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy()); 87906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov} 88006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 88106ccca5f70ef5f9c3e4add60b6fc842916705029Anton KorobeynikovSDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) { 88206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); 88306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 88406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 88506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov if (Depth > 0) { 88606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue FrameAddr = LowerFRAMEADDR(Op, DAG); 88706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue Offset = 88806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov DAG.getConstant(TD->getPointerSize(), MVT::i16); 88906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), 89006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov DAG.getNode(ISD::ADD, dl, getPointerTy(), 89106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov FrameAddr, Offset), 89206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov NULL, 0); 89306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov } 89406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 89506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov // Just load the return address. 89606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue RetAddrFI = getReturnAddressFrameIndex(DAG); 89706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), 89806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov RetAddrFI, NULL, 0); 89906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov} 90006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 90106ccca5f70ef5f9c3e4add60b6fc842916705029Anton KorobeynikovSDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) { 90206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 90306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MFI->setFrameAddressIsTaken(true); 90406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov EVT VT = Op.getValueType(); 90506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov DebugLoc dl = Op.getDebugLoc(); // FIXME probably not meaningful 90606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); 90706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, 90806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MSP430::FPW, VT); 90906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov while (Depth--) 91006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr, NULL, 0); 91106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return FrameAddr; 91206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov} 91306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 9146534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// getPostIndexedAddressParts - returns true by value, base pointer and 9156534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// offset pointer and addressing mode by reference if this node can be 9166534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// combined with a load / store to form a post-indexed load / store. 9176534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikovbool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op, 9186534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SDValue &Base, 9196534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SDValue &Offset, 9206534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov ISD::MemIndexedMode &AM, 9216534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SelectionDAG &DAG) const { 9226534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 9236534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov LoadSDNode *LD = cast<LoadSDNode>(N); 9246534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (LD->getExtensionType() != ISD::NON_EXTLOAD) 9256534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 9266534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 9276534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov EVT VT = LD->getMemoryVT(); 9286534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (VT != MVT::i8 && VT != MVT::i16) 9296534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 9306534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 9316534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (Op->getOpcode() != ISD::ADD) 9326534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 9336534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 9346534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) { 9356534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov uint64_t RHSC = RHS->getZExtValue(); 9366534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if ((VT == MVT::i16 && RHSC != 2) || 9376534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov (VT == MVT::i8 && RHSC != 1)) 9386534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 9396534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 9406534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov Base = Op->getOperand(0); 9416534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov Offset = DAG.getConstant(RHSC, VT); 9426534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov AM = ISD::POST_INC; 9436534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return true; 9446534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov } 9456534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 9466534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 9476534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov} 9486534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 9496534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 950fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikovconst char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const { 951fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov switch (Opcode) { 952fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov default: return NULL; 953fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov case MSP430ISD::RET_FLAG: return "MSP430ISD::RET_FLAG"; 9546bfcba7e137113e5f38cc4f937ad61cc7253ec74Anton Korobeynikov case MSP430ISD::RETI_FLAG: return "MSP430ISD::RETI_FLAG"; 955d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov case MSP430ISD::RRA: return "MSP430ISD::RRA"; 956e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case MSP430ISD::RLA: return "MSP430ISD::RLA"; 957e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case MSP430ISD::RRC: return "MSP430ISD::RRC"; 958b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov case MSP430ISD::CALL: return "MSP430ISD::CALL"; 9593513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov case MSP430ISD::Wrapper: return "MSP430ISD::Wrapper"; 9601bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case MSP430ISD::BR_CC: return "MSP430ISD::BR_CC"; 961ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case MSP430ISD::CMP: return "MSP430ISD::CMP"; 9621bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case MSP430ISD::SELECT_CC: return "MSP430ISD::SELECT_CC"; 9632625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430ISD::SHL: return "MSP430ISD::SHL"; 9642625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430ISD::SRA: return "MSP430ISD::SRA"; 965fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 966fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov} 9678b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 9688b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===// 9698b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov// Other Lowering Code 9708b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===// 9718b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 9728b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMachineBasicBlock* 9732625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMSP430TargetLowering::EmitShiftInstr(MachineInstr *MI, 9742625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineBasicBlock *BB, 9752625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const { 9762625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineFunction *F = BB->getParent(); 9772625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineRegisterInfo &RI = F->getRegInfo(); 9782625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov DebugLoc dl = MI->getDebugLoc(); 9792625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); 9802625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 9812625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned Opc; 9822625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov const TargetRegisterClass * RC; 9832625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov switch (MI->getOpcode()) { 9842625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov default: 9852625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov assert(0 && "Invalid shift opcode!"); 9862625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Shl8: 9872625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SHL8r1; 9882625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov RC = MSP430::GR8RegisterClass; 9892625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 9902625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Shl16: 9912625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SHL16r1; 9922625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov RC = MSP430::GR16RegisterClass; 9932625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 9942625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Sra8: 9952625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR8r1; 9962625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov RC = MSP430::GR8RegisterClass; 9972625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 9982625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Sra16: 9992625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR16r1; 10002625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov RC = MSP430::GR16RegisterClass; 10012625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 10022625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Srl8: 10032625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR8r1c; 10042625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov RC = MSP430::GR8RegisterClass; 10052625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 10062625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Srl16: 10072625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR16r1c; 10082625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov RC = MSP430::GR16RegisterClass; 10092625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 10102625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov } 10112625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10122625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov const BasicBlock *LLVM_BB = BB->getBasicBlock(); 10132625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineFunction::iterator I = BB; 10142625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov ++I; 10152625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10162625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Create loop block 10172625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB); 10182625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineBasicBlock *RemBB = F->CreateMachineBasicBlock(LLVM_BB); 10192625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10202625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov F->insert(I, LoopBB); 10212625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov F->insert(I, RemBB); 10222625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10232625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Update machine-CFG edges by transferring all successors of the current 10242625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // block to the block containing instructions after shift. 10252625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov RemBB->transferSuccessors(BB); 10262625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10272625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Inform sdisel of the edge changes. 10282625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), 10292625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov SE = BB->succ_end(); SI != SE; ++SI) 10302625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov EM->insert(std::make_pair(*SI, RemBB)); 10312625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10322625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Add adges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB 10332625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BB->addSuccessor(LoopBB); 10342625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BB->addSuccessor(RemBB); 10352625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov LoopBB->addSuccessor(RemBB); 10362625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov LoopBB->addSuccessor(LoopBB); 10372625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10382625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned ShiftAmtReg = RI.createVirtualRegister(MSP430::GR8RegisterClass); 10392625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned ShiftAmtReg2 = RI.createVirtualRegister(MSP430::GR8RegisterClass); 10402625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned ShiftReg = RI.createVirtualRegister(RC); 10412625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned ShiftReg2 = RI.createVirtualRegister(RC); 10422625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned ShiftAmtSrcReg = MI->getOperand(2).getReg(); 10432625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned SrcReg = MI->getOperand(1).getReg(); 10442625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned DstReg = MI->getOperand(0).getReg(); 10452625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10462625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // BB: 10472625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // cmp 0, N 10482625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // je RemBB 1049f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov BuildMI(BB, dl, TII.get(MSP430::CMP8ri)) 1050f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov .addReg(ShiftAmtSrcReg).addImm(0); 10512625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(BB, dl, TII.get(MSP430::JCC)) 10522625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addMBB(RemBB) 10532625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addImm(MSP430CC::COND_E); 10542625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10552625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // LoopBB: 10562625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB] 10572625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // ShiftAmt = phi [%N, BB], [%ShiftAmt2, LoopBB] 10582625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // ShiftReg2 = shift ShiftReg 10592625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // ShiftAmt2 = ShiftAmt - 1; 10602625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftReg) 10612625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(SrcReg).addMBB(BB) 10622625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftReg2).addMBB(LoopBB); 10632625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg) 10642625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftAmtSrcReg).addMBB(BB) 10652625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftAmtReg2).addMBB(LoopBB); 10662625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2) 10672625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftReg); 10682625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2) 10692625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftAmtReg).addImm(1); 10702625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::JCC)) 10712625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addMBB(LoopBB) 10722625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addImm(MSP430CC::COND_NE); 10732625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10742625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // RemBB: 10752625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB] 10762625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(RemBB, dl, TII.get(MSP430::PHI), DstReg) 10772625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(SrcReg).addMBB(BB) 10782625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftReg2).addMBB(LoopBB); 10792625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10805fcf52ccf34d6cb56e0bd6314aaa9a847f3a0939Anton Korobeynikov F->DeleteMachineInstr(MI); // The pseudo instruction is gone now. 10812625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return RemBB; 10822625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov} 10832625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10842625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMachineBasicBlock* 10858b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 1086fb2e752e4175920d0531f2afc93a23d0cdf4db14Evan Cheng MachineBasicBlock *BB, 1087fb2e752e4175920d0531f2afc93a23d0cdf4db14Evan Cheng DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const { 10882625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned Opc = MI->getOpcode(); 10892625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10902625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 || 10912625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc == MSP430::Sra8 || Opc == MSP430::Sra16 || 10922625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc == MSP430::Srl8 || Opc == MSP430::Srl16) 10932625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return EmitShiftInstr(MI, BB, EM); 10942625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10958b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); 10968b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov DebugLoc dl = MI->getDebugLoc(); 10972625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10982625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov assert((Opc == MSP430::Select16 || Opc == MSP430::Select8) && 10998b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov "Unexpected instr type to insert"); 11008b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 11018b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // To "insert" a SELECT instruction, we actually have to insert the diamond 11028b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // control-flow pattern. The incoming instruction knows the destination vreg 11038b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // to set, the condition code register to branch on, the true/false values to 11048b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // select between, and a branch opcode to use. 11058b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov const BasicBlock *LLVM_BB = BB->getBasicBlock(); 11068b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineFunction::iterator I = BB; 11078b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov ++I; 11088b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 11098b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // thisMBB: 11108b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // ... 11118b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // TrueVal = ... 11128b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // cmpTY ccX, r1, r2 11138b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // jCC copy1MBB 11148b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // fallthrough --> copy0MBB 11158b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *thisMBB = BB; 11168b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineFunction *F = BB->getParent(); 11178b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); 11188b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB); 11198b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BuildMI(BB, dl, TII.get(MSP430::JCC)) 11208b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addMBB(copy1MBB) 11218b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addImm(MI->getOperand(3).getImm()); 11228b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov F->insert(I, copy0MBB); 11238b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov F->insert(I, copy1MBB); 1124ce31910eae5bd4896fa6c27798e7b26885691d3bEvan Cheng // Inform sdisel of the edge changes. 1125ce31910eae5bd4896fa6c27798e7b26885691d3bEvan Cheng for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), 1126ce31910eae5bd4896fa6c27798e7b26885691d3bEvan Cheng SE = BB->succ_end(); SI != SE; ++SI) 1127ce31910eae5bd4896fa6c27798e7b26885691d3bEvan Cheng EM->insert(std::make_pair(*SI, copy1MBB)); 11288b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Update machine-CFG edges by transferring all successors of the current 11298b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // block to the new block which will contain the Phi node for the select. 11308b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov copy1MBB->transferSuccessors(BB); 11318b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Next, add the true and fallthrough blocks as its successors. 11328b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy0MBB); 11338b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy1MBB); 11348b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 11358b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // copy0MBB: 11368b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // %FalseValue = ... 11378b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // # fallthrough to copy1MBB 11388b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB = copy0MBB; 11398b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 11408b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Update machine-CFG edges 11418b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy1MBB); 11428b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 11438b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // copy1MBB: 11448b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] 11458b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // ... 11468b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB = copy1MBB; 11478b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BuildMI(BB, dl, TII.get(MSP430::PHI), 11488b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MI->getOperand(0).getReg()) 11498b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB) 11508b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB); 11518b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 11528b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov F->DeleteMachineInstr(MI); // The pseudo instruction is gone now. 11538b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov return BB; 11548b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov} 1155