1f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//===-- MSP430ISelLowering.cpp - MSP430 DAG Lowering Implementation ------===// 2f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// 3f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// The LLVM Compiler Infrastructure 4f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// 5f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// This file is distributed under the University of Illinois Open Source 6f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// License. See LICENSE.TXT for details. 7f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// 8f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//===----------------------------------------------------------------------===// 9f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// 10f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// This file implements the MSP430TargetLowering class. 11f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// 12f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//===----------------------------------------------------------------------===// 13f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 14f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#define DEBUG_TYPE "msp430-lower" 15f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 16f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430ISelLowering.h" 17f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430.h" 1806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov#include "MSP430MachineFunctionInfo.h" 19f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430Subtarget.h" 20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "MSP430TargetMachine.h" 21f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/CallingConvLower.h" 22f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h" 23f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineFunction.h" 24f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h" 25f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineRegisterInfo.h" 26f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/SelectionDAGISel.h" 27362dd0bef5437f85586c046bc53287b6fbe9c099Anton Korobeynikov#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 28f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/ValueTypes.h" 290b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/CallingConv.h" 300b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h" 310b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 320b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/GlobalAlias.h" 330b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/GlobalVariable.h" 340b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Intrinsics.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 643574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow TD = getDataLayout(); 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 1670ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov // varargs support 1680ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov setOperationAction(ISD::VASTART, MVT::Other, Custom); 1690ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov setOperationAction(ISD::VAARG, MVT::Other, Expand); 1700ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov setOperationAction(ISD::VAEND, MVT::Other, Expand); 1710ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov setOperationAction(ISD::VACOPY, MVT::Other, Expand); 17227253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov setOperationAction(ISD::JumpTable, MVT::i16, Custom); 1730ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov 174b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov // Libcalls names. 175b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov if (HWMultMode == HWMultIntr) { 176b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I8, "__mulqi3hw"); 177b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I16, "__mulhi3hw"); 178b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov } else if (HWMultMode == HWMultNoIntr) { 179b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I8, "__mulqi3hw_noint"); 180b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I16, "__mulhi3hw_noint"); 181b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov } 182fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman 183fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman setMinFunctionAlignment(1); 184fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman setPrefFunctionAlignment(2); 185f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 186f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 187d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerOperation(SDValue Op, 188d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 189f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov switch (Op.getOpcode()) { 190ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov case ISD::SHL: // FALLTHROUGH 191e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case ISD::SRL: 1924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case ISD::SRA: return LowerShifts(Op, DAG); 1933513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); 19469d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); 1955d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG); 1968d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov case ISD::SETCC: return LowerSETCC(Op, DAG); 1971bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case ISD::BR_CC: return LowerBR_CC(Op, DAG); 1981bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); 199b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov case ISD::SIGN_EXTEND: return LowerSIGN_EXTEND(Op, DAG); 20006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); 20106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); 2020ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov case ISD::VASTART: return LowerVASTART(Op, DAG); 20327253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov case ISD::JumpTable: return LowerJumpTable(Op, DAG); 204f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov default: 205c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("unimplemented operand"); 206f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov } 207f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 208f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 209c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===// 210cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov// MSP430 Inline Assembly Support 211cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===// 212cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 213cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// getConstraintType - Given a constraint letter, return the type of 214cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// constraint it is for this target. 215cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovTargetLowering::ConstraintType 216cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering::getConstraintType(const std::string &Constraint) const { 217cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov if (Constraint.size() == 1) { 218cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov switch (Constraint[0]) { 219cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov case 'r': 220cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return C_RegisterClass; 221cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov default: 222cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov break; 223cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 224cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 225cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return TargetLowering::getConstraintType(Constraint); 226cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov} 227cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 228cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikovstd::pair<unsigned, const TargetRegisterClass*> 229cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering:: 230cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovgetRegForInlineAsmConstraint(const std::string &Constraint, 2315b3fca50a08865f0db55fc92ad1c037a04e12177Chad Rosier MVT VT) const { 232cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov if (Constraint.size() == 1) { 233cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov // GCC Constraint Letters 234cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov switch (Constraint[0]) { 235cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov default: break; 236cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov case 'r': // GENERAL_REGS 237cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov if (VT == MVT::i8) 238420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper return std::make_pair(0U, &MSP430::GR8RegClass); 239cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 240420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper return std::make_pair(0U, &MSP430::GR16RegClass); 241cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 242cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 243cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 244cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); 245cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov} 246cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 247cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===// 248c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// Calling Convention Implementation 249c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===// 250c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 251f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430GenCallingConv.inc" 252c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 25398ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 25498ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerFormalArguments(SDValue Chain, 25565c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, 25698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isVarArg, 25798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> 25898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Ins, 259ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, 26098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SelectionDAG &DAG, 261d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) 262d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman const { 26398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 26498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman switch (CallConv) { 265c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov default: 266c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Unsupported calling convention"); 267c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov case CallingConv::C: 268c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov case CallingConv::Fast: 26998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals); 270e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov case CallingConv::MSP430_INTR: 2714d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie if (Ins.empty()) 2724d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie return Chain; 27375361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("ISRs cannot have arguments"); 274c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 275c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov} 276c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 27798ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 278d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin HolewinskiMSP430TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, 279d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) const { 280d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SelectionDAG &DAG = CLI.DAG; 281ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc &dl = CLI.DL; 282a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs; 283a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper SmallVectorImpl<SDValue> &OutVals = CLI.OutVals; 284a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins; 285d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SDValue Chain = CLI.Chain; 286d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SDValue Callee = CLI.Callee; 287d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski bool &isTailCall = CLI.IsTailCall; 288d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski CallingConv::ID CallConv = CLI.CallConv; 289d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski bool isVarArg = CLI.IsVarArg; 290d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski 2910c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng // MSP430 target does not yet support tail call optimization. 2920c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng isTailCall = false; 29398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 29498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman switch (CallConv) { 2954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov default: 296c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Unsupported calling convention"); 2974428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CallingConv::Fast: 2984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CallingConv::C: 29998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall, 300c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman Outs, OutVals, Ins, dl, DAG, InVals); 301e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov case CallingConv::MSP430_INTR: 30275361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("ISRs cannot be called directly"); 3034428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 3044428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 3054428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 306c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// LowerCCCArguments - transform physical registers into virtual registers and 307c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// generate load operations for arguments places on the stack. 308c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// FIXME: struct return stuff 30998ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 31098ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCArguments(SDValue Chain, 31165c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, 31298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isVarArg, 31398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> 31498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Ins, 315ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, 31698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SelectionDAG &DAG, 317d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) 318d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman const { 319c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineFunction &MF = DAG.getMachineFunction(); 320c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 321c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineRegisterInfo &RegInfo = MF.getRegInfo(); 3220ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>(); 323c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 324c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Assign locations to all of the incoming arguments. 325c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov SmallVector<CCValAssign, 16> ArgLocs; 326471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 32756cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling getTargetMachine(), ArgLocs, *DAG.getContext()); 32898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeFormalArguments(Ins, CC_MSP430); 329c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 3300ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov // Create frame index for the start of the first vararg value 3310ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov if (isVarArg) { 3320ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov unsigned Offset = CCInfo.getNextStackOffset(); 3330ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov FuncInfo->setVarArgsFrameIndex(MFI->CreateFixedObject(1, Offset, true)); 3340ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov } 335c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 336c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 337c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov CCValAssign &VA = ArgLocs[i]; 338c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.isRegLoc()) { 339c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Arguments passed in registers 340e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT RegVT = VA.getLocVT(); 341825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson switch (RegVT.getSimpleVT().SimpleTy) { 34295771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson default: 343804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin { 344dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#ifndef NDEBUG 3454437ae213d5435390f0750213b53ec807c047f22Chris Lattner errs() << "LowerFormalArguments Unhandled argument type: " 346825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson << RegVT.getSimpleVT().SimpleTy << "\n"; 347dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#endif 348c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable(0); 349804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin } 350825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i16: 351420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper unsigned VReg = RegInfo.createVirtualRegister(&MSP430::GR16RegClass); 352c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov RegInfo.addLiveIn(VA.getLocReg(), VReg); 35398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, RegVT); 354c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 355c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // If this is an 8-bit value, it is really passed promoted to 16 356c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // bits. Insert an assert[sz]ext to capture this, then truncate to the 357c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // right size. 358c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.getLocInfo() == CCValAssign::SExt) 359c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue, 360c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov DAG.getValueType(VA.getValVT())); 361c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov else if (VA.getLocInfo() == CCValAssign::ZExt) 362c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue, 363c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov DAG.getValueType(VA.getValVT())); 364c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 365c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.getLocInfo() != CCValAssign::Full) 366c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); 367c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 36898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman InVals.push_back(ArgValue); 369c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 370c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } else { 371c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Sanity check 372c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov assert(VA.isMemLoc()); 3736cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov 3746cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov SDValue InVal; 3756cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov ISD::ArgFlagsTy Flags = Ins[i].Flags; 3766cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov 3776cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov if (Flags.isByVal()) { 3786cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov int FI = MFI->CreateFixedObject(Flags.getByValSize(), 3796cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov VA.getLocMemOffset(), true); 3806cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov InVal = DAG.getFrameIndex(FI, getPointerTy()); 3816cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov } else { 3826cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov // Load the argument to a virtual register 3836cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov unsigned ObjSize = VA.getLocVT().getSizeInBits()/8; 3846cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov if (ObjSize > 2) { 3856cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov errs() << "LowerFormalArguments Unhandled argument type: " 3866cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov << EVT(VA.getLocVT()).getEVTString() 3876cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov << "\n"; 3886cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov } 3896cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov // Create the frame index object for this incoming parameter... 3906cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true); 3916cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov 3926cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov // Create the SelectionDAG nodes corresponding to a load 3936cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov //from this parameter 3946cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov SDValue FIN = DAG.getFrameIndex(FI, MVT::i16); 3956cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov InVal = DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, 3966cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov MachinePointerInfo::getFixedStack(FI), 3976cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov false, false, false, 0); 398c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 3996cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov 4006cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov InVals.push_back(InVal); 401c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 402c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 403c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 40498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return Chain; 405c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov} 406fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 40798ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 40898ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerReturn(SDValue Chain, 40965c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 41098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::OutputArg> &Outs, 411c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman const SmallVectorImpl<SDValue> &OutVals, 412ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, SelectionDAG &DAG) const { 41398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 414fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // CCValAssign - represent the assignment of the return value to a location 415fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov SmallVector<CCValAssign, 16> RVLocs; 416fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 417e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov // ISRs cannot return any value. 4184d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie if (CallConv == CallingConv::MSP430_INTR && !Outs.empty()) 41975361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("ISRs cannot return any value"); 420e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov 421fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // CCState - Info about the registers and stack slot. 422471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 42356cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling getTargetMachine(), RVLocs, *DAG.getContext()); 424fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 42598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman // Analize return values. 42698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeReturn(Outs, RetCC_MSP430); 427fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 428fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov SDValue Flag; 429294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen SmallVector<SDValue, 4> RetOps(1, Chain); 430fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 431fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // Copy the result values into the output registers. 432fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov for (unsigned i = 0; i != RVLocs.size(); ++i) { 433fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov CCValAssign &VA = RVLocs[i]; 434fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov assert(VA.isRegLoc() && "Can only return in registers!"); 435fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 436fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), 437c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman OutVals[i], Flag); 438fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 439dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov // Guarantee that all emitted copies are stuck together, 440dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov // avoiding something bad. 441fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov Flag = Chain.getValue(1); 442294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); 443fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 444fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 445e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov unsigned Opc = (CallConv == CallingConv::MSP430_INTR ? 446e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG); 447e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov 448294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen RetOps[0] = Chain; // Update chain. 449294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen 450294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen // Add the flag if we have it. 451fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (Flag.getNode()) 452294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen RetOps.push_back(Flag); 453fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 454294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen return DAG.getNode(Opc, dl, MVT::Other, &RetOps[0], RetOps.size()); 455fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov} 456fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 4574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// LowerCCCCallTo - functions arguments are copied from virtual regs to 4584428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted. 4590bf3c99886bed6796eada8f65942ee6023fc6e89Job Noorman// TODO: sret. 46098ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 46198ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, 46265c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 46398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isTailCall, 46498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::OutputArg> 46598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Outs, 466c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman const SmallVectorImpl<SDValue> &OutVals, 46798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> &Ins, 468ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, SelectionDAG &DAG, 469d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) const { 4704428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Analyze operands of the call, assigning locations to each operand. 4714428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<CCValAssign, 16> ArgLocs; 472471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 47356cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling getTargetMachine(), ArgLocs, *DAG.getContext()); 4744428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 47598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeCallOperands(Outs, CC_MSP430); 4764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4774428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Get a count of how many bytes are to be pushed on the stack. 4784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov unsigned NumBytes = CCInfo.getNextStackOffset(); 4794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCALLSEQ_START(Chain ,DAG.getConstant(NumBytes, 4816e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick getPointerTy(), true), 4826e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick dl); 4834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass; 4854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<SDValue, 12> MemOpChains; 4864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue StackPtr; 4874428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Walk the register/memloc assignments, inserting copies/loads. 4894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 4904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov CCValAssign &VA = ArgLocs[i]; 4914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 492c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman SDValue Arg = OutVals[i]; 4934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4944428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Promote the value if needed. 4954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov switch (VA.getLocInfo()) { 496c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Unknown loc info!"); 4974428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::Full: break; 4984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::SExt: 4994428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); 5004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 5014428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::ZExt: 5024428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg); 5034428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 5044428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::AExt: 5054428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); 5064428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 5074428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 5084428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Arguments that can be passed on register must be kept at RegsToPass 5104428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // vector 5114428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (VA.isRegLoc()) { 5124428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 5134428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } else { 5144428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov assert(VA.isMemLoc()); 5154428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (StackPtr.getNode() == 0) 5174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SPW, getPointerTy()); 5184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), 5204428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov StackPtr, 5214428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG.getIntPtrConstant(VA.getLocMemOffset())); 5224428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5236cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov SDValue MemOp; 5246cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov ISD::ArgFlagsTy Flags = Outs[i].Flags; 5256cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov 5266cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov if (Flags.isByVal()) { 5276cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), MVT::i16); 5286cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov MemOp = DAG.getMemcpy(Chain, dl, PtrOff, Arg, SizeNode, 5296cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov Flags.getByValAlign(), 5306cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov /*isVolatile*/false, 5316cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov /*AlwaysInline=*/true, 5326cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov MachinePointerInfo(), 5336cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov MachinePointerInfo()); 5346cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov } else { 5356cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov MemOp = DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo(), 5366cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov false, false, 0); 5376cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov } 5384428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5396cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov MemOpChains.push_back(MemOp); 5404428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 5414428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 5424428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5434428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Transform all store nodes into one single node because all store nodes are 5444428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // independent of each other. 5454428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (!MemOpChains.empty()) 546825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 5474428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov &MemOpChains[0], MemOpChains.size()); 5484428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5494428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Build a sequence of copy-to-reg nodes chained together with token chain and 5504428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // flag operands which copy the outgoing args into registers. The InFlag in 5517a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // necessary since all emitted instructions must be stuck together. 5524428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue InFlag; 5534428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 5544428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, 5554428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RegsToPass[i].second, InFlag); 5564428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(1); 5574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 5584428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5594428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // If the callee is a GlobalAddress node (quite common, every direct call is) 5604428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 5614428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Likewise ExternalSymbol -> TargetExternalSymbol. 5624428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 5630d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i16); 5644428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) 565825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i16); 5664428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5674428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Returns a chain & a flag for retval copy to use. 568f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 5694428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<SDValue, 8> Ops; 5704428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(Chain); 5714428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(Callee); 5724428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5734428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Add argument registers to the end of the list so that they are 5744428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // known live into the call. 5754428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 5764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(DAG.getRegister(RegsToPass[i].first, 5774428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RegsToPass[i].second.getValueType())); 5784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (InFlag.getNode()) 5804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(InFlag); 5814428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getNode(MSP430ISD::CALL, dl, NodeTys, &Ops[0], Ops.size()); 5834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(1); 5844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Create the CALLSEQ_END node. 5864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCALLSEQ_END(Chain, 5874428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG.getConstant(NumBytes, getPointerTy(), true), 5884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG.getConstant(0, getPointerTy(), true), 5896e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick InFlag, dl); 5904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(1); 5914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Handle result values, copying them out of physregs into vregs that we 5934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // return. 59498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl, 59598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DAG, InVals); 5964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 5974428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 59898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// LowerCallResult - Lower the result values of a call into the 59998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// appropriate copies out of appropriate physical registers. 60098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// 60198ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 6024428885c5acfffbbdd03ad2aab23960531c47753Anton KorobeynikovMSP430TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, 60365c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 60498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> &Ins, 605ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, SelectionDAG &DAG, 606d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) const { 6074428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 6084428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Assign locations to each value returned by this call. 6094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<CCValAssign, 16> RVLocs; 610471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 61156cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling getTargetMachine(), RVLocs, *DAG.getContext()); 6124428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 61398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeCallResult(Ins, RetCC_MSP430); 6144428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 6154428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Copy all of the result registers out of their specified physreg. 6164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0; i != RVLocs.size(); ++i) { 6174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(), 6184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RVLocs[i].getValVT(), InFlag).getValue(1); 6194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(2); 62098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman InVals.push_back(Chain.getValue(0)); 6214428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 6224428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 62398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return Chain; 6244428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 6254428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 626d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton KorobeynikovSDValue MSP430TargetLowering::LowerShifts(SDValue Op, 627d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 628ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov unsigned Opc = Op.getOpcode(); 629d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov SDNode* N = Op.getNode(); 630e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Op.getValueType(); 631ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(N); 632d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 6332625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Expand non-constant shifts to loops: 634d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov if (!isa<ConstantSDNode>(N->getOperand(1))) 6352625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov switch (Opc) { 636bc2198133a1836598b54b943420748e75d5dea94Craig Topper default: llvm_unreachable("Invalid shift opcode!"); 6372625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case ISD::SHL: 6382625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return DAG.getNode(MSP430ISD::SHL, dl, 6392625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov VT, N->getOperand(0), N->getOperand(1)); 6402625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case ISD::SRA: 6412625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return DAG.getNode(MSP430ISD::SRA, dl, 6422625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov VT, N->getOperand(0), N->getOperand(1)); 6432625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case ISD::SRL: 6442625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return DAG.getNode(MSP430ISD::SRL, dl, 6452625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov VT, N->getOperand(0), N->getOperand(1)); 6462625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov } 647d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 648d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue(); 649d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 650d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // Expand the stuff into sequence of shifts. 651d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // FIXME: for some shift amounts this might be done better! 652d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N 653d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov SDValue Victim = N->getOperand(0); 654e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov 655e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov if (Opc == ISD::SRL && ShiftAmount) { 656e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov // Emit a special goodness here: 657e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov // srl A, 1 => clrc; rrc A 658bf8ef3f29de28529b5d65970af9015c41f7c809bAnton Korobeynikov Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim); 659e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov ShiftAmount -= 1; 660e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov } 661e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov 662d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov while (ShiftAmount--) 663aceb620de855485a4fb2eed343d880d76f6c701cAnton Korobeynikov Victim = DAG.getNode((Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA), 664ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov dl, VT, Victim); 665d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 666d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov return Victim; 667d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov} 668d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 669d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerGlobalAddress(SDValue Op, 670d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 6713513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); 6723513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset(); 6733513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov 6743513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov // Create the TargetGlobalAddress node, folding in the constant offset. 675ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDValue Result = DAG.getTargetGlobalAddress(GV, SDLoc(Op), 6760d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel getPointerTy(), Offset); 677ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick return DAG.getNode(MSP430ISD::Wrapper, SDLoc(Op), 6783513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov getPointerTy(), Result); 6793513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov} 6803513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov 6815d59f68ade7573175f1ace09061a94286e59076bAnton KorobeynikovSDValue MSP430TargetLowering::LowerExternalSymbol(SDValue Op, 682d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 683ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 6845d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol(); 6855d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov SDValue Result = DAG.getTargetExternalSymbol(Sym, getPointerTy()); 6865d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov 68790f20044ade3712c8b0c3f4ebe47d57ad15ae6ceChad Rosier return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result); 6885d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov} 6895d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov 69069d5b48bc31b7a443355cdf1506005804b4f63e6Anton KorobeynikovSDValue MSP430TargetLowering::LowerBlockAddress(SDValue Op, 69169d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov SelectionDAG &DAG) const { 692ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 69369d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress(); 6946c7ccaa3fd1d6e96d0bf922554b09d2b17c3b0e3Michael Liao SDValue Result = DAG.getTargetBlockAddress(BA, getPointerTy()); 69569d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov 69690f20044ade3712c8b0c3f4ebe47d57ad15ae6ceChad Rosier return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result); 69769d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov} 69869d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov 6993926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikovstatic SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC, 7001bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC, 701ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, SelectionDAG &DAG) { 702ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov // FIXME: Handle bittests someday 703ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet"); 704ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 705ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov // FIXME: Handle jump negative someday 7063926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov MSP430CC::CondCodes TCC = MSP430CC::COND_INVALID; 707ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov switch (CC) { 708c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Invalid integer condition!"); 709ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETEQ: 7103926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_E; // aka COND_Z 711f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov // Minor optimization: if LHS is a constant, swap operands, then the 7121722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov // constant can be folded into comparison. 713f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov if (LHS.getOpcode() == ISD::Constant) 7141722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov std::swap(LHS, RHS); 715ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 716ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETNE: 7173926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_NE; // aka COND_NZ 718f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov // Minor optimization: if LHS is a constant, swap operands, then the 7191722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov // constant can be folded into comparison. 720f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov if (LHS.getOpcode() == ISD::Constant) 7211722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov std::swap(LHS, RHS); 722ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 723ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETULE: 724ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 725ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETUGE: 7260c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // Turn lhs u>= rhs with lhs constant into rhs u< lhs+1, this allows us to 7270c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // fold constant into instruction. 7280c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 7290c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov LHS = RHS; 7300c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 7310c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_LO; 7320c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov break; 7330c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov } 7343926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_HS; // aka COND_C 735ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 736ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETUGT: 737ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 738ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETULT: 7390c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // Turn lhs u< rhs with lhs constant into rhs u>= lhs+1, this allows us to 7400c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // fold constant into instruction. 7410c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 7420c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov LHS = RHS; 7430c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 7440c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_HS; 7450c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov break; 7460c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov } 7473926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_LO; // aka COND_NC 748ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 749ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETLE: 750ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 751ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETGE: 7520c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // Turn lhs >= rhs with lhs constant into rhs < lhs+1, this allows us to 7530c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // fold constant into instruction. 7540c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 7550c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov LHS = RHS; 7560c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 7570c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_L; 7580c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov break; 7590c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov } 7603926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_GE; 761ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 762ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETGT: 763ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 764ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETLT: 7650c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to 7660c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // fold constant into instruction. 7670c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 7680c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov LHS = RHS; 7690c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 7700c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_GE; 7710c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov break; 7720c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov } 7733926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_L; 774ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 775ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov } 776ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 7773926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TargetCC = DAG.getConstant(TCC, MVT::i8); 778f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner return DAG.getNode(MSP430ISD::CMP, dl, MVT::Glue, LHS, RHS); 779ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov} 780ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 7811bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 782d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const { 783ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov SDValue Chain = Op.getOperand(0); 7841bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); 7851bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue LHS = Op.getOperand(2); 7861bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue RHS = Op.getOperand(3); 7871bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Dest = Op.getOperand(4); 788ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl (Op); 7891bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 7903926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov SDValue TargetCC; 7911bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 7921bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 7931bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(), 7943926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov Chain, Dest, TargetCC, Flag); 795ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov} 796ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 797d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const { 7988d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue LHS = Op.getOperand(0); 7998d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue RHS = Op.getOperand(1); 800ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl (Op); 8018d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov 8028d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // If we are doing an AND and testing against zero, then the CMP 8038d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // will not be generated. The AND (or BIT) will generate the condition codes, 8048d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // but they are different from CMP. 805cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov // FIXME: since we're doing a post-processing, use a pseudoinstr here, so 806cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov // lowering & isel wouldn't diverge. 8078d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov bool andCC = false; 8088d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) { 8098d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (RHSC->isNullValue() && LHS.hasOneUse() && 8108d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov (LHS.getOpcode() == ISD::AND || 8118d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov (LHS.getOpcode() == ISD::TRUNCATE && 8128d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov LHS.getOperand(0).getOpcode() == ISD::AND))) { 8138d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov andCC = true; 8148d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 8158d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 8168d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get(); 8178d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue TargetCC; 8188d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 8198d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov 8208d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Get the condition codes directly from the status register, if its easy. 8218d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Otherwise a branch will be generated. Note that the AND and BIT 8228d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // instructions generate different flags than CMP, the carry bit can be used 8238d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // for NE/EQ. 8248d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov bool Invert = false; 8258d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov bool Shift = false; 8268d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov bool Convert = true; 8278d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov switch (cast<ConstantSDNode>(TargetCC)->getZExtValue()) { 8288d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov default: 8298d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Convert = false; 8308d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 8318d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov case MSP430CC::COND_HS: 8328d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Res = SRW & 1, no processing is required 8338d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 834cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov case MSP430CC::COND_LO: 8358d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Res = ~(SRW & 1) 8368d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Invert = true; 8378d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 838cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov case MSP430CC::COND_NE: 8398d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (andCC) { 8408d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // C = ~Z, thus Res = SRW & 1, no processing is required 8418d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } else { 842455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov // Res = ~((SRW >> 1) & 1) 8438d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Shift = true; 844455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov Invert = true; 8458d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 8468d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 847cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov case MSP430CC::COND_E: 848455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov Shift = true; 849455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov // C = ~Z for AND instruction, thus we can put Res = ~(SRW & 1), however, 850455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov // Res = (SRW >> 1) & 1 is 1 word shorter. 8518d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 8528d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 8538d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov EVT VT = Op.getValueType(); 8548d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue One = DAG.getConstant(1, VT); 8558d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (Convert) { 8568d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SRW, 857cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov MVT::i16, Flag); 8588d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (Shift) 8598d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // FIXME: somewhere this is turned into a SRL, lower it MSP specific? 8608d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One); 8618d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SR = DAG.getNode(ISD::AND, dl, MVT::i16, SR, One); 8628d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (Invert) 8638d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SR = DAG.getNode(ISD::XOR, dl, MVT::i16, SR, One); 8648d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov return SR; 8658d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } else { 8668d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue Zero = DAG.getConstant(0, VT); 867f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue); 8688d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SmallVector<SDValue, 4> Ops; 8698d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Ops.push_back(One); 8708d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Ops.push_back(Zero); 8718d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Ops.push_back(TargetCC); 8728d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Ops.push_back(Flag); 8738d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size()); 8748d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 8758d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov} 8768d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov 877d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op, 878d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 8791bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue LHS = Op.getOperand(0); 8801bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue RHS = Op.getOperand(1); 8811bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue TrueV = Op.getOperand(2); 8821bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue FalseV = Op.getOperand(3); 8831bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); 884ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl (Op); 8851bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 8863926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov SDValue TargetCC; 8871bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 8888b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 889f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue); 8908b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov SmallVector<SDValue, 4> Ops; 8918b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov Ops.push_back(TrueV); 8928b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov Ops.push_back(FalseV); 8933926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov Ops.push_back(TargetCC); 8941bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov Ops.push_back(Flag); 8958b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 8961bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size()); 8978b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov} 8988b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 899b78e214274d397407b6167a293b7cd7c3b526ddeAnton KorobeynikovSDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op, 900d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 901b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov SDValue Val = Op.getOperand(0); 902e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Op.getValueType(); 903ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 904b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 905825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson assert(VT == MVT::i16 && "Only support i16 for now!"); 906b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 907b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT, 908b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val), 909b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov DAG.getValueType(Val.getValueType())); 910b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov} 911b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 912d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue 913d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanMSP430TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) const { 91406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MachineFunction &MF = DAG.getMachineFunction(); 91506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>(); 91606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov int ReturnAddrIndex = FuncInfo->getRAIndex(); 91706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 91806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov if (ReturnAddrIndex == 0) { 91906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov // Set up a frame object for the return address. 920426c2bf5cdd2173e4a33aea8cb92cf684a724f4bChandler Carruth uint64_t SlotSize = TD->getPointerSize(); 92106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(SlotSize, -SlotSize, 922ed2ae136d29dd36122d2476801e7d7a86e8301e3Evan Cheng true); 92306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov FuncInfo->setRAIndex(ReturnAddrIndex); 92406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov } 92506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 92606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy()); 92706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov} 92806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 929d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op, 930d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 9312457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 9322457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng MFI->setReturnAddressIsTaken(true); 9332457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng 93406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); 935ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 93606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 93706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov if (Depth > 0) { 93806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue FrameAddr = LowerFRAMEADDR(Op, DAG); 93906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue Offset = 940426c2bf5cdd2173e4a33aea8cb92cf684a724f4bChandler Carruth DAG.getConstant(TD->getPointerSize(), MVT::i16); 94106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), 94206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov DAG.getNode(ISD::ADD, dl, getPointerTy(), 94306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov FrameAddr, Offset), 944d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper MachinePointerInfo(), false, false, false, 0); 94506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov } 94606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 94706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov // Just load the return address. 94806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue RetAddrFI = getReturnAddressFrameIndex(DAG); 94906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), 950d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper RetAddrFI, MachinePointerInfo(), false, false, false, 0); 95106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov} 95206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 953d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op, 954d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 95506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 95606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MFI->setFrameAddressIsTaken(true); 9572457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng 95806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov EVT VT = Op.getValueType(); 959ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); // FIXME probably not meaningful 96006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); 96106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, 96206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MSP430::FPW, VT); 96306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov while (Depth--) 964d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr, 965d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner MachinePointerInfo(), 966d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper false, false, false, 0); 96706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return FrameAddr; 96806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov} 96906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 9700ae61240341ca76e1329f251c64d2f475fa89278Anton KorobeynikovSDValue MSP430TargetLowering::LowerVASTART(SDValue Op, 9710ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov SelectionDAG &DAG) const { 9720ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov MachineFunction &MF = DAG.getMachineFunction(); 9730ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>(); 9740ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov 9750ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov // Frame index of first vararg argument 9760ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov SDValue FrameIndex = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), 9770ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov getPointerTy()); 9780ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); 9790ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov 9800ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov // Create a store of the frame index to the location operand 981ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick return DAG.getStore(Op.getOperand(0), SDLoc(Op), FrameIndex, 9820ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov Op.getOperand(1), MachinePointerInfo(SV), 9830ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov false, false, 0); 9840ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov} 9850ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov 98627253f5edd04791bfbd0b5dd6e228be1d8071fceAnton KorobeynikovSDValue MSP430TargetLowering::LowerJumpTable(SDValue Op, 98727253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov SelectionDAG &DAG) const { 98827253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov JumpTableSDNode *JT = cast<JumpTableSDNode>(Op); 98927253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov SDValue Result = DAG.getTargetJumpTable(JT->getIndex(), getPointerTy()); 990a77f816c4c6e4c833ac9ab78e2e038dcfb861c73Anton Korobeynikov return DAG.getNode(MSP430ISD::Wrapper, SDLoc(JT), 991a77f816c4c6e4c833ac9ab78e2e038dcfb861c73Anton Korobeynikov getPointerTy(), Result); 99227253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov} 99327253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov 9946534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// getPostIndexedAddressParts - returns true by value, base pointer and 9956534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// offset pointer and addressing mode by reference if this node can be 9966534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// combined with a load / store to form a post-indexed load / store. 9976534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikovbool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op, 9986534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SDValue &Base, 9996534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SDValue &Offset, 10006534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov ISD::MemIndexedMode &AM, 10016534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SelectionDAG &DAG) const { 10026534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 10036534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov LoadSDNode *LD = cast<LoadSDNode>(N); 10046534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (LD->getExtensionType() != ISD::NON_EXTLOAD) 10056534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 10066534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 10076534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov EVT VT = LD->getMemoryVT(); 10086534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (VT != MVT::i8 && VT != MVT::i16) 10096534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 10106534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 10116534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (Op->getOpcode() != ISD::ADD) 10126534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 10136534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 10146534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) { 10156534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov uint64_t RHSC = RHS->getZExtValue(); 10166534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if ((VT == MVT::i16 && RHSC != 2) || 10176534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov (VT == MVT::i8 && RHSC != 1)) 10186534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 10196534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 10206534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov Base = Op->getOperand(0); 10216534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov Offset = DAG.getConstant(RHSC, VT); 10226534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov AM = ISD::POST_INC; 10236534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return true; 10246534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov } 10256534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 10266534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 10276534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov} 10286534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 10296534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 1030fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikovconst char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const { 1031fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov switch (Opcode) { 1032fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov default: return NULL; 1033fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov case MSP430ISD::RET_FLAG: return "MSP430ISD::RET_FLAG"; 10346bfcba7e137113e5f38cc4f937ad61cc7253ec74Anton Korobeynikov case MSP430ISD::RETI_FLAG: return "MSP430ISD::RETI_FLAG"; 1035d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov case MSP430ISD::RRA: return "MSP430ISD::RRA"; 1036e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case MSP430ISD::RLA: return "MSP430ISD::RLA"; 1037e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case MSP430ISD::RRC: return "MSP430ISD::RRC"; 1038b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov case MSP430ISD::CALL: return "MSP430ISD::CALL"; 10393513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov case MSP430ISD::Wrapper: return "MSP430ISD::Wrapper"; 10401bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case MSP430ISD::BR_CC: return "MSP430ISD::BR_CC"; 1041ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case MSP430ISD::CMP: return "MSP430ISD::CMP"; 10421bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case MSP430ISD::SELECT_CC: return "MSP430ISD::SELECT_CC"; 10432625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430ISD::SHL: return "MSP430ISD::SHL"; 10442625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430ISD::SRA: return "MSP430ISD::SRA"; 1045fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 1046fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov} 10478b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 1048db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattnerbool MSP430TargetLowering::isTruncateFree(Type *Ty1, 1049db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *Ty2) const { 1050b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy()) 10519afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return false; 10529afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 10539afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return (Ty1->getPrimitiveSizeInBits() > Ty2->getPrimitiveSizeInBits()); 10549afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov} 10559afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 10569afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikovbool MSP430TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const { 10579afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov if (!VT1.isInteger() || !VT2.isInteger()) 10589afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return false; 10599afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 10609afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return (VT1.getSizeInBits() > VT2.getSizeInBits()); 10619afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov} 10629afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 1063db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattnerbool MSP430TargetLowering::isZExtFree(Type *Ty1, Type *Ty2) const { 10649afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov // MSP430 implicitly zero-extends 8-bit results in 16-bit registers. 1065b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands return 0 && Ty1->isIntegerTy(8) && Ty2->isIntegerTy(16); 10669afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov} 10679afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 10689afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikovbool MSP430TargetLowering::isZExtFree(EVT VT1, EVT VT2) const { 10699afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov // MSP430 implicitly zero-extends 8-bit results in 16-bit registers. 10709afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return 0 && VT1 == MVT::i8 && VT2 == MVT::i16; 10719afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov} 10729afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 1073968b667e27d7fc9a5bf5da52191a7af629e174dcEli Benderskybool MSP430TargetLowering::isZExtFree(SDValue Val, EVT VT2) const { 1074968b667e27d7fc9a5bf5da52191a7af629e174dcEli Bendersky return isZExtFree(Val.getValueType(), VT2); 1075968b667e27d7fc9a5bf5da52191a7af629e174dcEli Bendersky} 1076968b667e27d7fc9a5bf5da52191a7af629e174dcEli Bendersky 10778b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===// 10788b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov// Other Lowering Code 10798b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===// 10808b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 10818b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMachineBasicBlock* 10822625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMSP430TargetLowering::EmitShiftInstr(MachineInstr *MI, 1083af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman MachineBasicBlock *BB) const { 10842625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineFunction *F = BB->getParent(); 10852625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineRegisterInfo &RI = F->getRegInfo(); 10862625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov DebugLoc dl = MI->getDebugLoc(); 10872625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); 10882625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10892625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned Opc; 10902625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov const TargetRegisterClass * RC; 10912625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov switch (MI->getOpcode()) { 1092bc2198133a1836598b54b943420748e75d5dea94Craig Topper default: llvm_unreachable("Invalid shift opcode!"); 10932625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Shl8: 10942625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SHL8r1; 1095420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR8RegClass; 10962625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 10972625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Shl16: 10982625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SHL16r1; 1099420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR16RegClass; 11002625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 11012625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Sra8: 11022625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR8r1; 1103420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR8RegClass; 11042625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 11052625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Sra16: 11062625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR16r1; 1107420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR16RegClass; 11082625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 11092625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Srl8: 11102625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR8r1c; 1111420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR8RegClass; 11122625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 11132625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Srl16: 11142625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR16r1c; 1115420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR16RegClass; 11162625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 11172625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov } 11182625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11192625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov const BasicBlock *LLVM_BB = BB->getBasicBlock(); 11202625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineFunction::iterator I = BB; 11212625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov ++I; 11222625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11232625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Create loop block 11242625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB); 11252625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineBasicBlock *RemBB = F->CreateMachineBasicBlock(LLVM_BB); 11262625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11272625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov F->insert(I, LoopBB); 11282625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov F->insert(I, RemBB); 11292625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11302625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Update machine-CFG edges by transferring all successors of the current 11312625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // block to the block containing instructions after shift. 113214152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman RemBB->splice(RemBB->begin(), BB, 113314152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman llvm::next(MachineBasicBlock::iterator(MI)), 113414152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BB->end()); 113514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman RemBB->transferSuccessorsAndUpdatePHIs(BB); 11362625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11372625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Add adges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB 11382625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BB->addSuccessor(LoopBB); 11392625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BB->addSuccessor(RemBB); 11402625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov LoopBB->addSuccessor(RemBB); 11412625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov LoopBB->addSuccessor(LoopBB); 11422625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 1143420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper unsigned ShiftAmtReg = RI.createVirtualRegister(&MSP430::GR8RegClass); 1144420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper unsigned ShiftAmtReg2 = RI.createVirtualRegister(&MSP430::GR8RegClass); 11452625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned ShiftReg = RI.createVirtualRegister(RC); 11462625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned ShiftReg2 = RI.createVirtualRegister(RC); 11472625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned ShiftAmtSrcReg = MI->getOperand(2).getReg(); 11482625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned SrcReg = MI->getOperand(1).getReg(); 11492625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned DstReg = MI->getOperand(0).getReg(); 11502625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11512625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // BB: 11522625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // cmp 0, N 11532625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // je RemBB 1154f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov BuildMI(BB, dl, TII.get(MSP430::CMP8ri)) 1155f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov .addReg(ShiftAmtSrcReg).addImm(0); 11562625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(BB, dl, TII.get(MSP430::JCC)) 11572625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addMBB(RemBB) 11582625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addImm(MSP430CC::COND_E); 11592625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11602625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // LoopBB: 11612625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB] 11622625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // ShiftAmt = phi [%N, BB], [%ShiftAmt2, LoopBB] 11632625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // ShiftReg2 = shift ShiftReg 11642625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // ShiftAmt2 = ShiftAmt - 1; 11652625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftReg) 11662625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(SrcReg).addMBB(BB) 11672625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftReg2).addMBB(LoopBB); 11682625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg) 11692625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftAmtSrcReg).addMBB(BB) 11702625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftAmtReg2).addMBB(LoopBB); 11712625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2) 11722625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftReg); 11732625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2) 11742625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftAmtReg).addImm(1); 11752625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::JCC)) 11762625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addMBB(LoopBB) 11772625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addImm(MSP430CC::COND_NE); 11782625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11792625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // RemBB: 11802625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB] 118114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BuildMI(*RemBB, RemBB->begin(), dl, TII.get(MSP430::PHI), DstReg) 11822625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(SrcReg).addMBB(BB) 11832625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftReg2).addMBB(LoopBB); 11842625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 118514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman MI->eraseFromParent(); // The pseudo instruction is gone now. 11862625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return RemBB; 11872625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov} 11882625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11892625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMachineBasicBlock* 11908b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 1191af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman MachineBasicBlock *BB) const { 11922625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned Opc = MI->getOpcode(); 11932625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11942625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 || 11952625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc == MSP430::Sra8 || Opc == MSP430::Sra16 || 11962625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc == MSP430::Srl8 || Opc == MSP430::Srl16) 1197af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman return EmitShiftInstr(MI, BB); 11982625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11998b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); 12008b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov DebugLoc dl = MI->getDebugLoc(); 12012625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 12022625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov assert((Opc == MSP430::Select16 || Opc == MSP430::Select8) && 12038b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov "Unexpected instr type to insert"); 12048b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 12058b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // To "insert" a SELECT instruction, we actually have to insert the diamond 12068b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // control-flow pattern. The incoming instruction knows the destination vreg 12078b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // to set, the condition code register to branch on, the true/false values to 12088b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // select between, and a branch opcode to use. 12098b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov const BasicBlock *LLVM_BB = BB->getBasicBlock(); 12108b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineFunction::iterator I = BB; 12118b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov ++I; 12128b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 12138b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // thisMBB: 12148b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // ... 12158b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // TrueVal = ... 12168b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // cmpTY ccX, r1, r2 12178b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // jCC copy1MBB 12188b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // fallthrough --> copy0MBB 12198b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *thisMBB = BB; 12208b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineFunction *F = BB->getParent(); 12218b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); 12228b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB); 12238b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov F->insert(I, copy0MBB); 12248b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov F->insert(I, copy1MBB); 12258b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Update machine-CFG edges by transferring all successors of the current 12268b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // block to the new block which will contain the Phi node for the select. 122714152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman copy1MBB->splice(copy1MBB->begin(), BB, 122814152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman llvm::next(MachineBasicBlock::iterator(MI)), 122914152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BB->end()); 123014152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman copy1MBB->transferSuccessorsAndUpdatePHIs(BB); 12318b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Next, add the true and fallthrough blocks as its successors. 12328b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy0MBB); 12338b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy1MBB); 12348b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 123514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BuildMI(BB, dl, TII.get(MSP430::JCC)) 123614152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman .addMBB(copy1MBB) 123714152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman .addImm(MI->getOperand(3).getImm()); 123814152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman 12398b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // copy0MBB: 12408b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // %FalseValue = ... 12418b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // # fallthrough to copy1MBB 12428b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB = copy0MBB; 12438b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 12448b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Update machine-CFG edges 12458b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy1MBB); 12468b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 12478b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // copy1MBB: 12488b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] 12498b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // ... 12508b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB = copy1MBB; 125114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BuildMI(*BB, BB->begin(), dl, TII.get(MSP430::PHI), 12528b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MI->getOperand(0).getReg()) 12538b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB) 12548b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB); 12558b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 125614152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman MI->eraseFromParent(); // The pseudo instruction is gone now. 12578b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov return BB; 12588b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov} 1259