MSP430ISelLowering.cpp revision a7542d5f870c5d98960d1676e23ac1d1d975d7e5
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" 32f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/SelectionDAGISel.h" 33362dd0bef5437f85586c046bc53287b6fbe9c099Anton Korobeynikov#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 34f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/ValueTypes.h" 35b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov#include "llvm/Support/CommandLine.h" 36f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/Support/Debug.h" 37804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin#include "llvm/Support/ErrorHandling.h" 384437ae213d5435390f0750213b53ec807c047f22Chris Lattner#include "llvm/Support/raw_ostream.h" 39f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovusing namespace llvm; 40f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 41b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikovtypedef enum { 42b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov NoHWMult, 43b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov HWMultIntr, 44b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov HWMultNoIntr 45b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov} HWMultUseMode; 46b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov 47b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikovstatic cl::opt<HWMultUseMode> 48b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton KorobeynikovHWMultMode("msp430-hwmult-mode", 49b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov cl::desc("Hardware multiplier use mode"), 50b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov cl::init(HWMultNoIntr), 51b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov cl::values( 52b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov clEnumValN(NoHWMult, "no", 53b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov "Do not use hardware multiplier"), 54b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov clEnumValN(HWMultIntr, "interrupts", 55b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov "Assume hardware multiplier can be used inside interrupts"), 56b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov clEnumValN(HWMultNoIntr, "use", 57b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov "Assume hardware multiplier cannot be used inside interrupts"), 58b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov clEnumValEnd)); 59b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov 60f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovMSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) : 61f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner TargetLowering(tm, new TargetLoweringObjectFileELF()), 62a7542d5f870c5d98960d1676e23ac1d1d975d7e5Benjamin Kramer Subtarget(*tm.getSubtargetImpl()) { 63f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 6406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov TD = getTargetData(); 6506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 66f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov // Set up the register classes. 67420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper addRegisterClass(MVT::i8, &MSP430::GR8RegClass); 68420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper addRegisterClass(MVT::i16, &MSP430::GR16RegClass); 69f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 70f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov // Compute derived properties from the register classes 71f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov computeRegisterProperties(); 72fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 731476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov // Provide all sorts of operation actions 741476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov 751476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov // Division is expensive 761476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov setIntDivIsCheap(false); 771476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov 78c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov setStackPointerRegisterToSaveRestore(MSP430::SPW); 79c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov setBooleanContents(ZeroOrOneBooleanContent); 8028b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct? 81c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov 8206ac0820a6cefa6896000054d8e4906326c0cce6Anton Korobeynikov // We have post-incremented loads / stores. 836534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setIndexedLoadAction(ISD::POST_INC, MVT::i8, Legal); 846534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setIndexedLoadAction(ISD::POST_INC, MVT::i16, Legal); 856534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 866534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); 876534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); 886534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); 896534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Expand); 90825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Expand); 9136b6e533c1aac85452438161f7034a9f54bd1830Anton Korobeynikov 9254f30d3fc94e055f13e6744378323d05c5c050baAnton Korobeynikov // We don't have any truncstores 93825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setTruncStoreAction(MVT::i16, MVT::i8, Expand); 94825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 95825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRA, MVT::i8, Custom); 96825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SHL, MVT::i8, Custom); 97825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRL, MVT::i8, Custom); 98825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRA, MVT::i16, Custom); 99825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SHL, MVT::i16, Custom); 100825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRL, MVT::i16, Custom); 101825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ROTL, MVT::i8, Expand); 102825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ROTR, MVT::i8, Expand); 103825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ROTL, MVT::i16, Expand); 104825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ROTR, MVT::i16, Expand); 105825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::GlobalAddress, MVT::i16, Custom); 106825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ExternalSymbol, MVT::i16, Custom); 10769d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov setOperationAction(ISD::BlockAddress, MVT::i16, Custom); 108825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BR_JT, MVT::Other, Expand); 109825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BR_CC, MVT::i8, Custom); 110825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BR_CC, MVT::i16, Custom); 111825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BRCOND, MVT::Other, Expand); 1128d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov setOperationAction(ISD::SETCC, MVT::i8, Custom); 1138d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov setOperationAction(ISD::SETCC, MVT::i16, Custom); 114825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT, MVT::i8, Expand); 115825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT, MVT::i16, Expand); 116825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT_CC, MVT::i8, Custom); 117825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT_CC, MVT::i16, Custom); 118825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SIGN_EXTEND, MVT::i16, Custom); 119379a087cc7175532ff0c24c60069da5eec596879Anton Korobeynikov setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i8, Expand); 120379a087cc7175532ff0c24c60069da5eec596879Anton Korobeynikov setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i16, Expand); 121825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 122825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTTZ, MVT::i8, Expand); 123825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTTZ, MVT::i16, Expand); 12463974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i8, Expand); 12563974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i16, Expand); 126825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTLZ, MVT::i8, Expand); 127825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTLZ, MVT::i16, Expand); 12863974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i8, Expand); 12963974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i16, Expand); 130825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTPOP, MVT::i8, Expand); 131825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTPOP, MVT::i16, Expand); 132825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 133825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SHL_PARTS, MVT::i8, Expand); 134825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SHL_PARTS, MVT::i16, Expand); 135825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRL_PARTS, MVT::i8, Expand); 136825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRL_PARTS, MVT::i16, Expand); 137825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRA_PARTS, MVT::i8, Expand); 138825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRA_PARTS, MVT::i16, Expand); 139825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 140825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); 141e4ce880dfa340bf45ddce10bb1dbe856553677b6Eli Friedman 1428725bd22bf91c29e2351a127295c19fea996e2c7Anton Korobeynikov // FIXME: Implement efficiently multiplication by a constant 1438983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::MUL, MVT::i8, Expand); 1448983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::MULHS, MVT::i8, Expand); 1458983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::MULHU, MVT::i8, Expand); 1468983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::SMUL_LOHI, MVT::i8, Expand); 1478983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::UMUL_LOHI, MVT::i8, Expand); 148825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::MUL, MVT::i16, Expand); 149825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::MULHS, MVT::i16, Expand); 150825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::MULHU, MVT::i16, Expand); 151825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SMUL_LOHI, MVT::i16, Expand); 152825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UMUL_LOHI, MVT::i16, Expand); 153825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 1548983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::UDIV, MVT::i8, Expand); 1558983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::UDIVREM, MVT::i8, Expand); 1568983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::UREM, MVT::i8, Expand); 1578983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::SDIV, MVT::i8, Expand); 1588983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::SDIVREM, MVT::i8, Expand); 1598983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::SREM, MVT::i8, Expand); 160825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UDIV, MVT::i16, Expand); 161825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UDIVREM, MVT::i16, Expand); 162825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UREM, MVT::i16, Expand); 163825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SDIV, MVT::i16, Expand); 164825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SDIVREM, MVT::i16, Expand); 165825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SREM, MVT::i16, Expand); 166b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov 167b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov // Libcalls names. 168b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov if (HWMultMode == HWMultIntr) { 169b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I8, "__mulqi3hw"); 170b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I16, "__mulhi3hw"); 171b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov } else if (HWMultMode == HWMultNoIntr) { 172b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I8, "__mulqi3hw_noint"); 173b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I16, "__mulhi3hw_noint"); 174b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov } 175fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman 176fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman setMinFunctionAlignment(1); 177fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman setPrefFunctionAlignment(2); 178f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 179f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 180d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerOperation(SDValue Op, 181d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 182f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov switch (Op.getOpcode()) { 183ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov case ISD::SHL: // FALLTHROUGH 184e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case ISD::SRL: 1854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case ISD::SRA: return LowerShifts(Op, DAG); 1863513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); 18769d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); 1885d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG); 1898d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov case ISD::SETCC: return LowerSETCC(Op, DAG); 1901bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case ISD::BR_CC: return LowerBR_CC(Op, DAG); 1911bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); 192b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov case ISD::SIGN_EXTEND: return LowerSIGN_EXTEND(Op, DAG); 19306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); 19406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); 195f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov default: 196c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("unimplemented operand"); 197f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov } 198f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 199f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 200c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===// 201cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov// MSP430 Inline Assembly Support 202cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===// 203cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 204cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// getConstraintType - Given a constraint letter, return the type of 205cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// constraint it is for this target. 206cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovTargetLowering::ConstraintType 207cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering::getConstraintType(const std::string &Constraint) const { 208cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov if (Constraint.size() == 1) { 209cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov switch (Constraint[0]) { 210cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov case 'r': 211cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return C_RegisterClass; 212cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov default: 213cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov break; 214cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 215cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 216cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return TargetLowering::getConstraintType(Constraint); 217cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov} 218cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 219cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikovstd::pair<unsigned, const TargetRegisterClass*> 220cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering:: 221cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovgetRegForInlineAsmConstraint(const std::string &Constraint, 222cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov EVT VT) const { 223cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov if (Constraint.size() == 1) { 224cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov // GCC Constraint Letters 225cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov switch (Constraint[0]) { 226cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov default: break; 227cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov case 'r': // GENERAL_REGS 228cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov if (VT == MVT::i8) 229420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper return std::make_pair(0U, &MSP430::GR8RegClass); 230cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 231420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper return std::make_pair(0U, &MSP430::GR16RegClass); 232cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 233cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 234cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 235cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); 236cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov} 237cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 238cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===// 239c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// Calling Convention Implementation 240c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===// 241c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 242f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430GenCallingConv.inc" 243c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 24498ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 24598ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerFormalArguments(SDValue Chain, 24665c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, 24798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isVarArg, 24898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> 24998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Ins, 25098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DebugLoc dl, 25198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SelectionDAG &DAG, 252d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) 253d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman const { 25498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 25598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman switch (CallConv) { 256c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov default: 257c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Unsupported calling convention"); 258c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov case CallingConv::C: 259c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov case CallingConv::Fast: 26098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals); 261e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov case CallingConv::MSP430_INTR: 2624d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie if (Ins.empty()) 2634d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie return Chain; 26475361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("ISRs cannot have arguments"); 265c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 266c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov} 267c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 26898ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 269d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin HolewinskiMSP430TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, 270d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) const { 271d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SelectionDAG &DAG = CLI.DAG; 272d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski DebugLoc &dl = CLI.DL; 273d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs; 274d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SmallVector<SDValue, 32> &OutVals = CLI.OutVals; 275d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SmallVector<ISD::InputArg, 32> &Ins = CLI.Ins; 276d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SDValue Chain = CLI.Chain; 277d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SDValue Callee = CLI.Callee; 278d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski bool &isTailCall = CLI.IsTailCall; 279d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski CallingConv::ID CallConv = CLI.CallConv; 280d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski bool isVarArg = CLI.IsVarArg; 281d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski 2820c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng // MSP430 target does not yet support tail call optimization. 2830c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng isTailCall = false; 28498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 28598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman switch (CallConv) { 2864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov default: 287c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Unsupported calling convention"); 2884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CallingConv::Fast: 2894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CallingConv::C: 29098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall, 291c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman Outs, OutVals, Ins, dl, DAG, InVals); 292e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov case CallingConv::MSP430_INTR: 29375361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("ISRs cannot be called directly"); 2944428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 2954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 2964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 297c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// LowerCCCArguments - transform physical registers into virtual registers and 298c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// generate load operations for arguments places on the stack. 299c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// FIXME: struct return stuff 300c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// FIXME: varargs 30198ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 30298ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCArguments(SDValue Chain, 30365c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, 30498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isVarArg, 30598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> 30698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Ins, 30798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DebugLoc dl, 30898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SelectionDAG &DAG, 309d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) 310d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman const { 311c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineFunction &MF = DAG.getMachineFunction(); 312c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 313c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineRegisterInfo &RegInfo = MF.getRegInfo(); 314c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 315c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Assign locations to all of the incoming arguments. 316c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov SmallVector<CCValAssign, 16> ArgLocs; 317471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 318471e4224809f51652c71f319532697a879a75a0dEric Christopher getTargetMachine(), ArgLocs, *DAG.getContext()); 31998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeFormalArguments(Ins, CC_MSP430); 320c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 321c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov assert(!isVarArg && "Varargs not supported yet"); 322c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 323c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 324c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov CCValAssign &VA = ArgLocs[i]; 325c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.isRegLoc()) { 326c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Arguments passed in registers 327e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT RegVT = VA.getLocVT(); 328825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson switch (RegVT.getSimpleVT().SimpleTy) { 32995771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson default: 330804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin { 331dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#ifndef NDEBUG 3324437ae213d5435390f0750213b53ec807c047f22Chris Lattner errs() << "LowerFormalArguments Unhandled argument type: " 333825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson << RegVT.getSimpleVT().SimpleTy << "\n"; 334dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#endif 335c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable(0); 336804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin } 337825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i16: 338420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper unsigned VReg = RegInfo.createVirtualRegister(&MSP430::GR16RegClass); 339c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov RegInfo.addLiveIn(VA.getLocReg(), VReg); 34098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, RegVT); 341c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 342c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // If this is an 8-bit value, it is really passed promoted to 16 343c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // bits. Insert an assert[sz]ext to capture this, then truncate to the 344c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // right size. 345c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.getLocInfo() == CCValAssign::SExt) 346c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue, 347c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov DAG.getValueType(VA.getValVT())); 348c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov else if (VA.getLocInfo() == CCValAssign::ZExt) 349c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue, 350c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov DAG.getValueType(VA.getValVT())); 351c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 352c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.getLocInfo() != CCValAssign::Full) 353c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); 354c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 35598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman InVals.push_back(ArgValue); 356c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 357c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } else { 358c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Sanity check 359c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov assert(VA.isMemLoc()); 360c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Load the argument to a virtual register 361c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov unsigned ObjSize = VA.getLocVT().getSizeInBits()/8; 362c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (ObjSize > 2) { 3634437ae213d5435390f0750213b53ec807c047f22Chris Lattner errs() << "LowerFormalArguments Unhandled argument type: " 3641440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands << EVT(VA.getLocVT()).getEVTString() 365c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov << "\n"; 366c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 367c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Create the frame index object for this incoming parameter... 368ed2ae136d29dd36122d2476801e7d7a86e8301e3Evan Cheng int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true); 369c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 370c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Create the SelectionDAG nodes corresponding to a load 371c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov //from this parameter 372825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue FIN = DAG.getFrameIndex(FI, MVT::i16); 37398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, 374d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner MachinePointerInfo::getFixedStack(FI), 375d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper false, false, false, 0)); 376c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 377c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 378c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 37998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return Chain; 380c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov} 381fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 38298ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 38398ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerReturn(SDValue Chain, 38465c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 38598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::OutputArg> &Outs, 386c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman const SmallVectorImpl<SDValue> &OutVals, 387d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman DebugLoc dl, SelectionDAG &DAG) const { 38898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 389fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // CCValAssign - represent the assignment of the return value to a location 390fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov SmallVector<CCValAssign, 16> RVLocs; 391fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 392e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov // ISRs cannot return any value. 3934d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie if (CallConv == CallingConv::MSP430_INTR && !Outs.empty()) 39475361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("ISRs cannot return any value"); 395e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov 396fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // CCState - Info about the registers and stack slot. 397471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 398471e4224809f51652c71f319532697a879a75a0dEric Christopher getTargetMachine(), RVLocs, *DAG.getContext()); 399fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 40098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman // Analize return values. 40198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeReturn(Outs, RetCC_MSP430); 402fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 403fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // If this is the first return lowered for this function, add the regs to the 404fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // liveout set for the function. 405fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (DAG.getMachineFunction().getRegInfo().liveout_empty()) { 406fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov for (unsigned i = 0; i != RVLocs.size(); ++i) 407fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (RVLocs[i].isRegLoc()) 408fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); 409fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 410fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 411fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov SDValue Flag; 412fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 413fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // Copy the result values into the output registers. 414fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov for (unsigned i = 0; i != RVLocs.size(); ++i) { 415fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov CCValAssign &VA = RVLocs[i]; 416fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov assert(VA.isRegLoc() && "Can only return in registers!"); 417fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 418fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), 419c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman OutVals[i], Flag); 420fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 421dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov // Guarantee that all emitted copies are stuck together, 422dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov // avoiding something bad. 423fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov Flag = Chain.getValue(1); 424fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 425fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 426e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov unsigned Opc = (CallConv == CallingConv::MSP430_INTR ? 427e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG); 428e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov 429fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (Flag.getNode()) 430e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov return DAG.getNode(Opc, dl, MVT::Other, Chain, Flag); 431fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 432fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // Return Void 433e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov return DAG.getNode(Opc, dl, MVT::Other, Chain); 434fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov} 435fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 4364428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// LowerCCCCallTo - functions arguments are copied from virtual regs to 4374428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted. 4384428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// TODO: sret. 43998ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 44098ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, 44165c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 44298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isTailCall, 44398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::OutputArg> 44498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Outs, 445c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman const SmallVectorImpl<SDValue> &OutVals, 44698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> &Ins, 44798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DebugLoc dl, SelectionDAG &DAG, 448d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) const { 4494428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Analyze operands of the call, assigning locations to each operand. 4504428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<CCValAssign, 16> ArgLocs; 451471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 452471e4224809f51652c71f319532697a879a75a0dEric Christopher getTargetMachine(), ArgLocs, *DAG.getContext()); 4534428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 45498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeCallOperands(Outs, CC_MSP430); 4554428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4564428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Get a count of how many bytes are to be pushed on the stack. 4574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov unsigned NumBytes = CCInfo.getNextStackOffset(); 4584428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4594428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCALLSEQ_START(Chain ,DAG.getConstant(NumBytes, 4604428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov getPointerTy(), true)); 4614428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4624428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass; 4634428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<SDValue, 12> MemOpChains; 4644428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue StackPtr; 4654428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4664428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Walk the register/memloc assignments, inserting copies/loads. 4674428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 4684428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov CCValAssign &VA = ArgLocs[i]; 4694428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 470c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman SDValue Arg = OutVals[i]; 4714428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4724428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Promote the value if needed. 4734428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov switch (VA.getLocInfo()) { 474c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Unknown loc info!"); 4754428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::Full: break; 4764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::SExt: 4774428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); 4784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 4794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::ZExt: 4804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg); 4814428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 4824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::AExt: 4834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); 4844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 4854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 4864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4874428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Arguments that can be passed on register must be kept at RegsToPass 4884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // vector 4894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (VA.isRegLoc()) { 4904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 4914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } else { 4924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov assert(VA.isMemLoc()); 4934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4944428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (StackPtr.getNode() == 0) 4954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SPW, getPointerTy()); 4964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4974428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), 4984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov StackPtr, 4994428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG.getIntPtrConstant(VA.getLocMemOffset())); 5004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5014428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5024428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, 5036229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner MachinePointerInfo(),false, false, 0)); 5044428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 5054428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 5064428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5074428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Transform all store nodes into one single node because all store nodes are 5084428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // independent of each other. 5094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (!MemOpChains.empty()) 510825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 5114428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov &MemOpChains[0], MemOpChains.size()); 5124428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5134428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Build a sequence of copy-to-reg nodes chained together with token chain and 5144428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // flag operands which copy the outgoing args into registers. The InFlag in 5157a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // necessary since all emitted instructions must be stuck together. 5164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue InFlag; 5174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 5184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, 5194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RegsToPass[i].second, InFlag); 5204428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(1); 5214428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 5224428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5234428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // If the callee is a GlobalAddress node (quite common, every direct call is) 5244428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 5254428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Likewise ExternalSymbol -> TargetExternalSymbol. 5264428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 5270d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i16); 5284428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) 529825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i16); 5304428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5314428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Returns a chain & a flag for retval copy to use. 532f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 5334428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<SDValue, 8> Ops; 5344428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(Chain); 5354428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(Callee); 5364428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5374428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Add argument registers to the end of the list so that they are 5384428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // known live into the call. 5394428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 5404428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(DAG.getRegister(RegsToPass[i].first, 5414428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RegsToPass[i].second.getValueType())); 5424428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5434428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (InFlag.getNode()) 5444428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(InFlag); 5454428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5464428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getNode(MSP430ISD::CALL, dl, NodeTys, &Ops[0], Ops.size()); 5474428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(1); 5484428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5494428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Create the CALLSEQ_END node. 5504428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCALLSEQ_END(Chain, 5514428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG.getConstant(NumBytes, getPointerTy(), true), 5524428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG.getConstant(0, getPointerTy(), true), 5534428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag); 5544428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(1); 5554428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5564428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Handle result values, copying them out of physregs into vregs that we 5574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // return. 55898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl, 55998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DAG, InVals); 5604428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 5614428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 56298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// LowerCallResult - Lower the result values of a call into the 56398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// appropriate copies out of appropriate physical registers. 56498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// 56598ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 5664428885c5acfffbbdd03ad2aab23960531c47753Anton KorobeynikovMSP430TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, 56765c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 56898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> &Ins, 56998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DebugLoc dl, SelectionDAG &DAG, 570d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) const { 5714428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5724428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Assign locations to each value returned by this call. 5734428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<CCValAssign, 16> RVLocs; 574471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 575471e4224809f51652c71f319532697a879a75a0dEric Christopher getTargetMachine(), RVLocs, *DAG.getContext()); 5764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 57798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeCallResult(Ins, RetCC_MSP430); 5784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Copy all of the result registers out of their specified physreg. 5804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0; i != RVLocs.size(); ++i) { 5814428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(), 5824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RVLocs[i].getValVT(), InFlag).getValue(1); 5834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(2); 58498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman InVals.push_back(Chain.getValue(0)); 5854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 5864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 58798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return Chain; 5884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 5894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 590d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton KorobeynikovSDValue MSP430TargetLowering::LowerShifts(SDValue Op, 591d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 592ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov unsigned Opc = Op.getOpcode(); 593d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov SDNode* N = Op.getNode(); 594e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Op.getValueType(); 595d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov DebugLoc dl = N->getDebugLoc(); 596d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 5972625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Expand non-constant shifts to loops: 598d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov if (!isa<ConstantSDNode>(N->getOperand(1))) 5992625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov switch (Opc) { 600bc2198133a1836598b54b943420748e75d5dea94Craig Topper default: llvm_unreachable("Invalid shift opcode!"); 6012625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case ISD::SHL: 6022625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return DAG.getNode(MSP430ISD::SHL, dl, 6032625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov VT, N->getOperand(0), N->getOperand(1)); 6042625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case ISD::SRA: 6052625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return DAG.getNode(MSP430ISD::SRA, dl, 6062625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov VT, N->getOperand(0), N->getOperand(1)); 6072625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case ISD::SRL: 6082625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return DAG.getNode(MSP430ISD::SRL, dl, 6092625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov VT, N->getOperand(0), N->getOperand(1)); 6102625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov } 611d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 612d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue(); 613d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 614d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // Expand the stuff into sequence of shifts. 615d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // FIXME: for some shift amounts this might be done better! 616d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N 617d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov SDValue Victim = N->getOperand(0); 618e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov 619e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov if (Opc == ISD::SRL && ShiftAmount) { 620e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov // Emit a special goodness here: 621e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov // srl A, 1 => clrc; rrc A 622bf8ef3f29de28529b5d65970af9015c41f7c809bAnton Korobeynikov Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim); 623e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov ShiftAmount -= 1; 624e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov } 625e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov 626d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov while (ShiftAmount--) 627aceb620de855485a4fb2eed343d880d76f6c701cAnton Korobeynikov Victim = DAG.getNode((Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA), 628ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov dl, VT, Victim); 629d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 630d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov return Victim; 631d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov} 632d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 633d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerGlobalAddress(SDValue Op, 634d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 6353513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); 6363513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset(); 6373513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov 6383513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov // Create the TargetGlobalAddress node, folding in the constant offset. 6390d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel SDValue Result = DAG.getTargetGlobalAddress(GV, Op.getDebugLoc(), 6400d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel getPointerTy(), Offset); 6413513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov return DAG.getNode(MSP430ISD::Wrapper, Op.getDebugLoc(), 6423513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov getPointerTy(), Result); 6433513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov} 6443513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov 6455d59f68ade7573175f1ace09061a94286e59076bAnton KorobeynikovSDValue MSP430TargetLowering::LowerExternalSymbol(SDValue Op, 646d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 6475d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 6485d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol(); 6495d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov SDValue Result = DAG.getTargetExternalSymbol(Sym, getPointerTy()); 6505d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov 65190f20044ade3712c8b0c3f4ebe47d57ad15ae6ceChad Rosier return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result); 6525d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov} 6535d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov 65469d5b48bc31b7a443355cdf1506005804b4f63e6Anton KorobeynikovSDValue MSP430TargetLowering::LowerBlockAddress(SDValue Op, 65569d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov SelectionDAG &DAG) const { 65669d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 65769d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress(); 65869d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov SDValue Result = DAG.getBlockAddress(BA, getPointerTy(), /*isTarget=*/true); 65969d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov 66090f20044ade3712c8b0c3f4ebe47d57ad15ae6ceChad Rosier return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result); 66169d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov} 66269d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov 6633926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikovstatic SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC, 6641bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC, 6651bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov DebugLoc dl, SelectionDAG &DAG) { 666ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov // FIXME: Handle bittests someday 667ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet"); 668ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 669ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov // FIXME: Handle jump negative someday 6703926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov MSP430CC::CondCodes TCC = MSP430CC::COND_INVALID; 671ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov switch (CC) { 672c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Invalid integer condition!"); 673ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETEQ: 6743926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_E; // aka COND_Z 675f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov // Minor optimization: if LHS is a constant, swap operands, then the 6761722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov // constant can be folded into comparison. 677f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov if (LHS.getOpcode() == ISD::Constant) 6781722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov std::swap(LHS, RHS); 679ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 680ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETNE: 6813926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_NE; // aka COND_NZ 682f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov // Minor optimization: if LHS is a constant, swap operands, then the 6831722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov // constant can be folded into comparison. 684f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov if (LHS.getOpcode() == ISD::Constant) 6851722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov std::swap(LHS, RHS); 686ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 687ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETULE: 688ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 689ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETUGE: 6900c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // Turn lhs u>= rhs with lhs constant into rhs u< lhs+1, this allows us to 6910c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // fold constant into instruction. 6920c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 6930c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov LHS = RHS; 6940c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 6950c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_LO; 6960c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov break; 6970c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov } 6983926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_HS; // aka COND_C 699ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 700ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETUGT: 701ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 702ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETULT: 7030c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // Turn lhs u< rhs with lhs constant into rhs u>= lhs+1, this allows us to 7040c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // fold constant into instruction. 7050c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 7060c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov LHS = RHS; 7070c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 7080c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_HS; 7090c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov break; 7100c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov } 7113926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_LO; // aka COND_NC 712ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 713ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETLE: 714ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 715ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETGE: 7160c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // Turn lhs >= rhs with lhs constant into rhs < lhs+1, this allows us to 7170c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // fold constant into instruction. 7180c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 7190c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov LHS = RHS; 7200c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 7210c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_L; 7220c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov break; 7230c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov } 7243926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_GE; 725ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 726ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETGT: 727ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 728ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETLT: 7290c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to 7300c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // fold constant into instruction. 7310c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 7320c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov LHS = RHS; 7330c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 7340c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_GE; 7350c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov break; 7360c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov } 7373926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_L; 738ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 739ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov } 740ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 7413926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TargetCC = DAG.getConstant(TCC, MVT::i8); 742f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner return DAG.getNode(MSP430ISD::CMP, dl, MVT::Glue, LHS, RHS); 743ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov} 744ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 7451bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 746d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const { 747ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov SDValue Chain = Op.getOperand(0); 7481bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); 7491bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue LHS = Op.getOperand(2); 7501bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue RHS = Op.getOperand(3); 7511bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Dest = Op.getOperand(4); 7521bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 7531bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 7543926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov SDValue TargetCC; 7551bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 7561bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 7571bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(), 7583926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov Chain, Dest, TargetCC, Flag); 759ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov} 760ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 761d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const { 7628d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue LHS = Op.getOperand(0); 7638d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue RHS = Op.getOperand(1); 7648d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 7658d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov 7668d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // If we are doing an AND and testing against zero, then the CMP 7678d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // will not be generated. The AND (or BIT) will generate the condition codes, 7688d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // but they are different from CMP. 769cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov // FIXME: since we're doing a post-processing, use a pseudoinstr here, so 770cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov // lowering & isel wouldn't diverge. 7718d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov bool andCC = false; 7728d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) { 7738d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (RHSC->isNullValue() && LHS.hasOneUse() && 7748d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov (LHS.getOpcode() == ISD::AND || 7758d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov (LHS.getOpcode() == ISD::TRUNCATE && 7768d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov LHS.getOperand(0).getOpcode() == ISD::AND))) { 7778d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov andCC = true; 7788d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 7798d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 7808d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get(); 7818d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue TargetCC; 7828d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 7838d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov 7848d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Get the condition codes directly from the status register, if its easy. 7858d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Otherwise a branch will be generated. Note that the AND and BIT 7868d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // instructions generate different flags than CMP, the carry bit can be used 7878d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // for NE/EQ. 7888d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov bool Invert = false; 7898d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov bool Shift = false; 7908d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov bool Convert = true; 7918d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov switch (cast<ConstantSDNode>(TargetCC)->getZExtValue()) { 7928d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov default: 7938d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Convert = false; 7948d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 7958d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov case MSP430CC::COND_HS: 7968d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Res = SRW & 1, no processing is required 7978d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 798cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov case MSP430CC::COND_LO: 7998d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Res = ~(SRW & 1) 8008d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Invert = true; 8018d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 802cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov case MSP430CC::COND_NE: 8038d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (andCC) { 8048d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // C = ~Z, thus Res = SRW & 1, no processing is required 8058d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } else { 806455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov // Res = ~((SRW >> 1) & 1) 8078d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Shift = true; 808455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov Invert = true; 8098d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 8108d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 811cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov case MSP430CC::COND_E: 812455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov Shift = true; 813455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov // C = ~Z for AND instruction, thus we can put Res = ~(SRW & 1), however, 814455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov // Res = (SRW >> 1) & 1 is 1 word shorter. 8158d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 8168d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 8178d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov EVT VT = Op.getValueType(); 8188d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue One = DAG.getConstant(1, VT); 8198d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (Convert) { 8208d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SRW, 821cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov MVT::i16, Flag); 8228d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (Shift) 8238d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // FIXME: somewhere this is turned into a SRL, lower it MSP specific? 8248d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One); 8258d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SR = DAG.getNode(ISD::AND, dl, MVT::i16, SR, One); 8268d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (Invert) 8278d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SR = DAG.getNode(ISD::XOR, dl, MVT::i16, SR, One); 8288d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov return SR; 8298d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } else { 8308d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue Zero = DAG.getConstant(0, VT); 831f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue); 8328d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SmallVector<SDValue, 4> Ops; 8338d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Ops.push_back(One); 8348d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Ops.push_back(Zero); 8358d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Ops.push_back(TargetCC); 8368d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Ops.push_back(Flag); 8378d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size()); 8388d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 8398d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov} 8408d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov 841d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op, 842d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 8431bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue LHS = Op.getOperand(0); 8441bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue RHS = Op.getOperand(1); 8451bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue TrueV = Op.getOperand(2); 8461bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue FalseV = Op.getOperand(3); 8471bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); 8488b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 8491bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 8503926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov SDValue TargetCC; 8511bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 8528b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 853f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue); 8548b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov SmallVector<SDValue, 4> Ops; 8558b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov Ops.push_back(TrueV); 8568b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov Ops.push_back(FalseV); 8573926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov Ops.push_back(TargetCC); 8581bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov Ops.push_back(Flag); 8598b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 8601bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size()); 8618b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov} 8628b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 863b78e214274d397407b6167a293b7cd7c3b526ddeAnton KorobeynikovSDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op, 864d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 865b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov SDValue Val = Op.getOperand(0); 866e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Op.getValueType(); 867b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 868b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 869825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson assert(VT == MVT::i16 && "Only support i16 for now!"); 870b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 871b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT, 872b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val), 873b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov DAG.getValueType(Val.getValueType())); 874b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov} 875b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 876d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue 877d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanMSP430TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) const { 87806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MachineFunction &MF = DAG.getMachineFunction(); 87906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>(); 88006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov int ReturnAddrIndex = FuncInfo->getRAIndex(); 88106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 88206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov if (ReturnAddrIndex == 0) { 88306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov // Set up a frame object for the return address. 88406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov uint64_t SlotSize = TD->getPointerSize(); 88506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(SlotSize, -SlotSize, 886ed2ae136d29dd36122d2476801e7d7a86e8301e3Evan Cheng true); 88706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov FuncInfo->setRAIndex(ReturnAddrIndex); 88806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov } 88906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 89006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy()); 89106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov} 89206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 893d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op, 894d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 8952457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 8962457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng MFI->setReturnAddressIsTaken(true); 8972457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng 89806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); 89906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 90006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 90106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov if (Depth > 0) { 90206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue FrameAddr = LowerFRAMEADDR(Op, DAG); 90306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue Offset = 90406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov DAG.getConstant(TD->getPointerSize(), MVT::i16); 90506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), 90606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov DAG.getNode(ISD::ADD, dl, getPointerTy(), 90706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov FrameAddr, Offset), 908d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper MachinePointerInfo(), false, false, false, 0); 90906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov } 91006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 91106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov // Just load the return address. 91206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue RetAddrFI = getReturnAddressFrameIndex(DAG); 91306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), 914d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper RetAddrFI, MachinePointerInfo(), false, false, false, 0); 91506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov} 91606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 917d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op, 918d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 91906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 92006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MFI->setFrameAddressIsTaken(true); 9212457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng 92206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov EVT VT = Op.getValueType(); 92306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov DebugLoc dl = Op.getDebugLoc(); // FIXME probably not meaningful 92406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); 92506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, 92606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MSP430::FPW, VT); 92706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov while (Depth--) 928d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr, 929d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner MachinePointerInfo(), 930d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper false, false, false, 0); 93106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return FrameAddr; 93206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov} 93306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 9346534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// getPostIndexedAddressParts - returns true by value, base pointer and 9356534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// offset pointer and addressing mode by reference if this node can be 9366534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// combined with a load / store to form a post-indexed load / store. 9376534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikovbool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op, 9386534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SDValue &Base, 9396534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SDValue &Offset, 9406534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov ISD::MemIndexedMode &AM, 9416534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SelectionDAG &DAG) const { 9426534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 9436534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov LoadSDNode *LD = cast<LoadSDNode>(N); 9446534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (LD->getExtensionType() != ISD::NON_EXTLOAD) 9456534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 9466534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 9476534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov EVT VT = LD->getMemoryVT(); 9486534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (VT != MVT::i8 && VT != MVT::i16) 9496534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 9506534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 9516534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (Op->getOpcode() != ISD::ADD) 9526534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 9536534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 9546534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) { 9556534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov uint64_t RHSC = RHS->getZExtValue(); 9566534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if ((VT == MVT::i16 && RHSC != 2) || 9576534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov (VT == MVT::i8 && RHSC != 1)) 9586534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 9596534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 9606534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov Base = Op->getOperand(0); 9616534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov Offset = DAG.getConstant(RHSC, VT); 9626534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov AM = ISD::POST_INC; 9636534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return true; 9646534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov } 9656534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 9666534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 9676534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov} 9686534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 9696534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 970fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikovconst char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const { 971fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov switch (Opcode) { 972fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov default: return NULL; 973fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov case MSP430ISD::RET_FLAG: return "MSP430ISD::RET_FLAG"; 9746bfcba7e137113e5f38cc4f937ad61cc7253ec74Anton Korobeynikov case MSP430ISD::RETI_FLAG: return "MSP430ISD::RETI_FLAG"; 975d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov case MSP430ISD::RRA: return "MSP430ISD::RRA"; 976e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case MSP430ISD::RLA: return "MSP430ISD::RLA"; 977e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case MSP430ISD::RRC: return "MSP430ISD::RRC"; 978b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov case MSP430ISD::CALL: return "MSP430ISD::CALL"; 9793513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov case MSP430ISD::Wrapper: return "MSP430ISD::Wrapper"; 9801bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case MSP430ISD::BR_CC: return "MSP430ISD::BR_CC"; 981ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case MSP430ISD::CMP: return "MSP430ISD::CMP"; 9821bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case MSP430ISD::SELECT_CC: return "MSP430ISD::SELECT_CC"; 9832625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430ISD::SHL: return "MSP430ISD::SHL"; 9842625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430ISD::SRA: return "MSP430ISD::SRA"; 985fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 986fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov} 9878b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 988db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattnerbool MSP430TargetLowering::isTruncateFree(Type *Ty1, 989db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *Ty2) const { 990b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy()) 9919afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return false; 9929afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 9939afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return (Ty1->getPrimitiveSizeInBits() > Ty2->getPrimitiveSizeInBits()); 9949afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov} 9959afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 9969afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikovbool MSP430TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const { 9979afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov if (!VT1.isInteger() || !VT2.isInteger()) 9989afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return false; 9999afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 10009afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return (VT1.getSizeInBits() > VT2.getSizeInBits()); 10019afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov} 10029afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 1003db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattnerbool MSP430TargetLowering::isZExtFree(Type *Ty1, Type *Ty2) const { 10049afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov // MSP430 implicitly zero-extends 8-bit results in 16-bit registers. 1005b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands return 0 && Ty1->isIntegerTy(8) && Ty2->isIntegerTy(16); 10069afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov} 10079afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 10089afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikovbool MSP430TargetLowering::isZExtFree(EVT VT1, EVT VT2) const { 10099afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov // MSP430 implicitly zero-extends 8-bit results in 16-bit registers. 10109afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return 0 && VT1 == MVT::i8 && VT2 == MVT::i16; 10119afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov} 10129afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 10138b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===// 10148b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov// Other Lowering Code 10158b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===// 10168b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 10178b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMachineBasicBlock* 10182625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMSP430TargetLowering::EmitShiftInstr(MachineInstr *MI, 1019af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman MachineBasicBlock *BB) const { 10202625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineFunction *F = BB->getParent(); 10212625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineRegisterInfo &RI = F->getRegInfo(); 10222625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov DebugLoc dl = MI->getDebugLoc(); 10232625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); 10242625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10252625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned Opc; 10262625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov const TargetRegisterClass * RC; 10272625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov switch (MI->getOpcode()) { 1028bc2198133a1836598b54b943420748e75d5dea94Craig Topper default: llvm_unreachable("Invalid shift opcode!"); 10292625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Shl8: 10302625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SHL8r1; 1031420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR8RegClass; 10322625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 10332625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Shl16: 10342625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SHL16r1; 1035420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR16RegClass; 10362625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 10372625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Sra8: 10382625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR8r1; 1039420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR8RegClass; 10402625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 10412625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Sra16: 10422625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR16r1; 1043420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR16RegClass; 10442625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 10452625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Srl8: 10462625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR8r1c; 1047420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR8RegClass; 10482625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 10492625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Srl16: 10502625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR16r1c; 1051420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR16RegClass; 10522625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 10532625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov } 10542625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10552625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov const BasicBlock *LLVM_BB = BB->getBasicBlock(); 10562625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineFunction::iterator I = BB; 10572625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov ++I; 10582625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10592625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Create loop block 10602625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB); 10612625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineBasicBlock *RemBB = F->CreateMachineBasicBlock(LLVM_BB); 10622625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10632625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov F->insert(I, LoopBB); 10642625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov F->insert(I, RemBB); 10652625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10662625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Update machine-CFG edges by transferring all successors of the current 10672625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // block to the block containing instructions after shift. 106814152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman RemBB->splice(RemBB->begin(), BB, 106914152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman llvm::next(MachineBasicBlock::iterator(MI)), 107014152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BB->end()); 107114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman RemBB->transferSuccessorsAndUpdatePHIs(BB); 10722625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10732625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Add adges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB 10742625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BB->addSuccessor(LoopBB); 10752625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BB->addSuccessor(RemBB); 10762625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov LoopBB->addSuccessor(RemBB); 10772625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov LoopBB->addSuccessor(LoopBB); 10782625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 1079420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper unsigned ShiftAmtReg = RI.createVirtualRegister(&MSP430::GR8RegClass); 1080420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper unsigned ShiftAmtReg2 = RI.createVirtualRegister(&MSP430::GR8RegClass); 10812625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned ShiftReg = RI.createVirtualRegister(RC); 10822625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned ShiftReg2 = RI.createVirtualRegister(RC); 10832625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned ShiftAmtSrcReg = MI->getOperand(2).getReg(); 10842625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned SrcReg = MI->getOperand(1).getReg(); 10852625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned DstReg = MI->getOperand(0).getReg(); 10862625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10872625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // BB: 10882625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // cmp 0, N 10892625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // je RemBB 1090f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov BuildMI(BB, dl, TII.get(MSP430::CMP8ri)) 1091f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov .addReg(ShiftAmtSrcReg).addImm(0); 10922625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(BB, dl, TII.get(MSP430::JCC)) 10932625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addMBB(RemBB) 10942625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addImm(MSP430CC::COND_E); 10952625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10962625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // LoopBB: 10972625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB] 10982625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // ShiftAmt = phi [%N, BB], [%ShiftAmt2, LoopBB] 10992625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // ShiftReg2 = shift ShiftReg 11002625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // ShiftAmt2 = ShiftAmt - 1; 11012625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftReg) 11022625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(SrcReg).addMBB(BB) 11032625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftReg2).addMBB(LoopBB); 11042625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg) 11052625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftAmtSrcReg).addMBB(BB) 11062625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftAmtReg2).addMBB(LoopBB); 11072625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2) 11082625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftReg); 11092625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2) 11102625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftAmtReg).addImm(1); 11112625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::JCC)) 11122625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addMBB(LoopBB) 11132625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addImm(MSP430CC::COND_NE); 11142625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11152625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // RemBB: 11162625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB] 111714152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BuildMI(*RemBB, RemBB->begin(), dl, TII.get(MSP430::PHI), DstReg) 11182625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(SrcReg).addMBB(BB) 11192625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftReg2).addMBB(LoopBB); 11202625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 112114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman MI->eraseFromParent(); // The pseudo instruction is gone now. 11222625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return RemBB; 11232625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov} 11242625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11252625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMachineBasicBlock* 11268b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 1127af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman MachineBasicBlock *BB) const { 11282625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned Opc = MI->getOpcode(); 11292625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11302625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 || 11312625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc == MSP430::Sra8 || Opc == MSP430::Sra16 || 11322625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc == MSP430::Srl8 || Opc == MSP430::Srl16) 1133af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman return EmitShiftInstr(MI, BB); 11342625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11358b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); 11368b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov DebugLoc dl = MI->getDebugLoc(); 11372625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11382625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov assert((Opc == MSP430::Select16 || Opc == MSP430::Select8) && 11398b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov "Unexpected instr type to insert"); 11408b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 11418b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // To "insert" a SELECT instruction, we actually have to insert the diamond 11428b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // control-flow pattern. The incoming instruction knows the destination vreg 11438b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // to set, the condition code register to branch on, the true/false values to 11448b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // select between, and a branch opcode to use. 11458b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov const BasicBlock *LLVM_BB = BB->getBasicBlock(); 11468b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineFunction::iterator I = BB; 11478b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov ++I; 11488b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 11498b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // thisMBB: 11508b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // ... 11518b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // TrueVal = ... 11528b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // cmpTY ccX, r1, r2 11538b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // jCC copy1MBB 11548b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // fallthrough --> copy0MBB 11558b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *thisMBB = BB; 11568b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineFunction *F = BB->getParent(); 11578b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); 11588b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB); 11598b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov F->insert(I, copy0MBB); 11608b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov F->insert(I, copy1MBB); 11618b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Update machine-CFG edges by transferring all successors of the current 11628b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // block to the new block which will contain the Phi node for the select. 116314152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman copy1MBB->splice(copy1MBB->begin(), BB, 116414152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman llvm::next(MachineBasicBlock::iterator(MI)), 116514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BB->end()); 116614152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman copy1MBB->transferSuccessorsAndUpdatePHIs(BB); 11678b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Next, add the true and fallthrough blocks as its successors. 11688b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy0MBB); 11698b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy1MBB); 11708b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 117114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BuildMI(BB, dl, TII.get(MSP430::JCC)) 117214152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman .addMBB(copy1MBB) 117314152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman .addImm(MI->getOperand(3).getImm()); 117414152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman 11758b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // copy0MBB: 11768b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // %FalseValue = ... 11778b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // # fallthrough to copy1MBB 11788b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB = copy0MBB; 11798b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 11808b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Update machine-CFG edges 11818b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy1MBB); 11828b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 11838b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // copy1MBB: 11848b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] 11858b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // ... 11868b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB = copy1MBB; 118714152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BuildMI(*BB, BB->begin(), dl, TII.get(MSP430::PHI), 11888b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MI->getOperand(0).getReg()) 11898b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB) 11908b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB); 11918b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 119214152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman MI->eraseFromParent(); // The pseudo instruction is gone now. 11938b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov return BB; 11948b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov} 1195