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" 20f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#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" 27f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 28f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/ValueTypes.h" 29f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/IR/CallingConv.h" 30f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/IR/DerivedTypes.h" 31f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/IR/Function.h" 32c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov#include "llvm/IR/GlobalAlias.h" 33f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/IR/GlobalVariable.h" 34362dd0bef5437f85586c046bc53287b6fbe9c099Anton Korobeynikov#include "llvm/IR/Intrinsics.h" 35f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/Support/CommandLine.h" 36b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov#include "llvm/Support/Debug.h" 37f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/Support/ErrorHandling.h" 38804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin#include "llvm/Support/raw_ostream.h" 394437ae213d5435390f0750213b53ec807c047f22Chris Lattnerusing namespace llvm; 40f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 41f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovtypedef enum { 42f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton 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 60b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton KorobeynikovMSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) : 61b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov TargetLowering(tm, new TargetLoweringObjectFileELF()), 62f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov Subtarget(*tm.getSubtargetImpl()) { 63f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner 64f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner TD = getDataLayout(); 65f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 6606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov // Set up the register classes. 6706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov addRegisterClass(MVT::i8, &MSP430::GR8RegClass); 68f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov addRegisterClass(MVT::i16, &MSP430::GR16RegClass); 69825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 70825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson // Compute derived properties from the register classes 71f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov computeRegisterProperties(); 72f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 73f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov // Provide all sorts of operation actions 74fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 751476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov // Division is expensive 761476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov setIntDivIsCheap(false); 771476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov 781476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov setStackPointerRegisterToSaveRestore(MSP430::SPW); 791476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov setBooleanContents(ZeroOrOneBooleanContent); 80d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct? 81d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 82825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson // We have post-incremented loads / stores. 83d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov setIndexedLoadAction(ISD::POST_INC, MVT::i8, Legal); 84c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov setIndexedLoadAction(ISD::POST_INC, MVT::i16, Legal); 85c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov 86211ffa13519cadfb7f9baf4c8447fa055bf38fe8Evan Cheng setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); 87c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); 8806ac0820a6cefa6896000054d8e4906326c0cce6Anton Korobeynikov setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); 896534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Expand); 906534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Expand); 916534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 926534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov // We don't have any truncstores 936534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setTruncStoreAction(MVT::i16, MVT::i8, Expand); 946534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 956534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setOperationAction(ISD::SRA, MVT::i8, Custom); 96825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SHL, MVT::i8, Custom); 9736b6e533c1aac85452438161f7034a9f54bd1830Anton Korobeynikov setOperationAction(ISD::SRL, MVT::i8, Custom); 9854f30d3fc94e055f13e6744378323d05c5c050baAnton Korobeynikov 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); 107825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 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); 112825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SETCC, MVT::i8, Custom); 11369d5b48bc31b7a443355cdf1506005804b4f63e6Anton 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); 1188d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov setOperationAction(ISD::SIGN_EXTEND, MVT::i16, Custom); 1198d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i8, Expand); 120825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 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); 124825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i8, Expand); 125379a087cc7175532ff0c24c60069da5eec596879Anton Korobeynikov setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i16, Expand); 126379a087cc7175532ff0c24c60069da5eec596879Anton Korobeynikov setOperationAction(ISD::CTLZ, MVT::i8, Expand); 127825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTLZ, MVT::i16, Expand); 128825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i8, Expand); 129825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 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); 141825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 142825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson // FIXME: Implement efficiently multiplication by a constant 143e4ce880dfa340bf45ddce10bb1dbe856553677b6Eli Friedman setOperationAction(ISD::MUL, MVT::i8, Expand); 1448725bd22bf91c29e2351a127295c19fea996e2c7Anton 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); 1488983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::MUL, MVT::i16, Expand); 1498983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov 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 154825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UDIV, MVT::i8, Expand); 155825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 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); 1608983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::UDIV, MVT::i16, Expand); 1618983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov 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); 166825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 167825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson // varargs support 168b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setOperationAction(ISD::VASTART, MVT::Other, Custom); 169b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setOperationAction(ISD::VAARG, MVT::Other, Expand); 170b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setOperationAction(ISD::VAEND, MVT::Other, Expand); 171b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setOperationAction(ISD::VACOPY, MVT::Other, Expand); 172b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov 173b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov // Libcalls names. 174b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov if (HWMultMode == HWMultIntr) { 175b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I8, "__mulqi3hw"); 176b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I16, "__mulhi3hw"); 177f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov } else if (HWMultMode == HWMultNoIntr) { 178f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov setLibcallName(RTLIB::MUL_I8, "__mulqi3hw_noint"); 179d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman setLibcallName(RTLIB::MUL_I16, "__mulhi3hw_noint"); 180d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman } 181f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 182ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov setMinFunctionAlignment(1); 183e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov setPrefFunctionAlignment(2); 1844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 1853513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov 18669d5b48bc31b7a443355cdf1506005804b4f63e6Anton KorobeynikovSDValue MSP430TargetLowering::LowerOperation(SDValue Op, 1875d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov SelectionDAG &DAG) const { 1888d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov switch (Op.getOpcode()) { 1891bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case ISD::SHL: // FALLTHROUGH 1901bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case ISD::SRL: 191b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov case ISD::SRA: return LowerShifts(Op, DAG); 19206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); 19306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); 194f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG); 195c23197a26f34f559ea9797de51e187087c039c42Torok Edwin case ISD::SETCC: return LowerSETCC(Op, DAG); 196f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov case ISD::BR_CC: return LowerBR_CC(Op, DAG); 197f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); 198f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov case ISD::SIGN_EXTEND: return LowerSIGN_EXTEND(Op, DAG); 199f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); 200b4202b84d7e54efe5e144885c7da63e6cc465f80Bill Wendling case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); 20120c568f366be211323eeaf0e45ef053278ec9ddcBill Wendling case ISD::VASTART: return LowerVASTART(Op, DAG); 2023741be39f98795a841a4d8c35bf54928769ac3cdAnton Korobeynikov default: 20320c568f366be211323eeaf0e45ef053278ec9ddcBill Wendling llvm_unreachable("unimplemented operand"); 20420c568f366be211323eeaf0e45ef053278ec9ddcBill Wendling } 205c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov} 206cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 207cd76128f182b9a9f3986384523cf90f4c30e4d35Anton 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) 236cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return std::make_pair(0U, &MSP430::GR8RegClass); 237cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 238cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return std::make_pair(0U, &MSP430::GR16RegClass); 239cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 240cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 241cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 242cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); 243cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov} 244c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 245c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===// 246c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// Calling Convention Implementation 247f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//===----------------------------------------------------------------------===// 248c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 24998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman#include "MSP430GenCallingConv.inc" 25098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 25165c3c8f323198b99b88b109654194540cf9b3fa5Sandeep PatelSDValue 25298ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerFormalArguments(SDValue Chain, 25398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CallingConv::ID CallConv, 25498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isVarArg, 25598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> 25698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Ins, 257d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SDLoc dl, 258d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG, 25998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SmallVectorImpl<SDValue> &InVals) 26098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const { 261c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 262c23197a26f34f559ea9797de51e187087c039c42Torok Edwin switch (CallConv) { 263c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov default: 264c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov llvm_unreachable("Unsupported calling convention"); 26598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman case CallingConv::C: 266e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov case CallingConv::Fast: 267e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals); 268e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov case CallingConv::MSP430_INTR: 269e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov if (Ins.empty()) 27075361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner return Chain; 271e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov report_fatal_error("ISRs cannot have arguments"); 272e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov } 273c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov} 274c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 275c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton KorobeynikovSDValue 27698ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, 277022d9e1cef7586a80a96446ae8691a37def9bbf4Evan Cheng SmallVectorImpl<SDValue> &InVals) const { 27865c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel SelectionDAG &DAG = CLI.DAG; 2790c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng SDLoc &dl = CLI.DL; 28098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs; 281c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman SmallVector<SDValue, 32> &OutVals = CLI.OutVals; 28298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SmallVector<ISD::InputArg, 32> &Ins = CLI.Ins; 28398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SDValue Chain = CLI.Chain; 284d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SDValue Callee = CLI.Callee; 2850c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng bool &isTailCall = CLI.IsTailCall; 2860c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng CallingConv::ID CallConv = CLI.CallConv; 28798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isVarArg = CLI.IsVarArg; 28898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 2894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // MSP430 target does not yet support tail call optimization. 290c23197a26f34f559ea9797de51e187087c039c42Torok Edwin isTailCall = false; 2914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 2924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov switch (CallConv) { 29398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman default: 294c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman llvm_unreachable("Unsupported calling convention"); 295e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov case CallingConv::Fast: 29675361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner case CallingConv::C: 297e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall, 2984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Outs, OutVals, Ins, dl, DAG, InVals); 2994428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CallingConv::MSP430_INTR: 3004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov report_fatal_error("ISRs cannot be called directly"); 301c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 302c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov} 303c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 304c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// LowerCCCArguments - transform physical registers into virtual registers and 30598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// generate load operations for arguments places on the stack. 30698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman// FIXME: struct return stuff 30765c3c8f323198b99b88b109654194540cf9b3fa5Sandeep PatelSDValue 30898ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCArguments(SDValue Chain, 30998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CallingConv::ID CallConv, 31098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isVarArg, 31198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> 31298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Ins, 313d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SDLoc dl, 314d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG, 315c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov SmallVectorImpl<SDValue> &InVals) 316c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov const { 317c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineFunction &MF = DAG.getMachineFunction(); 318c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 319c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineRegisterInfo &RegInfo = MF.getRegInfo(); 320c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>(); 32198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 32298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman // Assign locations to all of the incoming arguments. 32398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SmallVector<CCValAssign, 16> ArgLocs; 324c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 325c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov getTargetMachine(), ArgLocs, *DAG.getContext()); 326c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov CCInfo.AnalyzeFormalArguments(Ins, CC_MSP430); 327c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 328c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Create frame index for the start of the first vararg value 329c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (isVarArg) { 330c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov unsigned Offset = CCInfo.getNextStackOffset(); 331e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson FuncInfo->setVarArgsFrameIndex(MFI->CreateFixedObject(1, Offset, true)); 332825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } 333804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin 334804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 335dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin CCValAssign &VA = ArgLocs[i]; 3364437ae213d5435390f0750213b53ec807c047f22Chris Lattner if (VA.isRegLoc()) { 337825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson // Arguments passed in registers 338dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin EVT RegVT = VA.getLocVT(); 339c23197a26f34f559ea9797de51e187087c039c42Torok Edwin switch (RegVT.getSimpleVT().SimpleTy) { 340804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin default: 341825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson { 342c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov#ifndef NDEBUG 3431df221f2bb8e8380e255d1bec73ab07b388d01a2Anton Korobeynikov errs() << "LowerFormalArguments Unhandled argument type: " 344c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov << RegVT.getSimpleVT().SimpleTy << "\n"; 34598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman#endif 346c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov llvm_unreachable(0); 347c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 348c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov case MVT::i16: 349c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov unsigned VReg = RegInfo.createVirtualRegister(&MSP430::GR16RegClass); 350c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov RegInfo.addLiveIn(VA.getLocReg(), VReg); 351c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 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) 36098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 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 366c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov InVals.push_back(ArgValue); 367c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 3684437ae213d5435390f0750213b53ec807c047f22Chris Lattner } else { 3691440e8b918d7116c3587cb95f4f7ac7a0a0b65adDuncan Sands // Sanity check 370c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov assert(VA.isMemLoc()); 371c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 372c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov SDValue InVal; 373ed2ae136d29dd36122d2476801e7d7a86e8301e3Evan Cheng ISD::ArgFlagsTy Flags = Ins[i].Flags; 374c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 375c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (Flags.isByVal()) { 376c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov int FI = MFI->CreateFixedObject(Flags.getByValSize(), 377825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson VA.getLocMemOffset(), true); 37898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman InVal = DAG.getFrameIndex(FI, getPointerTy()); 379d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner } else { 3804d58b641251f28bf34609ba5f389ba6ae0bf9641David Greene // Load the argument to a virtual register 381c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov unsigned ObjSize = VA.getLocVT().getSizeInBits()/8; 382c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (ObjSize > 2) { 383c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov errs() << "LowerFormalArguments Unhandled argument type: " 38498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman << EVT(VA.getLocVT()).getEVTString() 385c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov << "\n"; 386fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 38798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman // Create the frame index object for this incoming parameter... 38898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true); 38965c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel 39098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman // Create the SelectionDAG nodes corresponding to a load 391c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman //from this parameter 392d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SDValue FIN = DAG.getFrameIndex(FI, MVT::i16); 39398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman InVal = DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, 394fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov MachinePointerInfo::getFixedStack(FI), 395fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov false, false, false, 0); 396fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 397e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov 398e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov InVals.push_back(InVal); 39975361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner } 400e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov } 401e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov 402e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov return Chain; 403fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov} 40498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 40598ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 406fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton KorobeynikovMSP430TargetLowering::LowerReturn(SDValue Chain, 40798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CallingConv::ID CallConv, bool isVarArg, 40898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::OutputArg> &Outs, 409fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov const SmallVectorImpl<SDValue> &OutVals, 410fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov SDLoc dl, SelectionDAG &DAG) const { 411fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 412fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // CCValAssign - represent the assignment of the return value to a location 413fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov SmallVector<CCValAssign, 16> RVLocs; 414fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 415fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // ISRs cannot return any value. 416fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (CallConv == CallingConv::MSP430_INTR && !Outs.empty()) 417fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov report_fatal_error("ISRs cannot return any value"); 418fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 419fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // CCState - Info about the registers and stack slot. 420fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 421fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov getTargetMachine(), RVLocs, *DAG.getContext()); 422fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 423fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // Analize return values. 424fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov CCInfo.AnalyzeReturn(Outs, RetCC_MSP430); 425fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 426c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman SDValue Flag; 427fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov SmallVector<SDValue, 4> RetOps(1, Chain); 428dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov 429dcb802cf7be8e540e487c699f25d89c4821536abAnton 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!"); 433e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov 434e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), 435e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov OutVals[i], Flag); 436fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 437e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov // Guarantee that all emitted copies are stuck together, 438fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // avoiding something bad. 439fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov Flag = Chain.getValue(1); 440e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); 441fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 442fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 4434428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov unsigned Opc = (CallConv == CallingConv::MSP430_INTR ? 4444428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG); 4454428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 44698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman RetOps[0] = Chain; // Update chain. 44798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 44865c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel // Add the flag if we have it. 44998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman if (Flag.getNode()) 45098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman RetOps.push_back(Flag); 45198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 452c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman return DAG.getNode(Opc, dl, MVT::Other, &RetOps[0], RetOps.size()); 45398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman} 45498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 455d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman/// 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, 4604428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov CallingConv::ID CallConv, bool isVarArg, 46198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isTailCall, 4624428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov const SmallVectorImpl<ISD::OutputArg> 4634428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov &Outs, 4644428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov const SmallVectorImpl<SDValue> &OutVals, 4654428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov const SmallVectorImpl<ISD::InputArg> &Ins, 4664428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDLoc dl, SelectionDAG &DAG, 4674428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVectorImpl<SDValue> &InVals) const { 4684428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Analyze operands of the call, assigning locations to each operand. 4694428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<CCValAssign, 16> ArgLocs; 4704428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 4714428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov getTargetMachine(), ArgLocs, *DAG.getContext()); 4724428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4734428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 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(); 477c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman 4784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCALLSEQ_START(Chain ,DAG.getConstant(NumBytes, 4794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov getPointerTy(), true)); 4804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 481c23197a26f34f559ea9797de51e187087c039c42Torok Edwin 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 4894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue Arg = OutVals[i]; 4904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Promote the value if needed. 4924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov switch (VA.getLocInfo()) { 4934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 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)); 5106229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner } 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(), 517825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson StackPtr, 5184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG.getIntPtrConstant(VA.getLocMemOffset())); 5194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5204428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue MemOp; 5214428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov ISD::ArgFlagsTy Flags = Outs[i].Flags; 5224428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5234428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (Flags.isByVal()) { 5244428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), MVT::i16); 5254428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov MemOp = DAG.getMemcpy(Chain, dl, PtrOff, Arg, SizeNode, 5264428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Flags.getByValAlign(), 5274428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov /*isVolatile*/false, 5284428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov /*AlwaysInline=*/true, 5294428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov MachinePointerInfo(), 5304428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov MachinePointerInfo()); 5314428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } else { 5324428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov MemOp = DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo(), 5334428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov false, false, 0); 5340d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel } 5354428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 536825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MemOpChains.push_back(MemOp); 5374428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 5384428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 539f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner 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()) 5434428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 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 5484428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // 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)) 5604428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i16); 5614428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) 5624428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i16); 5634428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5644428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Returns a chain & a flag for retval copy to use. 56598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 56698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SmallVector<SDValue, 8> Ops; 5674428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(Chain); 5684428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(Callee); 56998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 57098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman // Add argument registers to the end of the list so that they are 57198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman // known live into the call. 57298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 5734428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(DAG.getRegister(RegsToPass[i].first, 57465c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel RegsToPass[i].second.getValueType())); 57598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 57698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman if (InFlag.getNode()) 577d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman 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); 58198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 582e922c0201916e0b980ab3cfe91e1413e68d55647Owen Anderson // Create the CALLSEQ_END node. 5834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCALLSEQ_END(Chain, 58498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 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, 5924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG, InVals); 5934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 59498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 5954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// LowerCallResult - Lower the result values of a call into the 5964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// appropriate copies out of appropriate physical registers. 597d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov/// 598d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue 599ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton KorobeynikovMSP430TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, 600d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov CallingConv::ID CallConv, bool isVarArg, 601e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson const SmallVectorImpl<ISD::InputArg> &Ins, 602d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov SDLoc dl, SelectionDAG &DAG, 603d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov SmallVectorImpl<SDValue> &InVals) const { 6042625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 605d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // Assign locations to each value returned by this call. 6062625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov SmallVector<CCValAssign, 16> RVLocs; 6072625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 6082625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov getTargetMachine(), RVLocs, *DAG.getContext()); 6092625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 6102625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov CCInfo.AnalyzeCallResult(Ins, RetCC_MSP430); 6112625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 6122625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Copy all of the result registers out of their specified physreg. 6132625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov for (unsigned i = 0; i != RVLocs.size(); ++i) { 6142625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(), 6152625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov RVLocs[i].getValVT(), InFlag).getValue(1); 6162625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov InFlag = Chain.getValue(2); 6172625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov InVals.push_back(Chain.getValue(0)); 6182625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov } 619d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 620d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov return Chain; 621d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov} 622d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 623d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton KorobeynikovSDValue MSP430TargetLowering::LowerShifts(SDValue Op, 624d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov SelectionDAG &DAG) const { 625d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov unsigned Opc = Op.getOpcode(); 626e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov SDNode* N = Op.getNode(); 627e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov EVT VT = Op.getValueType(); 628e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov SDLoc dl(N); 629e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov 630bf8ef3f29de28529b5d65970af9015c41f7c809bAnton Korobeynikov // Expand non-constant shifts to loops: 631e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov if (!isa<ConstantSDNode>(N->getOperand(1))) 632e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov switch (Opc) { 633e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov default: llvm_unreachable("Invalid shift opcode!"); 634d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov case ISD::SHL: 635aceb620de855485a4fb2eed343d880d76f6c701cAnton Korobeynikov return DAG.getNode(MSP430ISD::SHL, dl, 636ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov VT, N->getOperand(0), N->getOperand(1)); 637d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov case ISD::SRA: 638d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov return DAG.getNode(MSP430ISD::SRA, dl, 639d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov VT, N->getOperand(0), N->getOperand(1)); 640d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov case ISD::SRL: 641d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman return DAG.getNode(MSP430ISD::SRL, dl, 642d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman VT, N->getOperand(0), N->getOperand(1)); 6433513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov } 6443513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov 6453513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue(); 6463513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov 6470d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel // Expand the stuff into sequence of shifts. 6480d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel // FIXME: for some shift amounts this might be done better! 6493513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N 6503513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov SDValue Victim = N->getOperand(0); 6513513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov 6523513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov if (Opc == ISD::SRL && ShiftAmount) { 6535d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov // Emit a special goodness here: 654d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman // srl A, 1 => clrc; rrc A 6555d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim); 6565d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov ShiftAmount -= 1; 6575d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov } 6585d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov 6595d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov while (ShiftAmount--) 6605d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov Victim = DAG.getNode((Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA), 6615d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov dl, VT, Victim); 66269d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov 66369d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov return Victim; 66469d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov} 66569d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov 66669d5b48bc31b7a443355cdf1506005804b4f63e6Anton KorobeynikovSDValue MSP430TargetLowering::LowerGlobalAddress(SDValue Op, 66769d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov SelectionDAG &DAG) const { 66869d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); 66969d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset(); 67069d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov 6713926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov // Create the TargetGlobalAddress node, folding in the constant offset. 6721bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Result = DAG.getTargetGlobalAddress(GV, SDLoc(Op), 6731bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov getPointerTy(), Offset); 674ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov return DAG.getNode(MSP430ISD::Wrapper, SDLoc(Op), 675ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov getPointerTy(), Result); 676ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov} 677ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 6783926fb63c24ceeefc0215b8e14eb81c85403639eAnton KorobeynikovSDValue MSP430TargetLowering::LowerExternalSymbol(SDValue Op, 679ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov SelectionDAG &DAG) const { 680c23197a26f34f559ea9797de51e187087c039c42Torok Edwin SDLoc dl(Op); 681ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol(); 6823926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov SDValue Result = DAG.getTargetExternalSymbol(Sym, getPointerTy()); 683f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov 6841722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result); 685f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov} 6861722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov 687ed1a51af376b9027db60ff060e0a2572493df07bAnton KorobeynikovSDValue MSP430TargetLowering::LowerBlockAddress(SDValue Op, 688ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov SelectionDAG &DAG) const { 6893926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov SDLoc dl(Op); 690f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress(); 6911722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov SDValue Result = DAG.getTargetBlockAddress(BA, getPointerTy()); 692f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov 6931722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result); 694ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov} 695ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 696ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikovstatic SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC, 697ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov ISD::CondCode CC, 6980c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov SDLoc dl, SelectionDAG &DAG) { 6990c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // FIXME: Handle bittests someday 7000c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet"); 7010c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov 7020c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // FIXME: Handle jump negative someday 7030c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov MSP430CC::CondCodes TCC = MSP430CC::COND_INVALID; 7040c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov switch (CC) { 7050c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov default: llvm_unreachable("Invalid integer condition!"); 7063926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov case ISD::SETEQ: 707ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov TCC = MSP430CC::COND_E; // aka COND_Z 708ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov // Minor optimization: if LHS is a constant, swap operands, then the 709ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov // constant can be folded into comparison. 710ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov if (LHS.getOpcode() == ISD::Constant) 7110c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov std::swap(LHS, RHS); 7120c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov break; 7130c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov case ISD::SETNE: 7140c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_NE; // aka COND_NZ 7150c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // Minor optimization: if LHS is a constant, swap operands, then the 7160c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // constant can be folded into comparison. 7170c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov if (LHS.getOpcode() == ISD::Constant) 7180c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov std::swap(LHS, RHS); 7193926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov break; 720ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETULE: 721ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 722ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETUGE: 723ed1a51af376b9027db60ff060e0a2572493df07bAnton 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 } 7310c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_HS; // aka COND_C 7323926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov break; 733ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETUGT: 734ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 735ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETULT: 736ed1a51af376b9027db60ff060e0a2572493df07bAnton 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 } 7440c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_LO; // aka COND_NC 7453926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov break; 746ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETLE: 747ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 748ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETGE: 7493926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov // Turn lhs >= rhs with lhs constant into rhs < lhs+1, this allows us to 750f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner // fold constant into instruction. 751ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 752ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov LHS = RHS; 7531bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 754d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman TCC = MSP430CC::COND_L; 755ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 7561bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov } 7571bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov TCC = MSP430CC::COND_GE; 7581bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov break; 7591bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case ISD::SETGT: 7601bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 7611bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case ISD::SETLT: 7623926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to 7631bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov // fold constant into instruction. 7641bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 7651bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov LHS = RHS; 7663926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 767ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov TCC = MSP430CC::COND_GE; 768ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 769d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman } 7708d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov TCC = MSP430CC::COND_L; 7718d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 7728d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 7738d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov 7748d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov TargetCC = DAG.getConstant(TCC, MVT::i8); 7758d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov return DAG.getNode(MSP430ISD::CMP, dl, MVT::Glue, LHS, RHS); 7768d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov} 777cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov 778cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov 7798d1ffbd1adad453fe330be4951400bfd25fab666Anton KorobeynikovSDValue MSP430TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const { 7808d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue Chain = Op.getOperand(0); 7818d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); 7828d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue LHS = Op.getOperand(2); 7838d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue RHS = Op.getOperand(3); 7848d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue Dest = Op.getOperand(4); 7858d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDLoc dl (Op); 7868d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov 7878d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue TargetCC; 7888d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 7898d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov 7908d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(), 7918d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Chain, Dest, TargetCC, Flag); 7928d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov} 7938d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov 7948d1ffbd1adad453fe330be4951400bfd25fab666Anton KorobeynikovSDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const { 7958d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue LHS = Op.getOperand(0); 7968d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue RHS = Op.getOperand(1); 7978d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov 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. 8028d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // FIXME: since we're doing a post-processing, use a pseudoinstr here, so 8038d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // lowering & isel wouldn't diverge. 8048d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov bool andCC = false; 8058d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) { 806cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton 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))) { 810cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov andCC = true; 8118d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 8128d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 8138d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get(); 814455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov SDValue TargetCC; 8158d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 816455080ff100c9383bc2619ae8ad86a02f61c3b00Anton 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 819cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov // instructions generate different flags than CMP, the carry bit can be used 820455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov // for NE/EQ. 821455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov bool Invert = false; 822455080ff100c9383bc2619ae8ad86a02f61c3b00Anton 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: 829cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov // Res = SRW & 1, no processing is required 8308d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 8318d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov case MSP430CC::COND_LO: 8328d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Res = ~(SRW & 1) 8338d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Invert = true; 8348d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 8358d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov case MSP430CC::COND_NE: 8368d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (andCC) { 8378d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // C = ~Z, thus Res = SRW & 1, no processing is required 8388d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } else { 839f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner // Res = ~((SRW >> 1) & 1) 8408d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Shift = true; 8418d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Invert = true; 8428d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 8438d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 8448d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov case MSP430CC::COND_E: 8458d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Shift = true; 8468d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // C = ~Z for AND instruction, thus we can put Res = ~(SRW & 1), however, 8478d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Res = (SRW >> 1) & 1 is 1 word shorter. 8488d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 849d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman } 850d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman EVT VT = Op.getValueType(); 8511bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue One = DAG.getConstant(1, VT); 8521bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov if (Convert) { 8531bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SRW, 8541bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov MVT::i16, Flag); 8551bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov if (Shift) 8568b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // FIXME: somewhere this is turned into a SRL, lower it MSP specific? 8571bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One); 8583926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov SR = DAG.getNode(ISD::AND, dl, MVT::i16, SR, One); 8591bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov if (Invert) 8608b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov SR = DAG.getNode(ISD::XOR, dl, MVT::i16, SR, One); 861f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner return SR; 8628b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov } else { 8638b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov SDValue Zero = DAG.getConstant(0, VT); 8648b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue); 8653926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov SmallVector<SDValue, 4> Ops; 8661bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov Ops.push_back(One); 8678b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov Ops.push_back(Zero); 8681bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov Ops.push_back(TargetCC); 8698b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov Ops.push_back(Flag); 8708b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size()); 871b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov } 872d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman} 873b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 874e50ed30282bb5b4a9ed952580523f2dda16215acOwen AndersonSDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op, 875b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov SelectionDAG &DAG) const { 876b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov SDValue LHS = Op.getOperand(0); 877825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue RHS = Op.getOperand(1); 878b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov SDValue TrueV = Op.getOperand(2); 879b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov SDValue FalseV = Op.getOperand(3); 880b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); 881b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov SDLoc dl (Op); 882b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 883b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov SDValue TargetCC; 884d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 885d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman 88606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue); 88706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SmallVector<SDValue, 4> Ops; 88806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov Ops.push_back(TrueV); 88906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov Ops.push_back(FalseV); 89006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov Ops.push_back(TargetCC); 89106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov Ops.push_back(Flag); 89206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 89306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size()); 894ed2ae136d29dd36122d2476801e7d7a86e8301e3Evan Cheng} 89506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 89606ccca5f70ef5f9c3e4add60b6fc842916705029Anton KorobeynikovSDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op, 89706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SelectionDAG &DAG) const { 89806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue Val = Op.getOperand(0); 89906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov EVT VT = Op.getValueType(); 90006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDLoc dl(Op); 901d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman 902d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman assert(VT == MVT::i16 && "Only support i16 for now!"); 9032457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng 9042457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT, 9052457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val), 90606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov DAG.getValueType(Val.getValueType())); 90706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov} 90806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 90906ccca5f70ef5f9c3e4add60b6fc842916705029Anton KorobeynikovSDValue 91006ccca5f70ef5f9c3e4add60b6fc842916705029Anton KorobeynikovMSP430TargetLowering::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) { 916d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner // Set up a frame object for the return address. 91706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov uint64_t SlotSize = TD->getPointerSize(); 91806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(SlotSize, -SlotSize, 91906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov true); 92006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov FuncInfo->setRAIndex(ReturnAddrIndex); 92106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov } 922d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner 92306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy()); 92406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov} 925d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman 926d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op, 92706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SelectionDAG &DAG) const { 92806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 9292457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng MFI->setReturnAddressIsTaken(true); 93006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 93106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); 93206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDLoc dl(Op); 93306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 93406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov if (Depth > 0) { 93506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue FrameAddr = LowerFRAMEADDR(Op, DAG); 936d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner SDValue Offset = 937d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner DAG.getConstant(TD->getPointerSize(), MVT::i16); 9384d58b641251f28bf34609ba5f389ba6ae0bf9641David Greene return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), 93906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov DAG.getNode(ISD::ADD, dl, getPointerTy(), 94006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov FrameAddr, Offset), 94106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MachinePointerInfo(), false, false, false, 0); 9426534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov } 9436534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 9446534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov // Just load the return address. 9456534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SDValue RetAddrFI = getReturnAddressFrameIndex(DAG); 9466534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), 9476534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov RetAddrFI, MachinePointerInfo(), false, false, false, 0); 9486534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov} 9496534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 9506534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton KorobeynikovSDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op, 9516534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SelectionDAG &DAG) const { 9526534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 9536534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov MFI->setFrameAddressIsTaken(true); 9546534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 9556534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov EVT VT = Op.getValueType(); 9566534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SDLoc dl(Op); // FIXME probably not meaningful 9576534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); 9586534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, 9596534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov MSP430::FPW, VT); 9606534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov while (Depth--) 9616534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr, 9626534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov MachinePointerInfo(), 9636534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov false, false, false, 0); 9646534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return FrameAddr; 9656534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov} 9666534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 9676534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton KorobeynikovSDValue MSP430TargetLowering::LowerVASTART(SDValue Op, 9686534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SelectionDAG &DAG) const { 9696534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov MachineFunction &MF = DAG.getMachineFunction(); 9706534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>(); 9716534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 9726534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov // Frame index of first vararg argument 9736534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SDValue FrameIndex = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), 9746534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov getPointerTy()); 9756534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); 9766534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 9776534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov // Create a store of the frame index to the location operand 978fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov return DAG.getStore(Op.getOperand(0), SDLoc(Op), FrameIndex, 979fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov Op.getOperand(1), MachinePointerInfo(SV), 980fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov false, false, 0); 981fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov} 9826bfcba7e137113e5f38cc4f937ad61cc7253ec74Anton Korobeynikov 983d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov/// getPostIndexedAddressParts - returns true by value, base pointer and 984e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov/// offset pointer and addressing mode by reference if this node can be 985e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov/// combined with a load / store to form a post-indexed load / store. 986b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikovbool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op, 9873513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov SDValue &Base, 9881bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue &Offset, 989ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov ISD::MemIndexedMode &AM, 9901bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SelectionDAG &DAG) const { 9912625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 9922625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov LoadSDNode *LD = cast<LoadSDNode>(N); 993fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (LD->getExtensionType() != ISD::NON_EXTLOAD) 994fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov return false; 9958b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 9969afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov EVT VT = LD->getMemoryVT(); 9979afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov if (VT != MVT::i8 && VT != MVT::i16) 998b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands return false; 9999afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 10009afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov if (Op->getOpcode() != ISD::ADD) 10019afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return false; 10029afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 10039afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) { 10049afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov uint64_t RHSC = RHS->getZExtValue(); 10059afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov if ((VT == MVT::i16 && RHSC != 2) || 10069afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov (VT == MVT::i8 && RHSC != 1)) 10079afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return false; 10089afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 10099afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov Base = Op->getOperand(0); 10109afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov Offset = DAG.getConstant(RHSC, VT); 10119afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov AM = ISD::POST_INC; 10129afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return true; 1013b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands } 10149afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 10159afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return false; 10169afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov} 10179afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 10189afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 10199afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikovconst char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const { 10209afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov switch (Opcode) { 10218b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov default: return NULL; 10228b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov case MSP430ISD::RET_FLAG: return "MSP430ISD::RET_FLAG"; 10238b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov case MSP430ISD::RETI_FLAG: return "MSP430ISD::RETI_FLAG"; 10248b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov case MSP430ISD::RRA: return "MSP430ISD::RRA"; 10258b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov case MSP430ISD::RLA: return "MSP430ISD::RLA"; 10262625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430ISD::RRC: return "MSP430ISD::RRC"; 1027af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman case MSP430ISD::CALL: return "MSP430ISD::CALL"; 10282625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430ISD::Wrapper: return "MSP430ISD::Wrapper"; 10292625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430ISD::BR_CC: return "MSP430ISD::BR_CC"; 10302625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430ISD::CMP: return "MSP430ISD::CMP"; 10312625de35eda2aec28bdec3370a81f533f9721736Anton 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"; 10342625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov } 10352625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov} 10362625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10372625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikovbool MSP430TargetLowering::isTruncateFree(Type *Ty1, 10382625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Type *Ty2) const { 10392625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy()) 10402625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return false; 10412625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10422625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return (Ty1->getPrimitiveSizeInBits() > Ty2->getPrimitiveSizeInBits()); 10432625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov} 10442625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10452625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikovbool MSP430TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const { 10462625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov if (!VT1.isInteger() || !VT2.isInteger()) 10472625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return false; 10482625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10492625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return (VT1.getSizeInBits() > VT2.getSizeInBits()); 10502625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov} 10512625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10522625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikovbool MSP430TargetLowering::isZExtFree(Type *Ty1, Type *Ty2) const { 10532625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // MSP430 implicitly zero-extends 8-bit results in 16-bit registers. 10542625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return 0 && Ty1->isIntegerTy(8) && Ty2->isIntegerTy(16); 10552625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov} 10562625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10572625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikovbool MSP430TargetLowering::isZExtFree(EVT VT1, EVT VT2) const { 10582625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // MSP430 implicitly zero-extends 8-bit results in 16-bit registers. 10592625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return 0 && VT1 == MVT::i8 && VT2 == MVT::i16; 10602625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov} 10612625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10622625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikovbool MSP430TargetLowering::isZExtFree(SDValue Val, EVT VT2) const { 10632625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return isZExtFree(Val.getValueType(), VT2); 10642625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov} 10652625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10662625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov//===----------------------------------------------------------------------===// 10672625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov// Other Lowering Code 10682625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov//===----------------------------------------------------------------------===// 10692625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 10702625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMachineBasicBlock* 10712625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMSP430TargetLowering::EmitShiftInstr(MachineInstr *MI, 10722625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 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(); 107714152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman 107814152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman unsigned Opc; 107914152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman const TargetRegisterClass * RC; 108014152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman switch (MI->getOpcode()) { 10812625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov default: llvm_unreachable("Invalid shift opcode!"); 10822625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Shl8: 10832625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SHL8r1; 10842625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov RC = &MSP430::GR8RegClass; 10852625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 10862625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Shl16: 10872625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SHL16r1; 10882625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov RC = &MSP430::GR16RegClass; 10892625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 10902625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Sra8: 10912625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR8r1; 10922625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov RC = &MSP430::GR8RegClass; 10932625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 10942625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Sra16: 10952625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR16r1; 10962625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov RC = &MSP430::GR16RegClass; 10972625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 10982625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Srl8: 1099f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov Opc = MSP430::SAR8r1c; 1100f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov RC = &MSP430::GR8RegClass; 11012625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 11022625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Srl16: 11032625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR16r1c; 11042625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 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. 11212625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov RemBB->splice(RemBB->begin(), BB, 11222625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov llvm::next(MachineBasicBlock::iterator(MI)), 11232625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BB->end()); 11242625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov RemBB->transferSuccessorsAndUpdatePHIs(BB); 11252625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 112614152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman // Add adges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB 11272625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BB->addSuccessor(LoopBB); 11282625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BB->addSuccessor(RemBB); 11292625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov LoopBB->addSuccessor(RemBB); 113014152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman LoopBB->addSuccessor(LoopBB); 11312625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 11322625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned ShiftAmtReg = RI.createVirtualRegister(&MSP430::GR8RegClass); 11332625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned ShiftAmtReg2 = RI.createVirtualRegister(&MSP430::GR8RegClass); 11342625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned ShiftReg = RI.createVirtualRegister(RC); 11358b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov unsigned ShiftReg2 = RI.createVirtualRegister(RC); 1136af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman 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 1142af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman // je RemBB 11432625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(BB, dl, TII.get(MSP430::CMP8ri)) 11448b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(ShiftAmtSrcReg).addImm(0); 11458b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BuildMI(BB, dl, TII.get(MSP430::JCC)) 11462625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addMBB(RemBB) 11472625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addImm(MSP430CC::COND_E); 11488b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 11498b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // LoopBB: 11508b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB] 11518b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // ShiftAmt = phi [%N, BB], [%ShiftAmt2, LoopBB] 11528b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // ShiftReg2 = shift ShiftReg 11538b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // ShiftAmt2 = ShiftAmt - 1; 11548b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftReg) 11558b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(SrcReg).addMBB(BB) 11568b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(ShiftReg2).addMBB(LoopBB); 11578b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg) 11588b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(ShiftAmtSrcReg).addMBB(BB) 11598b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(ShiftAmtReg2).addMBB(LoopBB); 11608b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2) 11618b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(ShiftReg); 11628b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2) 11638b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(ShiftAmtReg).addImm(1); 11648b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::JCC)) 11658b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addMBB(LoopBB) 11668b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addImm(MSP430CC::COND_NE); 11678b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 11688b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // RemBB: 11698b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB] 11708b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BuildMI(*RemBB, RemBB->begin(), dl, TII.get(MSP430::PHI), DstReg) 11718b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(SrcReg).addMBB(BB) 117214152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman .addReg(ShiftReg2).addMBB(LoopBB); 117314152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman 117414152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman MI->eraseFromParent(); // The pseudo instruction is gone now. 117514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman return RemBB; 11768b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov} 11778b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 11788b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMachineBasicBlock* 11798b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 118014152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman MachineBasicBlock *BB) const { 118114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman unsigned Opc = MI->getOpcode(); 118214152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman 118314152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 || 11848b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov Opc == MSP430::Sra8 || Opc == MSP430::Sra16 || 11858b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov Opc == MSP430::Srl8 || Opc == MSP430::Srl16) 11868b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov return EmitShiftInstr(MI, BB); 11878b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 11888b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); 11898b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov DebugLoc dl = MI->getDebugLoc(); 11908b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 11918b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton 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 119614152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman // 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; 120114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman 12028b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // thisMBB: 12038b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // ... 1204 // TrueVal = ... 1205 // cmpTY ccX, r1, r2 1206 // jCC copy1MBB 1207 // fallthrough --> copy0MBB 1208 MachineBasicBlock *thisMBB = BB; 1209 MachineFunction *F = BB->getParent(); 1210 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); 1211 MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB); 1212 F->insert(I, copy0MBB); 1213 F->insert(I, copy1MBB); 1214 // Update machine-CFG edges by transferring all successors of the current 1215 // block to the new block which will contain the Phi node for the select. 1216 copy1MBB->splice(copy1MBB->begin(), BB, 1217 llvm::next(MachineBasicBlock::iterator(MI)), 1218 BB->end()); 1219 copy1MBB->transferSuccessorsAndUpdatePHIs(BB); 1220 // Next, add the true and fallthrough blocks as its successors. 1221 BB->addSuccessor(copy0MBB); 1222 BB->addSuccessor(copy1MBB); 1223 1224 BuildMI(BB, dl, TII.get(MSP430::JCC)) 1225 .addMBB(copy1MBB) 1226 .addImm(MI->getOperand(3).getImm()); 1227 1228 // copy0MBB: 1229 // %FalseValue = ... 1230 // # fallthrough to copy1MBB 1231 BB = copy0MBB; 1232 1233 // Update machine-CFG edges 1234 BB->addSuccessor(copy1MBB); 1235 1236 // copy1MBB: 1237 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] 1238 // ... 1239 BB = copy1MBB; 1240 BuildMI(*BB, BB->begin(), dl, TII.get(MSP430::PHI), 1241 MI->getOperand(0).getReg()) 1242 .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB) 1243 .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB); 1244 1245 MI->eraseFromParent(); // The pseudo instruction is gone now. 1246 return BB; 1247} 1248