MSP430ISelLowering.cpp revision ac6d9bec671252dd1e596fa71180ff6b39d06b5d
1f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//===-- MSP430ISelLowering.cpp - MSP430 DAG Lowering Implementation ------===// 2f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// 3f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// The LLVM Compiler Infrastructure 4f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// 5f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// This file is distributed under the University of Illinois Open Source 6f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// License. See LICENSE.TXT for details. 7f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// 8f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//===----------------------------------------------------------------------===// 9f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// 10f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// This file implements the MSP430TargetLowering class. 11f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// 12f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//===----------------------------------------------------------------------===// 13f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 14f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#define DEBUG_TYPE "msp430-lower" 15f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 16f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430ISelLowering.h" 17f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430.h" 1806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov#include "MSP430MachineFunctionInfo.h" 19f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430Subtarget.h" 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); 1720ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov 173b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov // Libcalls names. 174b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov if (HWMultMode == HWMultIntr) { 175b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I8, "__mulqi3hw"); 176b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I16, "__mulhi3hw"); 177b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov } else if (HWMultMode == HWMultNoIntr) { 178b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I8, "__mulqi3hw_noint"); 179b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I16, "__mulhi3hw_noint"); 180b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov } 181fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman 182fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman setMinFunctionAlignment(1); 183fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman setPrefFunctionAlignment(2); 184f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 185f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 186d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerOperation(SDValue Op, 187d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 188f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov switch (Op.getOpcode()) { 189ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov case ISD::SHL: // FALLTHROUGH 190e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case ISD::SRL: 1914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case ISD::SRA: return LowerShifts(Op, DAG); 1923513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); 19369d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); 1945d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG); 1958d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov case ISD::SETCC: return LowerSETCC(Op, DAG); 1961bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case ISD::BR_CC: return LowerBR_CC(Op, DAG); 1971bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); 198b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov case ISD::SIGN_EXTEND: return LowerSIGN_EXTEND(Op, DAG); 19906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); 20006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); 2010ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov case ISD::VASTART: return LowerVASTART(Op, DAG); 202f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov default: 203c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("unimplemented operand"); 204f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov } 205f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 206f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 207c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===// 208cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov// MSP430 Inline Assembly Support 209cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===// 210cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 211cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// getConstraintType - Given a constraint letter, return the type of 212cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// constraint it is for this target. 213cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovTargetLowering::ConstraintType 214cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering::getConstraintType(const std::string &Constraint) const { 215cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov if (Constraint.size() == 1) { 216cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov switch (Constraint[0]) { 217cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov case 'r': 218cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return C_RegisterClass; 219cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov default: 220cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov break; 221cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 222cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 223cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return TargetLowering::getConstraintType(Constraint); 224cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov} 225cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 226cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikovstd::pair<unsigned, const TargetRegisterClass*> 227cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering:: 228cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovgetRegForInlineAsmConstraint(const std::string &Constraint, 229cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov EVT VT) const { 230cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov if (Constraint.size() == 1) { 231cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov // GCC Constraint Letters 232cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov switch (Constraint[0]) { 233cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov default: break; 234cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov case 'r': // GENERAL_REGS 235cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov if (VT == MVT::i8) 236420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper return std::make_pair(0U, &MSP430::GR8RegClass); 237cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 238420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper return std::make_pair(0U, &MSP430::GR16RegClass); 239cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 240cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 241cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 242cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); 243cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov} 244cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 245cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===// 246c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// Calling Convention Implementation 247c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===// 248c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 249f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430GenCallingConv.inc" 250c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 25198ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 25298ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerFormalArguments(SDValue Chain, 25365c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, 25498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isVarArg, 25598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> 25698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Ins, 257ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, 25898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SelectionDAG &DAG, 259d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) 260d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman const { 26198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 26298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman switch (CallConv) { 263c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov default: 264c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Unsupported calling convention"); 265c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov case CallingConv::C: 266c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov case CallingConv::Fast: 26798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals); 268e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov case CallingConv::MSP430_INTR: 2694d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie if (Ins.empty()) 2704d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie return Chain; 27175361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("ISRs cannot have arguments"); 272c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 273c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov} 274c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 27598ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 276d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin HolewinskiMSP430TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, 277d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) const { 278d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SelectionDAG &DAG = CLI.DAG; 279ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc &dl = CLI.DL; 280d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs; 281d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SmallVector<SDValue, 32> &OutVals = CLI.OutVals; 282d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SmallVector<ISD::InputArg, 32> &Ins = CLI.Ins; 283d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SDValue Chain = CLI.Chain; 284d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SDValue Callee = CLI.Callee; 285d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski bool &isTailCall = CLI.IsTailCall; 286d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski CallingConv::ID CallConv = CLI.CallConv; 287d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski bool isVarArg = CLI.IsVarArg; 288d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski 2890c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng // MSP430 target does not yet support tail call optimization. 2900c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng isTailCall = false; 29198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 29298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman switch (CallConv) { 2934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov default: 294c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Unsupported calling convention"); 2954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CallingConv::Fast: 2964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CallingConv::C: 29798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall, 298c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman Outs, OutVals, Ins, dl, DAG, InVals); 299e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov case CallingConv::MSP430_INTR: 30075361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("ISRs cannot be called directly"); 3014428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 3024428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 3034428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 304c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// LowerCCCArguments - transform physical registers into virtual registers and 305c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// generate load operations for arguments places on the stack. 306c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// FIXME: struct return stuff 30798ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 30898ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCArguments(SDValue Chain, 30965c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, 31098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isVarArg, 31198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> 31298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Ins, 313ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, 31498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SelectionDAG &DAG, 315d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) 316d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman const { 317c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineFunction &MF = DAG.getMachineFunction(); 318c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 319c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineRegisterInfo &RegInfo = MF.getRegInfo(); 3200ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>(); 321c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 322c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Assign locations to all of the incoming arguments. 323c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov SmallVector<CCValAssign, 16> ArgLocs; 324471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 32556cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling getTargetMachine(), ArgLocs, *DAG.getContext()); 32698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeFormalArguments(Ins, CC_MSP430); 327c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 3280ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov // Create frame index for the start of the first vararg value 3290ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov if (isVarArg) { 3300ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov unsigned Offset = CCInfo.getNextStackOffset(); 3310ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov FuncInfo->setVarArgsFrameIndex(MFI->CreateFixedObject(1, Offset, true)); 3320ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov } 333c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 334c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 335c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov CCValAssign &VA = ArgLocs[i]; 336c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.isRegLoc()) { 337c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Arguments passed in registers 338e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT RegVT = VA.getLocVT(); 339825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson switch (RegVT.getSimpleVT().SimpleTy) { 34095771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson default: 341804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin { 342dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#ifndef NDEBUG 3434437ae213d5435390f0750213b53ec807c047f22Chris Lattner errs() << "LowerFormalArguments Unhandled argument type: " 344825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson << RegVT.getSimpleVT().SimpleTy << "\n"; 345dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#endif 346c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable(0); 347804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin } 348825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i16: 349420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper unsigned VReg = RegInfo.createVirtualRegister(&MSP430::GR16RegClass); 350c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov RegInfo.addLiveIn(VA.getLocReg(), VReg); 35198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, RegVT); 352c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 353c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // If this is an 8-bit value, it is really passed promoted to 16 354c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // bits. Insert an assert[sz]ext to capture this, then truncate to the 355c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // right size. 356c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.getLocInfo() == CCValAssign::SExt) 357c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue, 358c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov DAG.getValueType(VA.getValVT())); 359c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov else if (VA.getLocInfo() == CCValAssign::ZExt) 360c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue, 361c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov DAG.getValueType(VA.getValVT())); 362c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 363c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.getLocInfo() != CCValAssign::Full) 364c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); 365c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 36698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman InVals.push_back(ArgValue); 367c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 368c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } else { 369c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Sanity check 370c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov assert(VA.isMemLoc()); 3716cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov 3726cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov SDValue InVal; 3736cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov ISD::ArgFlagsTy Flags = Ins[i].Flags; 3746cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov 3756cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov if (Flags.isByVal()) { 3766cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov int FI = MFI->CreateFixedObject(Flags.getByValSize(), 3776cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov VA.getLocMemOffset(), true); 3786cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov InVal = DAG.getFrameIndex(FI, getPointerTy()); 3796cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov } else { 3806cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov // Load the argument to a virtual register 3816cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov unsigned ObjSize = VA.getLocVT().getSizeInBits()/8; 3826cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov if (ObjSize > 2) { 3836cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov errs() << "LowerFormalArguments Unhandled argument type: " 3846cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov << EVT(VA.getLocVT()).getEVTString() 3856cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov << "\n"; 3866cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov } 3876cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov // Create the frame index object for this incoming parameter... 3886cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true); 3896cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov 3906cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov // Create the SelectionDAG nodes corresponding to a load 3916cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov //from this parameter 3926cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov SDValue FIN = DAG.getFrameIndex(FI, MVT::i16); 3936cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov InVal = DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, 3946cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov MachinePointerInfo::getFixedStack(FI), 3956cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov false, false, false, 0); 396c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 3976cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov 3986cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov InVals.push_back(InVal); 399c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 400c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 401c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 40298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return Chain; 403c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov} 404fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 40598ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 40698ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerReturn(SDValue Chain, 40765c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 40898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::OutputArg> &Outs, 409c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman const SmallVectorImpl<SDValue> &OutVals, 410ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, SelectionDAG &DAG) const { 41198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 412fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // CCValAssign - represent the assignment of the return value to a location 413fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov SmallVector<CCValAssign, 16> RVLocs; 414fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 415e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov // ISRs cannot return any value. 4164d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie if (CallConv == CallingConv::MSP430_INTR && !Outs.empty()) 41775361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("ISRs cannot return any value"); 418e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov 419fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // CCState - Info about the registers and stack slot. 420471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 42156cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling getTargetMachine(), RVLocs, *DAG.getContext()); 422fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 42398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman // Analize return values. 42498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeReturn(Outs, RetCC_MSP430); 425fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 426fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov SDValue Flag; 427294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen SmallVector<SDValue, 4> RetOps(1, Chain); 428fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 429fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // Copy the result values into the output registers. 430fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov for (unsigned i = 0; i != RVLocs.size(); ++i) { 431fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov CCValAssign &VA = RVLocs[i]; 432fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov assert(VA.isRegLoc() && "Can only return in registers!"); 433fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 434fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), 435c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman OutVals[i], Flag); 436fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 437dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov // Guarantee that all emitted copies are stuck together, 438dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov // avoiding something bad. 439fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov Flag = Chain.getValue(1); 440294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); 441fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 442fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 443e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov unsigned Opc = (CallConv == CallingConv::MSP430_INTR ? 444e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG); 445e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov 446294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen RetOps[0] = Chain; // Update chain. 447294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen 448294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen // Add the flag if we have it. 449fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (Flag.getNode()) 450294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen RetOps.push_back(Flag); 451fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 452294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen return DAG.getNode(Opc, dl, MVT::Other, &RetOps[0], RetOps.size()); 453fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov} 454fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 4554428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// LowerCCCCallTo - functions arguments are copied from virtual regs to 4564428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted. 4574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// TODO: sret. 45898ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 45998ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, 46065c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 46198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isTailCall, 46298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::OutputArg> 46398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Outs, 464c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman const SmallVectorImpl<SDValue> &OutVals, 46598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> &Ins, 466ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, SelectionDAG &DAG, 467d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) const { 4684428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Analyze operands of the call, assigning locations to each operand. 4694428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<CCValAssign, 16> ArgLocs; 470471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 47156cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling getTargetMachine(), ArgLocs, *DAG.getContext()); 4724428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 47398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeCallOperands(Outs, CC_MSP430); 4744428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4754428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Get a count of how many bytes are to be pushed on the stack. 4764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov unsigned NumBytes = CCInfo.getNextStackOffset(); 4774428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCALLSEQ_START(Chain ,DAG.getConstant(NumBytes, 4794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov getPointerTy(), true)); 4804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4814428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass; 4824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<SDValue, 12> MemOpChains; 4834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue StackPtr; 4844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Walk the register/memloc assignments, inserting copies/loads. 4864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 4874428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov CCValAssign &VA = ArgLocs[i]; 4884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 489c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman SDValue Arg = OutVals[i]; 4904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Promote the value if needed. 4924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov switch (VA.getLocInfo()) { 493c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Unknown loc info!"); 4944428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::Full: break; 4954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::SExt: 4964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); 4974428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 4984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::ZExt: 4994428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg); 5004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 5014428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::AExt: 5024428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); 5034428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 5044428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 5054428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5064428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Arguments that can be passed on register must be kept at RegsToPass 5074428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // vector 5084428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (VA.isRegLoc()) { 5094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 5104428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } else { 5114428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov assert(VA.isMemLoc()); 5124428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5134428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (StackPtr.getNode() == 0) 5144428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SPW, getPointerTy()); 5154428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), 5174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov StackPtr, 5184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG.getIntPtrConstant(VA.getLocMemOffset())); 5194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5206cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov SDValue MemOp; 5216cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov ISD::ArgFlagsTy Flags = Outs[i].Flags; 5226cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov 5236cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov if (Flags.isByVal()) { 5246cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), MVT::i16); 5256cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov MemOp = DAG.getMemcpy(Chain, dl, PtrOff, Arg, SizeNode, 5266cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov Flags.getByValAlign(), 5276cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov /*isVolatile*/false, 5286cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov /*AlwaysInline=*/true, 5296cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov MachinePointerInfo(), 5306cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov MachinePointerInfo()); 5316cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov } else { 5326cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov MemOp = DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo(), 5336cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov false, false, 0); 5346cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov } 5354428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5366cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov MemOpChains.push_back(MemOp); 5374428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 5384428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 5394428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5404428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Transform all store nodes into one single node because all store nodes are 5414428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // independent of each other. 5424428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (!MemOpChains.empty()) 543825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 5444428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov &MemOpChains[0], MemOpChains.size()); 5454428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5464428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Build a sequence of copy-to-reg nodes chained together with token chain and 5474428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // flag operands which copy the outgoing args into registers. The InFlag in 5487a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // necessary since all emitted instructions must be stuck together. 5494428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue InFlag; 5504428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 5514428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, 5524428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RegsToPass[i].second, InFlag); 5534428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(1); 5544428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 5554428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5564428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // If the callee is a GlobalAddress node (quite common, every direct call is) 5574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 5584428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Likewise ExternalSymbol -> TargetExternalSymbol. 5594428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 5600d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i16); 5614428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) 562825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i16); 5634428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5644428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Returns a chain & a flag for retval copy to use. 565f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 5664428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<SDValue, 8> Ops; 5674428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(Chain); 5684428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(Callee); 5694428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5704428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Add argument registers to the end of the list so that they are 5714428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // known live into the call. 5724428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 5734428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(DAG.getRegister(RegsToPass[i].first, 5744428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RegsToPass[i].second.getValueType())); 5754428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (InFlag.getNode()) 5774428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(InFlag); 5784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getNode(MSP430ISD::CALL, dl, NodeTys, &Ops[0], Ops.size()); 5804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(1); 5814428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Create the CALLSEQ_END node. 5834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCALLSEQ_END(Chain, 5844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG.getConstant(NumBytes, getPointerTy(), true), 5854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG.getConstant(0, getPointerTy(), true), 5864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag); 5874428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(1); 5884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Handle result values, copying them out of physregs into vregs that we 5904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // return. 59198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl, 59298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DAG, InVals); 5934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 5944428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 59598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// LowerCallResult - Lower the result values of a call into the 59698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// appropriate copies out of appropriate physical registers. 59798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// 59898ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 5994428885c5acfffbbdd03ad2aab23960531c47753Anton KorobeynikovMSP430TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, 60065c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 60198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> &Ins, 602ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, SelectionDAG &DAG, 603d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) const { 6044428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 6054428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Assign locations to each value returned by this call. 6064428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<CCValAssign, 16> RVLocs; 607471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 60856cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling getTargetMachine(), RVLocs, *DAG.getContext()); 6094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 61098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeCallResult(Ins, RetCC_MSP430); 6114428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 6124428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Copy all of the result registers out of their specified physreg. 6134428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0; i != RVLocs.size(); ++i) { 6144428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(), 6154428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RVLocs[i].getValVT(), InFlag).getValue(1); 6164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(2); 61798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman InVals.push_back(Chain.getValue(0)); 6184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 6194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 62098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return Chain; 6214428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 6224428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 623d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton KorobeynikovSDValue MSP430TargetLowering::LowerShifts(SDValue Op, 624d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 625ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov unsigned Opc = Op.getOpcode(); 626d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov SDNode* N = Op.getNode(); 627e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Op.getValueType(); 628ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(N); 629d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 6302625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Expand non-constant shifts to loops: 631d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov if (!isa<ConstantSDNode>(N->getOperand(1))) 6322625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov switch (Opc) { 633bc2198133a1836598b54b943420748e75d5dea94Craig Topper default: llvm_unreachable("Invalid shift opcode!"); 6342625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case ISD::SHL: 6352625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return DAG.getNode(MSP430ISD::SHL, dl, 6362625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov VT, N->getOperand(0), N->getOperand(1)); 6372625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case ISD::SRA: 6382625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return DAG.getNode(MSP430ISD::SRA, dl, 6392625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov VT, N->getOperand(0), N->getOperand(1)); 6402625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case ISD::SRL: 6412625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return DAG.getNode(MSP430ISD::SRL, dl, 6422625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov VT, N->getOperand(0), N->getOperand(1)); 6432625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov } 644d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 645d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue(); 646d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 647d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // Expand the stuff into sequence of shifts. 648d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // FIXME: for some shift amounts this might be done better! 649d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N 650d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov SDValue Victim = N->getOperand(0); 651e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov 652e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov if (Opc == ISD::SRL && ShiftAmount) { 653e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov // Emit a special goodness here: 654e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov // srl A, 1 => clrc; rrc A 655bf8ef3f29de28529b5d65970af9015c41f7c809bAnton Korobeynikov Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim); 656e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov ShiftAmount -= 1; 657e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov } 658e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov 659d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov while (ShiftAmount--) 660aceb620de855485a4fb2eed343d880d76f6c701cAnton Korobeynikov Victim = DAG.getNode((Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA), 661ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov dl, VT, Victim); 662d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 663d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov return Victim; 664d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov} 665d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 666d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerGlobalAddress(SDValue Op, 667d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 6683513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); 6693513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset(); 6703513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov 6713513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov // Create the TargetGlobalAddress node, folding in the constant offset. 672ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDValue Result = DAG.getTargetGlobalAddress(GV, SDLoc(Op), 6730d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel getPointerTy(), Offset); 674ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick return DAG.getNode(MSP430ISD::Wrapper, SDLoc(Op), 6753513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov getPointerTy(), Result); 6763513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov} 6773513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov 6785d59f68ade7573175f1ace09061a94286e59076bAnton KorobeynikovSDValue MSP430TargetLowering::LowerExternalSymbol(SDValue Op, 679d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 680ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 6815d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol(); 6825d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov SDValue Result = DAG.getTargetExternalSymbol(Sym, getPointerTy()); 6835d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov 68490f20044ade3712c8b0c3f4ebe47d57ad15ae6ceChad Rosier return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result); 6855d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov} 6865d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov 68769d5b48bc31b7a443355cdf1506005804b4f63e6Anton KorobeynikovSDValue MSP430TargetLowering::LowerBlockAddress(SDValue Op, 68869d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov SelectionDAG &DAG) const { 689ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 69069d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress(); 6916c7ccaa3fd1d6e96d0bf922554b09d2b17c3b0e3Michael Liao SDValue Result = DAG.getTargetBlockAddress(BA, getPointerTy()); 69269d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov 69390f20044ade3712c8b0c3f4ebe47d57ad15ae6ceChad Rosier return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result); 69469d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov} 69569d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov 6963926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikovstatic SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC, 6971bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC, 698ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, SelectionDAG &DAG) { 699ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov // FIXME: Handle bittests someday 700ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet"); 701ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 702ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov // FIXME: Handle jump negative someday 7033926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov MSP430CC::CondCodes TCC = MSP430CC::COND_INVALID; 704ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov switch (CC) { 705c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Invalid integer condition!"); 706ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETEQ: 7073926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_E; // aka COND_Z 708f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov // Minor optimization: if LHS is a constant, swap operands, then the 7091722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov // constant can be folded into comparison. 710f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov if (LHS.getOpcode() == ISD::Constant) 7111722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov std::swap(LHS, RHS); 712ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 713ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETNE: 7143926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_NE; // aka COND_NZ 715f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov // Minor optimization: if LHS is a constant, swap operands, then the 7161722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov // constant can be folded into comparison. 717f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov if (LHS.getOpcode() == ISD::Constant) 7181722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov std::swap(LHS, RHS); 719ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 720ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETULE: 721ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 722ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETUGE: 7230c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // Turn lhs u>= rhs with lhs constant into rhs u< lhs+1, this allows us to 7240c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // fold constant into instruction. 7250c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 7260c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov LHS = RHS; 7270c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 7280c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_LO; 7290c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov break; 7300c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov } 7313926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_HS; // aka COND_C 732ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 733ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETUGT: 734ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 735ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETULT: 7360c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // Turn lhs u< rhs with lhs constant into rhs u>= lhs+1, this allows us to 7370c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // fold constant into instruction. 7380c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 7390c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov LHS = RHS; 7400c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 7410c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_HS; 7420c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov break; 7430c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov } 7443926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_LO; // aka COND_NC 745ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 746ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETLE: 747ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 748ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETGE: 7490c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // Turn lhs >= rhs with lhs constant into rhs < lhs+1, this allows us to 7500c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // fold constant into instruction. 7510c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 7520c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov LHS = RHS; 7530c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 7540c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_L; 7550c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov break; 7560c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov } 7573926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_GE; 758ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 759ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETGT: 760ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 761ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETLT: 7620c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to 7630c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // fold constant into instruction. 7640c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 7650c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov LHS = RHS; 7660c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 7670c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_GE; 7680c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov break; 7690c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov } 7703926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_L; 771ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 772ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov } 773ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 7743926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TargetCC = DAG.getConstant(TCC, MVT::i8); 775f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner return DAG.getNode(MSP430ISD::CMP, dl, MVT::Glue, LHS, RHS); 776ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov} 777ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 7781bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 779d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const { 780ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov SDValue Chain = Op.getOperand(0); 7811bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); 7821bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue LHS = Op.getOperand(2); 7831bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue RHS = Op.getOperand(3); 7841bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Dest = Op.getOperand(4); 785ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl (Op); 7861bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 7873926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov SDValue TargetCC; 7881bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 7891bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 7901bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(), 7913926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov Chain, Dest, TargetCC, Flag); 792ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov} 793ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 794d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const { 7958d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue LHS = Op.getOperand(0); 7968d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue RHS = Op.getOperand(1); 797ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl (Op); 7988d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov 7998d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // If we are doing an AND and testing against zero, then the CMP 8008d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // will not be generated. The AND (or BIT) will generate the condition codes, 8018d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // but they are different from CMP. 802cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov // FIXME: since we're doing a post-processing, use a pseudoinstr here, so 803cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov // lowering & isel wouldn't diverge. 8048d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov bool andCC = false; 8058d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) { 8068d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (RHSC->isNullValue() && LHS.hasOneUse() && 8078d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov (LHS.getOpcode() == ISD::AND || 8088d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov (LHS.getOpcode() == ISD::TRUNCATE && 8098d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov LHS.getOperand(0).getOpcode() == ISD::AND))) { 8108d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov andCC = true; 8118d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 8128d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 8138d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get(); 8148d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue TargetCC; 8158d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 8168d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov 8178d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Get the condition codes directly from the status register, if its easy. 8188d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Otherwise a branch will be generated. Note that the AND and BIT 8198d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // instructions generate different flags than CMP, the carry bit can be used 8208d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // for NE/EQ. 8218d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov bool Invert = false; 8228d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov bool Shift = false; 8238d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov bool Convert = true; 8248d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov switch (cast<ConstantSDNode>(TargetCC)->getZExtValue()) { 8258d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov default: 8268d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Convert = false; 8278d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 8288d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov case MSP430CC::COND_HS: 8298d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Res = SRW & 1, no processing is required 8308d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 831cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov case MSP430CC::COND_LO: 8328d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Res = ~(SRW & 1) 8338d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Invert = true; 8348d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 835cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov case MSP430CC::COND_NE: 8368d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (andCC) { 8378d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // C = ~Z, thus Res = SRW & 1, no processing is required 8388d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } else { 839455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov // Res = ~((SRW >> 1) & 1) 8408d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Shift = true; 841455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov Invert = true; 8428d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 8438d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 844cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov case MSP430CC::COND_E: 845455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov Shift = true; 846455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov // C = ~Z for AND instruction, thus we can put Res = ~(SRW & 1), however, 847455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov // Res = (SRW >> 1) & 1 is 1 word shorter. 8488d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 8498d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 8508d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov EVT VT = Op.getValueType(); 8518d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue One = DAG.getConstant(1, VT); 8528d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (Convert) { 8538d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SRW, 854cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov MVT::i16, Flag); 8558d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (Shift) 8568d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // FIXME: somewhere this is turned into a SRL, lower it MSP specific? 8578d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One); 8588d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SR = DAG.getNode(ISD::AND, dl, MVT::i16, SR, One); 8598d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (Invert) 8608d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SR = DAG.getNode(ISD::XOR, dl, MVT::i16, SR, One); 8618d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov return SR; 8628d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } else { 8638d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue Zero = DAG.getConstant(0, VT); 864f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue); 8658d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SmallVector<SDValue, 4> Ops; 8668d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Ops.push_back(One); 8678d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Ops.push_back(Zero); 8688d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Ops.push_back(TargetCC); 8698d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Ops.push_back(Flag); 8708d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size()); 8718d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 8728d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov} 8738d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov 874d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op, 875d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 8761bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue LHS = Op.getOperand(0); 8771bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue RHS = Op.getOperand(1); 8781bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue TrueV = Op.getOperand(2); 8791bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue FalseV = Op.getOperand(3); 8801bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); 881ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl (Op); 8821bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 8833926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov SDValue TargetCC; 8841bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 8858b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 886f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue); 8878b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov SmallVector<SDValue, 4> Ops; 8888b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov Ops.push_back(TrueV); 8898b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov Ops.push_back(FalseV); 8903926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov Ops.push_back(TargetCC); 8911bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov Ops.push_back(Flag); 8928b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 8931bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size()); 8948b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov} 8958b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 896b78e214274d397407b6167a293b7cd7c3b526ddeAnton KorobeynikovSDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op, 897d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 898b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov SDValue Val = Op.getOperand(0); 899e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Op.getValueType(); 900ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 901b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 902825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson assert(VT == MVT::i16 && "Only support i16 for now!"); 903b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 904b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT, 905b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val), 906b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov DAG.getValueType(Val.getValueType())); 907b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov} 908b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 909d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue 910d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanMSP430TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) const { 91106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MachineFunction &MF = DAG.getMachineFunction(); 91206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>(); 91306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov int ReturnAddrIndex = FuncInfo->getRAIndex(); 91406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 91506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov if (ReturnAddrIndex == 0) { 91606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov // Set up a frame object for the return address. 917426c2bf5cdd2173e4a33aea8cb92cf684a724f4bChandler Carruth uint64_t SlotSize = TD->getPointerSize(); 91806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(SlotSize, -SlotSize, 919ed2ae136d29dd36122d2476801e7d7a86e8301e3Evan Cheng true); 92006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov FuncInfo->setRAIndex(ReturnAddrIndex); 92106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov } 92206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 92306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy()); 92406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov} 92506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 926d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op, 927d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 9282457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 9292457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng MFI->setReturnAddressIsTaken(true); 9302457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng 93106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); 932ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 93306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 93406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov if (Depth > 0) { 93506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue FrameAddr = LowerFRAMEADDR(Op, DAG); 93606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue Offset = 937426c2bf5cdd2173e4a33aea8cb92cf684a724f4bChandler Carruth DAG.getConstant(TD->getPointerSize(), MVT::i16); 93806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), 93906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov DAG.getNode(ISD::ADD, dl, getPointerTy(), 94006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov FrameAddr, Offset), 941d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper MachinePointerInfo(), false, false, false, 0); 94206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov } 94306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 94406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov // Just load the return address. 94506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue RetAddrFI = getReturnAddressFrameIndex(DAG); 94606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), 947d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper RetAddrFI, MachinePointerInfo(), false, false, false, 0); 94806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov} 94906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 950d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op, 951d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 95206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 95306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MFI->setFrameAddressIsTaken(true); 9542457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng 95506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov EVT VT = Op.getValueType(); 956ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); // FIXME probably not meaningful 95706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); 95806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, 95906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MSP430::FPW, VT); 96006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov while (Depth--) 961d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr, 962d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner MachinePointerInfo(), 963d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper false, false, false, 0); 96406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return FrameAddr; 96506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov} 96606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 9670ae61240341ca76e1329f251c64d2f475fa89278Anton KorobeynikovSDValue MSP430TargetLowering::LowerVASTART(SDValue Op, 9680ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov SelectionDAG &DAG) const { 9690ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov MachineFunction &MF = DAG.getMachineFunction(); 9700ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>(); 9710ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov 9720ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov // Frame index of first vararg argument 9730ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov SDValue FrameIndex = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), 9740ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov getPointerTy()); 9750ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); 9760ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov 9770ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov // Create a store of the frame index to the location operand 978ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick return DAG.getStore(Op.getOperand(0), SDLoc(Op), FrameIndex, 9790ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov Op.getOperand(1), MachinePointerInfo(SV), 9800ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov false, false, 0); 9810ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov} 9820ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov 9836534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// getPostIndexedAddressParts - returns true by value, base pointer and 9846534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// offset pointer and addressing mode by reference if this node can be 9856534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// combined with a load / store to form a post-indexed load / store. 9866534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikovbool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op, 9876534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SDValue &Base, 9886534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SDValue &Offset, 9896534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov ISD::MemIndexedMode &AM, 9906534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SelectionDAG &DAG) const { 9916534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 9926534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov LoadSDNode *LD = cast<LoadSDNode>(N); 9936534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (LD->getExtensionType() != ISD::NON_EXTLOAD) 9946534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 9956534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 9966534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov EVT VT = LD->getMemoryVT(); 9976534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (VT != MVT::i8 && VT != MVT::i16) 9986534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 9996534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 10006534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (Op->getOpcode() != ISD::ADD) 10016534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 10026534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 10036534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) { 10046534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov uint64_t RHSC = RHS->getZExtValue(); 10056534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if ((VT == MVT::i16 && RHSC != 2) || 10066534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov (VT == MVT::i8 && RHSC != 1)) 10076534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 10086534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 10096534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov Base = Op->getOperand(0); 10106534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov Offset = DAG.getConstant(RHSC, VT); 10116534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov AM = ISD::POST_INC; 10126534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return true; 10136534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov } 10146534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 10156534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 10166534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov} 10176534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 10186534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 1019fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikovconst char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const { 1020fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov switch (Opcode) { 1021fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov default: return NULL; 1022fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov case MSP430ISD::RET_FLAG: return "MSP430ISD::RET_FLAG"; 10236bfcba7e137113e5f38cc4f937ad61cc7253ec74Anton Korobeynikov case MSP430ISD::RETI_FLAG: return "MSP430ISD::RETI_FLAG"; 1024d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov case MSP430ISD::RRA: return "MSP430ISD::RRA"; 1025e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case MSP430ISD::RLA: return "MSP430ISD::RLA"; 1026e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case MSP430ISD::RRC: return "MSP430ISD::RRC"; 1027b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov case MSP430ISD::CALL: return "MSP430ISD::CALL"; 10283513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov case MSP430ISD::Wrapper: return "MSP430ISD::Wrapper"; 10291bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case MSP430ISD::BR_CC: return "MSP430ISD::BR_CC"; 1030ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case MSP430ISD::CMP: return "MSP430ISD::CMP"; 10311bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case MSP430ISD::SELECT_CC: return "MSP430ISD::SELECT_CC"; 10322625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430ISD::SHL: return "MSP430ISD::SHL"; 10332625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430ISD::SRA: return "MSP430ISD::SRA"; 1034fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 1035fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov} 10368b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 1037db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattnerbool MSP430TargetLowering::isTruncateFree(Type *Ty1, 1038db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *Ty2) const { 1039b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy()) 10409afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return false; 10419afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 10429afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return (Ty1->getPrimitiveSizeInBits() > Ty2->getPrimitiveSizeInBits()); 10439afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov} 10449afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 10459afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikovbool MSP430TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const { 10469afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov if (!VT1.isInteger() || !VT2.isInteger()) 10479afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return false; 10489afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 10499afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return (VT1.getSizeInBits() > VT2.getSizeInBits()); 10509afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov} 10519afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 1052db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattnerbool MSP430TargetLowering::isZExtFree(Type *Ty1, Type *Ty2) const { 10539afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov // MSP430 implicitly zero-extends 8-bit results in 16-bit registers. 1054b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands return 0 && Ty1->isIntegerTy(8) && Ty2->isIntegerTy(16); 10559afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov} 10569afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 10579afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikovbool MSP430TargetLowering::isZExtFree(EVT VT1, EVT VT2) const { 10589afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov // MSP430 implicitly zero-extends 8-bit results in 16-bit registers. 10599afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return 0 && VT1 == MVT::i8 && VT2 == MVT::i16; 10609afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov} 10619afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 1062968b667e27d7fc9a5bf5da52191a7af629e174dcEli Benderskybool MSP430TargetLowering::isZExtFree(SDValue Val, EVT VT2) const { 1063968b667e27d7fc9a5bf5da52191a7af629e174dcEli Bendersky return isZExtFree(Val.getValueType(), VT2); 1064968b667e27d7fc9a5bf5da52191a7af629e174dcEli Bendersky} 1065968b667e27d7fc9a5bf5da52191a7af629e174dcEli Bendersky 10668b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===// 10678b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov// Other Lowering Code 10688b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===// 10698b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 10708b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMachineBasicBlock* 10712625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMSP430TargetLowering::EmitShiftInstr(MachineInstr *MI, 1072af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman MachineBasicBlock *BB) const { 10732625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineFunction *F = BB->getParent(); 10742625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineRegisterInfo &RI = F->getRegInfo(); 10752625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov DebugLoc dl = MI->getDebugLoc(); 10762625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); 10772625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10782625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned Opc; 10792625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov const TargetRegisterClass * RC; 10802625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov switch (MI->getOpcode()) { 1081bc2198133a1836598b54b943420748e75d5dea94Craig Topper default: llvm_unreachable("Invalid shift opcode!"); 10822625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Shl8: 10832625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SHL8r1; 1084420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR8RegClass; 10852625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 10862625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Shl16: 10872625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SHL16r1; 1088420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR16RegClass; 10892625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 10902625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Sra8: 10912625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR8r1; 1092420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR8RegClass; 10932625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 10942625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Sra16: 10952625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR16r1; 1096420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR16RegClass; 10972625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 10982625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Srl8: 10992625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR8r1c; 1100420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR8RegClass; 11012625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 11022625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Srl16: 11032625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR16r1c; 1104420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR16RegClass; 11052625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 11062625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov } 11072625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11082625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov const BasicBlock *LLVM_BB = BB->getBasicBlock(); 11092625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineFunction::iterator I = BB; 11102625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov ++I; 11112625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11122625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Create loop block 11132625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB); 11142625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineBasicBlock *RemBB = F->CreateMachineBasicBlock(LLVM_BB); 11152625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11162625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov F->insert(I, LoopBB); 11172625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov F->insert(I, RemBB); 11182625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11192625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Update machine-CFG edges by transferring all successors of the current 11202625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // block to the block containing instructions after shift. 112114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman RemBB->splice(RemBB->begin(), BB, 112214152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman llvm::next(MachineBasicBlock::iterator(MI)), 112314152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BB->end()); 112414152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman RemBB->transferSuccessorsAndUpdatePHIs(BB); 11252625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11262625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Add adges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB 11272625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BB->addSuccessor(LoopBB); 11282625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BB->addSuccessor(RemBB); 11292625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov LoopBB->addSuccessor(RemBB); 11302625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov LoopBB->addSuccessor(LoopBB); 11312625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 1132420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper unsigned ShiftAmtReg = RI.createVirtualRegister(&MSP430::GR8RegClass); 1133420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper unsigned ShiftAmtReg2 = RI.createVirtualRegister(&MSP430::GR8RegClass); 11342625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned ShiftReg = RI.createVirtualRegister(RC); 11352625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned ShiftReg2 = RI.createVirtualRegister(RC); 11362625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned ShiftAmtSrcReg = MI->getOperand(2).getReg(); 11372625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned SrcReg = MI->getOperand(1).getReg(); 11382625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned DstReg = MI->getOperand(0).getReg(); 11392625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11402625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // BB: 11412625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // cmp 0, N 11422625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // je RemBB 1143f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov BuildMI(BB, dl, TII.get(MSP430::CMP8ri)) 1144f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov .addReg(ShiftAmtSrcReg).addImm(0); 11452625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(BB, dl, TII.get(MSP430::JCC)) 11462625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addMBB(RemBB) 11472625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addImm(MSP430CC::COND_E); 11482625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11492625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // LoopBB: 11502625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB] 11512625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // ShiftAmt = phi [%N, BB], [%ShiftAmt2, LoopBB] 11522625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // ShiftReg2 = shift ShiftReg 11532625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // ShiftAmt2 = ShiftAmt - 1; 11542625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftReg) 11552625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(SrcReg).addMBB(BB) 11562625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftReg2).addMBB(LoopBB); 11572625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg) 11582625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftAmtSrcReg).addMBB(BB) 11592625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftAmtReg2).addMBB(LoopBB); 11602625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2) 11612625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftReg); 11622625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2) 11632625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftAmtReg).addImm(1); 11642625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::JCC)) 11652625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addMBB(LoopBB) 11662625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addImm(MSP430CC::COND_NE); 11672625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11682625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // RemBB: 11692625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB] 117014152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BuildMI(*RemBB, RemBB->begin(), dl, TII.get(MSP430::PHI), DstReg) 11712625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(SrcReg).addMBB(BB) 11722625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftReg2).addMBB(LoopBB); 11732625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 117414152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman MI->eraseFromParent(); // The pseudo instruction is gone now. 11752625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return RemBB; 11762625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov} 11772625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11782625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMachineBasicBlock* 11798b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 1180af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman MachineBasicBlock *BB) const { 11812625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned Opc = MI->getOpcode(); 11822625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11832625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 || 11842625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc == MSP430::Sra8 || Opc == MSP430::Sra16 || 11852625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc == MSP430::Srl8 || Opc == MSP430::Srl16) 1186af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman return EmitShiftInstr(MI, BB); 11872625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11888b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); 11898b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov DebugLoc dl = MI->getDebugLoc(); 11902625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11912625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov assert((Opc == MSP430::Select16 || Opc == MSP430::Select8) && 11928b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov "Unexpected instr type to insert"); 11938b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 11948b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // To "insert" a SELECT instruction, we actually have to insert the diamond 11958b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // control-flow pattern. The incoming instruction knows the destination vreg 11968b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // to set, the condition code register to branch on, the true/false values to 11978b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // select between, and a branch opcode to use. 11988b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov const BasicBlock *LLVM_BB = BB->getBasicBlock(); 11998b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineFunction::iterator I = BB; 12008b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov ++I; 12018b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 12028b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // thisMBB: 12038b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // ... 12048b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // TrueVal = ... 12058b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // cmpTY ccX, r1, r2 12068b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // jCC copy1MBB 12078b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // fallthrough --> copy0MBB 12088b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *thisMBB = BB; 12098b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineFunction *F = BB->getParent(); 12108b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); 12118b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB); 12128b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov F->insert(I, copy0MBB); 12138b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov F->insert(I, copy1MBB); 12148b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Update machine-CFG edges by transferring all successors of the current 12158b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // block to the new block which will contain the Phi node for the select. 121614152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman copy1MBB->splice(copy1MBB->begin(), BB, 121714152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman llvm::next(MachineBasicBlock::iterator(MI)), 121814152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BB->end()); 121914152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman copy1MBB->transferSuccessorsAndUpdatePHIs(BB); 12208b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Next, add the true and fallthrough blocks as its successors. 12218b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy0MBB); 12228b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy1MBB); 12238b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 122414152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BuildMI(BB, dl, TII.get(MSP430::JCC)) 122514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman .addMBB(copy1MBB) 122614152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman .addImm(MI->getOperand(3).getImm()); 122714152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman 12288b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // copy0MBB: 12298b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // %FalseValue = ... 12308b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // # fallthrough to copy1MBB 12318b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB = copy0MBB; 12328b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 12338b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Update machine-CFG edges 12348b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy1MBB); 12358b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 12368b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // copy1MBB: 12378b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] 12388b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // ... 12398b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB = copy1MBB; 124014152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BuildMI(*BB, BB->begin(), dl, TII.get(MSP430::PHI), 12418b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MI->getOperand(0).getReg()) 12428b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB) 12438b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB); 12448b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 124514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman MI->eraseFromParent(); // The pseudo instruction is gone now. 12468b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov return BB; 12478b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov} 1248