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#include "MSP430ISelLowering.h" 15f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430.h" 1606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov#include "MSP430MachineFunctionInfo.h" 17f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430Subtarget.h" 18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "MSP430TargetMachine.h" 19f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/CallingConvLower.h" 20f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h" 21f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineFunction.h" 22f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h" 23f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineRegisterInfo.h" 24f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/SelectionDAGISel.h" 25362dd0bef5437f85586c046bc53287b6fbe9c099Anton Korobeynikov#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 26f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/ValueTypes.h" 270b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/CallingConv.h" 280b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h" 290b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 300b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/GlobalAlias.h" 310b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/GlobalVariable.h" 320b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Intrinsics.h" 33b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov#include "llvm/Support/CommandLine.h" 34f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/Support/Debug.h" 35804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin#include "llvm/Support/ErrorHandling.h" 364437ae213d5435390f0750213b53ec807c047f22Chris Lattner#include "llvm/Support/raw_ostream.h" 37f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovusing namespace llvm; 38f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 39dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "msp430-lower" 40dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 41b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikovtypedef enum { 42b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov NoHWMult, 43b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov HWMultIntr, 44b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov HWMultNoIntr 45b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov} HWMultUseMode; 46b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov 47b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikovstatic cl::opt<HWMultUseMode> 48fe16848601bdde6e3a5e0860199169dd171222a4Nadav RotemHWMultMode("msp430-hwmult-mode", cl::Hidden, 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 60cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMSP430TargetLowering::MSP430TargetLowering(const TargetMachine &TM) 61cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines : TargetLowering(TM, new TargetLoweringObjectFileELF()) { 6206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 63f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov // Set up the register classes. 64420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper addRegisterClass(MVT::i8, &MSP430::GR8RegClass); 65420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper addRegisterClass(MVT::i16, &MSP430::GR16RegClass); 66f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 67f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov // Compute derived properties from the register classes 68f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov computeRegisterProperties(); 69fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 701476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov // Provide all sorts of operation actions 711476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov 721476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov // Division is expensive 731476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov setIntDivIsCheap(false); 741476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov 75c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov setStackPointerRegisterToSaveRestore(MSP430::SPW); 76c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov setBooleanContents(ZeroOrOneBooleanContent); 7728b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct? 78c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov 7906ac0820a6cefa6896000054d8e4906326c0cce6Anton Korobeynikov // We have post-incremented loads / stores. 806534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setIndexedLoadAction(ISD::POST_INC, MVT::i8, Legal); 816534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setIndexedLoadAction(ISD::POST_INC, MVT::i16, Legal); 826534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 836534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); 846534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); 856534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); 866534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Expand); 87825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Expand); 8836b6e533c1aac85452438161f7034a9f54bd1830Anton Korobeynikov 8954f30d3fc94e055f13e6744378323d05c5c050baAnton Korobeynikov // We don't have any truncstores 90825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setTruncStoreAction(MVT::i16, MVT::i8, Expand); 91825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 92825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRA, MVT::i8, Custom); 93825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SHL, MVT::i8, Custom); 94825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRL, MVT::i8, Custom); 95825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRA, MVT::i16, Custom); 96825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SHL, MVT::i16, Custom); 97825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRL, MVT::i16, Custom); 98825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ROTL, MVT::i8, Expand); 99825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ROTR, MVT::i8, Expand); 100825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ROTL, MVT::i16, Expand); 101825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ROTR, MVT::i16, Expand); 102825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::GlobalAddress, MVT::i16, Custom); 103825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ExternalSymbol, MVT::i16, Custom); 10469d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov setOperationAction(ISD::BlockAddress, MVT::i16, Custom); 105825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BR_JT, MVT::Other, Expand); 106825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BR_CC, MVT::i8, Custom); 107825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BR_CC, MVT::i16, Custom); 108825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BRCOND, MVT::Other, Expand); 1098d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov setOperationAction(ISD::SETCC, MVT::i8, Custom); 1108d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov setOperationAction(ISD::SETCC, MVT::i16, Custom); 111825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT, MVT::i8, Expand); 112825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT, MVT::i16, Expand); 113825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT_CC, MVT::i8, Custom); 114825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT_CC, MVT::i16, Custom); 115825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SIGN_EXTEND, MVT::i16, Custom); 116379a087cc7175532ff0c24c60069da5eec596879Anton Korobeynikov setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i8, Expand); 117379a087cc7175532ff0c24c60069da5eec596879Anton Korobeynikov setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i16, Expand); 118825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 119825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTTZ, MVT::i8, Expand); 120825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTTZ, MVT::i16, Expand); 12163974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i8, Expand); 12263974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i16, Expand); 123825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTLZ, MVT::i8, Expand); 124825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTLZ, MVT::i16, Expand); 12563974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i8, Expand); 12663974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i16, Expand); 127825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTPOP, MVT::i8, Expand); 128825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTPOP, MVT::i16, Expand); 129825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 130825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SHL_PARTS, MVT::i8, Expand); 131825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SHL_PARTS, MVT::i16, Expand); 132825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRL_PARTS, MVT::i8, Expand); 133825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRL_PARTS, MVT::i16, Expand); 134825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRA_PARTS, MVT::i8, Expand); 135825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRA_PARTS, MVT::i16, Expand); 136825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 137825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); 138e4ce880dfa340bf45ddce10bb1dbe856553677b6Eli Friedman 1398725bd22bf91c29e2351a127295c19fea996e2c7Anton Korobeynikov // FIXME: Implement efficiently multiplication by a constant 1408983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::MUL, MVT::i8, Expand); 1418983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::MULHS, MVT::i8, Expand); 1428983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::MULHU, MVT::i8, Expand); 1438983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::SMUL_LOHI, MVT::i8, Expand); 1448983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::UMUL_LOHI, MVT::i8, Expand); 145825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::MUL, MVT::i16, Expand); 146825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::MULHS, MVT::i16, Expand); 147825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::MULHU, MVT::i16, Expand); 148825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SMUL_LOHI, MVT::i16, Expand); 149825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UMUL_LOHI, MVT::i16, Expand); 150825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 1518983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::UDIV, MVT::i8, Expand); 1528983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::UDIVREM, MVT::i8, Expand); 1538983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::UREM, MVT::i8, Expand); 1548983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::SDIV, MVT::i8, Expand); 1558983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::SDIVREM, MVT::i8, Expand); 1568983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::SREM, MVT::i8, Expand); 157825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UDIV, MVT::i16, Expand); 158825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UDIVREM, MVT::i16, Expand); 159825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UREM, MVT::i16, Expand); 160825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SDIV, MVT::i16, Expand); 161825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SDIVREM, MVT::i16, Expand); 162825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SREM, MVT::i16, Expand); 163b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov 1640ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov // varargs support 1650ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov setOperationAction(ISD::VASTART, MVT::Other, Custom); 1660ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov setOperationAction(ISD::VAARG, MVT::Other, Expand); 1670ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov setOperationAction(ISD::VAEND, MVT::Other, Expand); 1680ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov setOperationAction(ISD::VACOPY, MVT::Other, Expand); 16927253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov setOperationAction(ISD::JumpTable, MVT::i16, Custom); 1700ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov 171b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov // Libcalls names. 172b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov if (HWMultMode == HWMultIntr) { 173b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I8, "__mulqi3hw"); 174b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I16, "__mulhi3hw"); 175b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov } else if (HWMultMode == HWMultNoIntr) { 176b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I8, "__mulqi3hw_noint"); 177b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I16, "__mulhi3hw_noint"); 178b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov } 179fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman 180fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman setMinFunctionAlignment(1); 181fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman setPrefFunctionAlignment(2); 182f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 183f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 184d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerOperation(SDValue Op, 185d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 186f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov switch (Op.getOpcode()) { 187ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov case ISD::SHL: // FALLTHROUGH 188e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case ISD::SRL: 1894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case ISD::SRA: return LowerShifts(Op, DAG); 1903513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); 19169d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); 1925d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG); 1938d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov case ISD::SETCC: return LowerSETCC(Op, DAG); 1941bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case ISD::BR_CC: return LowerBR_CC(Op, DAG); 1951bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); 196b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov case ISD::SIGN_EXTEND: return LowerSIGN_EXTEND(Op, DAG); 19706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); 19806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); 1990ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov case ISD::VASTART: return LowerVASTART(Op, DAG); 20027253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov case ISD::JumpTable: return LowerJumpTable(Op, DAG); 201f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov default: 202c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("unimplemented operand"); 203f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov } 204f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 205f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 206c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===// 207cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov// MSP430 Inline Assembly Support 208cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===// 209cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 210cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// getConstraintType - Given a constraint letter, return the type of 211cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// constraint it is for this target. 212cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovTargetLowering::ConstraintType 213cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering::getConstraintType(const std::string &Constraint) const { 214cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov if (Constraint.size() == 1) { 215cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov switch (Constraint[0]) { 216cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov case 'r': 217cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return C_RegisterClass; 218cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov default: 219cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov break; 220cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 221cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 222cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return TargetLowering::getConstraintType(Constraint); 223cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov} 224cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 225cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikovstd::pair<unsigned, const TargetRegisterClass*> 226cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering:: 227cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovgetRegForInlineAsmConstraint(const std::string &Constraint, 2285b3fca50a08865f0db55fc92ad1c037a04e12177Chad Rosier MVT VT) const { 229cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov if (Constraint.size() == 1) { 230cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov // GCC Constraint Letters 231cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov switch (Constraint[0]) { 232cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov default: break; 233cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov case 'r': // GENERAL_REGS 234cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov if (VT == MVT::i8) 235420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper return std::make_pair(0U, &MSP430::GR8RegClass); 236cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 237420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper return std::make_pair(0U, &MSP430::GR16RegClass); 238cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 239cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 240cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 241cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); 242cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov} 243cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 244cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===// 245c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// Calling Convention Implementation 246c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===// 247c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 248f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430GenCallingConv.inc" 249c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 2503edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman/// For each argument in a function store the number of pieces it is composed 2513edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman/// of. 2523edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormantemplate<typename ArgT> 2533edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void ParseFunctionArgs(const SmallVectorImpl<ArgT> &Args, 2543edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman SmallVectorImpl<unsigned> &Out) { 2553edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman unsigned CurrentArgIndex = ~0U; 2563edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman for (unsigned i = 0, e = Args.size(); i != e; i++) { 2573edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman if (CurrentArgIndex == Args[i].OrigArgIndex) { 2583edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman Out.back()++; 2593edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman } else { 2603edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman Out.push_back(1); 2613edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman CurrentArgIndex++; 2623edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman } 2633edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman } 2643edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman} 2653edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 2663edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void AnalyzeVarArgs(CCState &State, 2673edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman const SmallVectorImpl<ISD::OutputArg> &Outs) { 2683edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman State.AnalyzeCallOperands(Outs, CC_MSP430_AssignStack); 2693edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman} 2703edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 2713edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void AnalyzeVarArgs(CCState &State, 2723edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman const SmallVectorImpl<ISD::InputArg> &Ins) { 2733edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman State.AnalyzeFormalArguments(Ins, CC_MSP430_AssignStack); 2743edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman} 2753edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 2763edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman/// Analyze incoming and outgoing function arguments. We need custom C++ code 2773edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman/// to handle special constraints in the ABI like reversing the order of the 2783edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman/// pieces of splitted arguments. In addition, all pieces of a certain argument 2793edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman/// have to be passed either using registers or the stack but never mixing both. 2803edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormantemplate<typename ArgT> 2813edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void AnalyzeArguments(CCState &State, 2823edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman SmallVectorImpl<CCValAssign> &ArgLocs, 2833edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman const SmallVectorImpl<ArgT> &Args) { 284dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines static const MCPhysReg RegList[] = { 2853edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman MSP430::R15W, MSP430::R14W, MSP430::R13W, MSP430::R12W 2863edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman }; 2873edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman static const unsigned NbRegs = array_lengthof(RegList); 2883edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 2893edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman if (State.isVarArg()) { 2903edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman AnalyzeVarArgs(State, Args); 2913edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman return; 2923edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman } 2933edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 2943edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman SmallVector<unsigned, 4> ArgsParts; 2953edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman ParseFunctionArgs(Args, ArgsParts); 2963edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 2973edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman unsigned RegsLeft = NbRegs; 2983edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman bool UseStack = false; 2993edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman unsigned ValNo = 0; 3003edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 3013edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman for (unsigned i = 0, e = ArgsParts.size(); i != e; i++) { 3023edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman MVT ArgVT = Args[ValNo].VT; 3033edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman ISD::ArgFlagsTy ArgFlags = Args[ValNo].Flags; 3043edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman MVT LocVT = ArgVT; 3053edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman CCValAssign::LocInfo LocInfo = CCValAssign::Full; 3063edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 3073edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman // Promote i8 to i16 3083edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman if (LocVT == MVT::i8) { 3093edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman LocVT = MVT::i16; 3103edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman if (ArgFlags.isSExt()) 3113edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman LocInfo = CCValAssign::SExt; 3123edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman else if (ArgFlags.isZExt()) 3133edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman LocInfo = CCValAssign::ZExt; 3143edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman else 3153edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman LocInfo = CCValAssign::AExt; 3163edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman } 3173edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 3183edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman // Handle byval arguments 3193edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman if (ArgFlags.isByVal()) { 3203edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman State.HandleByVal(ValNo++, ArgVT, LocVT, LocInfo, 2, 2, ArgFlags); 3213edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman continue; 3223edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman } 3233edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 3243edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman unsigned Parts = ArgsParts[i]; 3253edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 3263edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman if (!UseStack && Parts <= RegsLeft) { 3273edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman unsigned FirstVal = ValNo; 3283edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman for (unsigned j = 0; j < Parts; j++) { 3293edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman unsigned Reg = State.AllocateReg(RegList, NbRegs); 3303edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman State.addLoc(CCValAssign::getReg(ValNo++, ArgVT, Reg, LocVT, LocInfo)); 3313edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman RegsLeft--; 3323edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman } 3333edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 3343edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman // Reverse the order of the pieces to agree with the "big endian" format 3353edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman // required in the calling convention ABI. 3363edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman SmallVectorImpl<CCValAssign>::iterator B = ArgLocs.begin() + FirstVal; 3373edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman std::reverse(B, B + Parts); 3383edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman } else { 3393edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman UseStack = true; 3403edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman for (unsigned j = 0; j < Parts; j++) 3413edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman CC_MSP430_AssignStack(ValNo++, ArgVT, LocVT, LocInfo, ArgFlags, State); 3423edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman } 3433edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman } 3443edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman} 3453edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 3463edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void AnalyzeRetResult(CCState &State, 3473edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman const SmallVectorImpl<ISD::InputArg> &Ins) { 3483edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman State.AnalyzeCallResult(Ins, RetCC_MSP430); 3493edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman} 3503edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 3513edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void AnalyzeRetResult(CCState &State, 3523edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman const SmallVectorImpl<ISD::OutputArg> &Outs) { 3533edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman State.AnalyzeReturn(Outs, RetCC_MSP430); 3543edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman} 3553edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 3563edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormantemplate<typename ArgT> 3573edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void AnalyzeReturnValues(CCState &State, 3583edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman SmallVectorImpl<CCValAssign> &RVLocs, 3593edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman const SmallVectorImpl<ArgT> &Args) { 3603edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman AnalyzeRetResult(State, Args); 3613edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 3623edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman // Reverse splitted return values to get the "big endian" format required 3633edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman // to agree with the calling convention ABI. 3643edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman std::reverse(RVLocs.begin(), RVLocs.end()); 3653edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman} 3663edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 36798ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 36898ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerFormalArguments(SDValue Chain, 36965c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, 37098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isVarArg, 37198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> 37298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Ins, 373ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, 37498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SelectionDAG &DAG, 375d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) 376d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman const { 37798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 37898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman switch (CallConv) { 379c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov default: 380c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Unsupported calling convention"); 381c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov case CallingConv::C: 382c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov case CallingConv::Fast: 38398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals); 384e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov case CallingConv::MSP430_INTR: 3854d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie if (Ins.empty()) 3864d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie return Chain; 38775361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("ISRs cannot have arguments"); 388c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 389c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov} 390c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 39198ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 392d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin HolewinskiMSP430TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, 393d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) const { 394d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SelectionDAG &DAG = CLI.DAG; 395ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc &dl = CLI.DL; 396a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs; 397a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper SmallVectorImpl<SDValue> &OutVals = CLI.OutVals; 398a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins; 399d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SDValue Chain = CLI.Chain; 400d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SDValue Callee = CLI.Callee; 401d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski bool &isTailCall = CLI.IsTailCall; 402d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski CallingConv::ID CallConv = CLI.CallConv; 403d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski bool isVarArg = CLI.IsVarArg; 404d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski 4050c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng // MSP430 target does not yet support tail call optimization. 4060c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng isTailCall = false; 40798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 40898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman switch (CallConv) { 4094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov default: 410c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Unsupported calling convention"); 4114428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CallingConv::Fast: 4124428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CallingConv::C: 41398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall, 414c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman Outs, OutVals, Ins, dl, DAG, InVals); 415e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov case CallingConv::MSP430_INTR: 41675361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("ISRs cannot be called directly"); 4174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 4184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 4194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 420c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// LowerCCCArguments - transform physical registers into virtual registers and 421c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// generate load operations for arguments places on the stack. 422c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// FIXME: struct return stuff 42398ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 42498ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCArguments(SDValue Chain, 42565c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, 42698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isVarArg, 42798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> 42898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Ins, 429ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, 43098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SelectionDAG &DAG, 431d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) 432d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman const { 433c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineFunction &MF = DAG.getMachineFunction(); 434c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 435c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineRegisterInfo &RegInfo = MF.getRegInfo(); 4360ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>(); 437c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 438c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Assign locations to all of the incoming arguments. 439c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov SmallVector<CCValAssign, 16> ArgLocs; 440471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 44156cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling getTargetMachine(), ArgLocs, *DAG.getContext()); 4423edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman AnalyzeArguments(CCInfo, ArgLocs, Ins); 443c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 4440ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov // Create frame index for the start of the first vararg value 4450ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov if (isVarArg) { 4460ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov unsigned Offset = CCInfo.getNextStackOffset(); 4470ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov FuncInfo->setVarArgsFrameIndex(MFI->CreateFixedObject(1, Offset, true)); 4480ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov } 449c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 450c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 451c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov CCValAssign &VA = ArgLocs[i]; 452c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.isRegLoc()) { 453c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Arguments passed in registers 454e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT RegVT = VA.getLocVT(); 455825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson switch (RegVT.getSimpleVT().SimpleTy) { 45695771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson default: 457804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin { 458dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#ifndef NDEBUG 4594437ae213d5435390f0750213b53ec807c047f22Chris Lattner errs() << "LowerFormalArguments Unhandled argument type: " 460825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson << RegVT.getSimpleVT().SimpleTy << "\n"; 461dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#endif 462dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines llvm_unreachable(nullptr); 463804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin } 464825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i16: 465420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper unsigned VReg = RegInfo.createVirtualRegister(&MSP430::GR16RegClass); 466c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov RegInfo.addLiveIn(VA.getLocReg(), VReg); 46798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, RegVT); 468c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 469c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // If this is an 8-bit value, it is really passed promoted to 16 470c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // bits. Insert an assert[sz]ext to capture this, then truncate to the 471c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // right size. 472c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.getLocInfo() == CCValAssign::SExt) 473c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue, 474c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov DAG.getValueType(VA.getValVT())); 475c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov else if (VA.getLocInfo() == CCValAssign::ZExt) 476c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue, 477c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov DAG.getValueType(VA.getValVT())); 478c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 479c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.getLocInfo() != CCValAssign::Full) 480c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); 481c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 48298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman InVals.push_back(ArgValue); 483c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 484c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } else { 485c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Sanity check 486c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov assert(VA.isMemLoc()); 4876cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov 4886cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov SDValue InVal; 4896cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov ISD::ArgFlagsTy Flags = Ins[i].Flags; 4906cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov 4916cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov if (Flags.isByVal()) { 4926cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov int FI = MFI->CreateFixedObject(Flags.getByValSize(), 4936cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov VA.getLocMemOffset(), true); 4946cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov InVal = DAG.getFrameIndex(FI, getPointerTy()); 4956cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov } else { 4966cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov // Load the argument to a virtual register 4976cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov unsigned ObjSize = VA.getLocVT().getSizeInBits()/8; 4986cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov if (ObjSize > 2) { 4996cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov errs() << "LowerFormalArguments Unhandled argument type: " 5006cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov << EVT(VA.getLocVT()).getEVTString() 5016cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov << "\n"; 5026cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov } 5036cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov // Create the frame index object for this incoming parameter... 5046cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true); 5056cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov 5066cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov // Create the SelectionDAG nodes corresponding to a load 5076cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov //from this parameter 5086cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov SDValue FIN = DAG.getFrameIndex(FI, MVT::i16); 5096cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov InVal = DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, 5106cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov MachinePointerInfo::getFixedStack(FI), 5116cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov false, false, false, 0); 512c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 5136cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov 5146cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov InVals.push_back(InVal); 515c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 516c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 517c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 51898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return Chain; 519c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov} 520fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 52198ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 52298ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerReturn(SDValue Chain, 52365c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 52498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::OutputArg> &Outs, 525c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman const SmallVectorImpl<SDValue> &OutVals, 526ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, SelectionDAG &DAG) const { 52798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 528fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // CCValAssign - represent the assignment of the return value to a location 529fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov SmallVector<CCValAssign, 16> RVLocs; 530fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 531e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov // ISRs cannot return any value. 5324d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie if (CallConv == CallingConv::MSP430_INTR && !Outs.empty()) 53375361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("ISRs cannot return any value"); 534e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov 535fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // CCState - Info about the registers and stack slot. 536471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 53756cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling getTargetMachine(), RVLocs, *DAG.getContext()); 538fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 53998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman // Analize return values. 5403edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman AnalyzeReturnValues(CCInfo, RVLocs, Outs); 541fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 542fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov SDValue Flag; 543294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen SmallVector<SDValue, 4> RetOps(1, Chain); 544fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 545fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // Copy the result values into the output registers. 546fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov for (unsigned i = 0; i != RVLocs.size(); ++i) { 547fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov CCValAssign &VA = RVLocs[i]; 548fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov assert(VA.isRegLoc() && "Can only return in registers!"); 549fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 550fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), 551c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman OutVals[i], Flag); 552fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 553dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov // Guarantee that all emitted copies are stuck together, 554dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov // avoiding something bad. 555fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov Flag = Chain.getValue(1); 556294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); 557fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 558fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 559e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov unsigned Opc = (CallConv == CallingConv::MSP430_INTR ? 560e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG); 561e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov 562294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen RetOps[0] = Chain; // Update chain. 563294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen 564294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen // Add the flag if we have it. 565fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (Flag.getNode()) 566294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen RetOps.push_back(Flag); 567fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 568dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return DAG.getNode(Opc, dl, MVT::Other, RetOps); 569fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov} 570fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 5714428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// LowerCCCCallTo - functions arguments are copied from virtual regs to 5724428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted. 5730bf3c99886bed6796eada8f65942ee6023fc6e89Job Noorman// TODO: sret. 57498ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 57598ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, 57665c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 57798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isTailCall, 57898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::OutputArg> 57998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Outs, 580c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman const SmallVectorImpl<SDValue> &OutVals, 58198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> &Ins, 582ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, SelectionDAG &DAG, 583d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) const { 5844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Analyze operands of the call, assigning locations to each operand. 5854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<CCValAssign, 16> ArgLocs; 586471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 58756cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling getTargetMachine(), ArgLocs, *DAG.getContext()); 5883edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman AnalyzeArguments(CCInfo, ArgLocs, Outs); 5894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Get a count of how many bytes are to be pushed on the stack. 5914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov unsigned NumBytes = CCInfo.getNextStackOffset(); 5924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCALLSEQ_START(Chain ,DAG.getConstant(NumBytes, 5946e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick getPointerTy(), true), 5956e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick dl); 5964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5974428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass; 5984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<SDValue, 12> MemOpChains; 5994428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue StackPtr; 6004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 6014428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Walk the register/memloc assignments, inserting copies/loads. 6024428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 6034428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov CCValAssign &VA = ArgLocs[i]; 6044428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 605c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman SDValue Arg = OutVals[i]; 6064428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 6074428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Promote the value if needed. 6084428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov switch (VA.getLocInfo()) { 609c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Unknown loc info!"); 6104428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::Full: break; 6114428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::SExt: 6124428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); 6134428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 6144428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::ZExt: 6154428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg); 6164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 6174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::AExt: 6184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); 6194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 6204428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 6214428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 6224428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Arguments that can be passed on register must be kept at RegsToPass 6234428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // vector 6244428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (VA.isRegLoc()) { 6254428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 6264428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } else { 6274428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov assert(VA.isMemLoc()); 6284428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 629dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!StackPtr.getNode()) 6304428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SPW, getPointerTy()); 6314428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 6324428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), 6334428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov StackPtr, 6344428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG.getIntPtrConstant(VA.getLocMemOffset())); 6354428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 6366cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov SDValue MemOp; 6376cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov ISD::ArgFlagsTy Flags = Outs[i].Flags; 6386cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov 6396cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov if (Flags.isByVal()) { 6406cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), MVT::i16); 6416cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov MemOp = DAG.getMemcpy(Chain, dl, PtrOff, Arg, SizeNode, 6426cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov Flags.getByValAlign(), 6436cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov /*isVolatile*/false, 6446cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov /*AlwaysInline=*/true, 6456cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov MachinePointerInfo(), 6466cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov MachinePointerInfo()); 6476cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov } else { 6486cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov MemOp = DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo(), 6496cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov false, false, 0); 6506cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov } 6514428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 6526cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov MemOpChains.push_back(MemOp); 6534428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 6544428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 6554428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 6564428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Transform all store nodes into one single node because all store nodes are 6574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // independent of each other. 6584428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (!MemOpChains.empty()) 659dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains); 6604428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 6614428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Build a sequence of copy-to-reg nodes chained together with token chain and 6624428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // flag operands which copy the outgoing args into registers. The InFlag in 6637a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // necessary since all emitted instructions must be stuck together. 6644428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue InFlag; 6654428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 6664428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, 6674428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RegsToPass[i].second, InFlag); 6684428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(1); 6694428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 6704428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 6714428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // If the callee is a GlobalAddress node (quite common, every direct call is) 6724428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 6734428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Likewise ExternalSymbol -> TargetExternalSymbol. 6744428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 6750d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i16); 6764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) 677825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i16); 6784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 6794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Returns a chain & a flag for retval copy to use. 680f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 6814428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<SDValue, 8> Ops; 6824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(Chain); 6834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(Callee); 6844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 6854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Add argument registers to the end of the list so that they are 6864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // known live into the call. 6874428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 6884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(DAG.getRegister(RegsToPass[i].first, 6894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RegsToPass[i].second.getValueType())); 6904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 6914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (InFlag.getNode()) 6924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(InFlag); 6934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 694dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Chain = DAG.getNode(MSP430ISD::CALL, dl, NodeTys, Ops); 6954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(1); 6964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 6974428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Create the CALLSEQ_END node. 6984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCALLSEQ_END(Chain, 6994428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG.getConstant(NumBytes, getPointerTy(), true), 7004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG.getConstant(0, getPointerTy(), true), 7016e0b2a0cb0d398f175a5294bf0ad5488c714e8c2Andrew Trick InFlag, dl); 7024428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(1); 7034428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 7044428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Handle result values, copying them out of physregs into vregs that we 7054428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // return. 70698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl, 70798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DAG, InVals); 7084428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 7094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 71098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// LowerCallResult - Lower the result values of a call into the 71198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// appropriate copies out of appropriate physical registers. 71298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// 71398ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 7144428885c5acfffbbdd03ad2aab23960531c47753Anton KorobeynikovMSP430TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, 71565c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 71698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> &Ins, 717ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, SelectionDAG &DAG, 718d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) const { 7194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 7204428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Assign locations to each value returned by this call. 7214428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<CCValAssign, 16> RVLocs; 722471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 72356cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling getTargetMachine(), RVLocs, *DAG.getContext()); 7244428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 7253edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman AnalyzeReturnValues(CCInfo, RVLocs, Ins); 7264428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 7274428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Copy all of the result registers out of their specified physreg. 7284428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0; i != RVLocs.size(); ++i) { 7294428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(), 7304428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RVLocs[i].getValVT(), InFlag).getValue(1); 7314428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(2); 73298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman InVals.push_back(Chain.getValue(0)); 7334428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 7344428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 73598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return Chain; 7364428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 7374428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 738d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton KorobeynikovSDValue MSP430TargetLowering::LowerShifts(SDValue Op, 739d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 740ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov unsigned Opc = Op.getOpcode(); 741d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov SDNode* N = Op.getNode(); 742e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Op.getValueType(); 743ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(N); 744d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 7452625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Expand non-constant shifts to loops: 746d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov if (!isa<ConstantSDNode>(N->getOperand(1))) 7472625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov switch (Opc) { 748bc2198133a1836598b54b943420748e75d5dea94Craig Topper default: llvm_unreachable("Invalid shift opcode!"); 7492625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case ISD::SHL: 7502625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return DAG.getNode(MSP430ISD::SHL, dl, 7512625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov VT, N->getOperand(0), N->getOperand(1)); 7522625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case ISD::SRA: 7532625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return DAG.getNode(MSP430ISD::SRA, dl, 7542625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov VT, N->getOperand(0), N->getOperand(1)); 7552625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case ISD::SRL: 7562625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return DAG.getNode(MSP430ISD::SRL, dl, 7572625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov VT, N->getOperand(0), N->getOperand(1)); 7582625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov } 759d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 760d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue(); 761d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 762d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // Expand the stuff into sequence of shifts. 763d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // FIXME: for some shift amounts this might be done better! 764d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N 765d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov SDValue Victim = N->getOperand(0); 766e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov 767e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov if (Opc == ISD::SRL && ShiftAmount) { 768e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov // Emit a special goodness here: 769e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov // srl A, 1 => clrc; rrc A 770bf8ef3f29de28529b5d65970af9015c41f7c809bAnton Korobeynikov Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim); 771e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov ShiftAmount -= 1; 772e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov } 773e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov 774d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov while (ShiftAmount--) 775aceb620de855485a4fb2eed343d880d76f6c701cAnton Korobeynikov Victim = DAG.getNode((Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA), 776ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov dl, VT, Victim); 777d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 778d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov return Victim; 779d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov} 780d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 781d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerGlobalAddress(SDValue Op, 782d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 7833513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); 7843513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset(); 7853513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov 7863513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov // Create the TargetGlobalAddress node, folding in the constant offset. 787ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDValue Result = DAG.getTargetGlobalAddress(GV, SDLoc(Op), 7880d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel getPointerTy(), Offset); 789ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick return DAG.getNode(MSP430ISD::Wrapper, SDLoc(Op), 7903513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov getPointerTy(), Result); 7913513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov} 7923513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov 7935d59f68ade7573175f1ace09061a94286e59076bAnton KorobeynikovSDValue MSP430TargetLowering::LowerExternalSymbol(SDValue Op, 794d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 795ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 7965d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol(); 7975d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov SDValue Result = DAG.getTargetExternalSymbol(Sym, getPointerTy()); 7985d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov 79990f20044ade3712c8b0c3f4ebe47d57ad15ae6ceChad Rosier return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result); 8005d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov} 8015d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov 80269d5b48bc31b7a443355cdf1506005804b4f63e6Anton KorobeynikovSDValue MSP430TargetLowering::LowerBlockAddress(SDValue Op, 80369d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov SelectionDAG &DAG) const { 804ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 80569d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress(); 8066c7ccaa3fd1d6e96d0bf922554b09d2b17c3b0e3Michael Liao SDValue Result = DAG.getTargetBlockAddress(BA, getPointerTy()); 80769d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov 80890f20044ade3712c8b0c3f4ebe47d57ad15ae6ceChad Rosier return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result); 80969d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov} 81069d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov 8113926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikovstatic SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC, 8121bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC, 813ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, SelectionDAG &DAG) { 814ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov // FIXME: Handle bittests someday 815ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet"); 816ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 817ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov // FIXME: Handle jump negative someday 8183926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov MSP430CC::CondCodes TCC = MSP430CC::COND_INVALID; 819ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov switch (CC) { 820c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Invalid integer condition!"); 821ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETEQ: 8223926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_E; // aka COND_Z 823f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov // Minor optimization: if LHS is a constant, swap operands, then the 8241722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov // constant can be folded into comparison. 825f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov if (LHS.getOpcode() == ISD::Constant) 8261722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov std::swap(LHS, RHS); 827ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 828ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETNE: 8293926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_NE; // aka COND_NZ 830f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov // Minor optimization: if LHS is a constant, swap operands, then the 8311722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov // constant can be folded into comparison. 832f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov if (LHS.getOpcode() == ISD::Constant) 8331722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov std::swap(LHS, RHS); 834ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 835ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETULE: 836ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 837ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETUGE: 8380c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // Turn lhs u>= rhs with lhs constant into rhs u< lhs+1, this allows us to 8390c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // fold constant into instruction. 8400c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 8410c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov LHS = RHS; 8420c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 8430c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_LO; 8440c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov break; 8450c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov } 8463926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_HS; // aka COND_C 847ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 848ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETUGT: 849ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 850ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETULT: 8510c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // Turn lhs u< rhs with lhs constant into rhs u>= lhs+1, this allows us to 8520c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // fold constant into instruction. 8530c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 8540c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov LHS = RHS; 8550c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 8560c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_HS; 8570c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov break; 8580c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov } 8593926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_LO; // aka COND_NC 860ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 861ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETLE: 862ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 863ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETGE: 8640c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // Turn lhs >= rhs with lhs constant into rhs < lhs+1, this allows us to 8650c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // fold constant into instruction. 8660c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 8670c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov LHS = RHS; 8680c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 8690c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_L; 8700c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov break; 8710c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov } 8723926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_GE; 873ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 874ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETGT: 875ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 876ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETLT: 8770c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to 8780c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // fold constant into instruction. 8790c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 8800c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov LHS = RHS; 8810c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 8820c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_GE; 8830c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov break; 8840c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov } 8853926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_L; 886ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 887ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov } 888ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 8893926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TargetCC = DAG.getConstant(TCC, MVT::i8); 890f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner return DAG.getNode(MSP430ISD::CMP, dl, MVT::Glue, LHS, RHS); 891ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov} 892ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 8931bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 894d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const { 895ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov SDValue Chain = Op.getOperand(0); 8961bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); 8971bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue LHS = Op.getOperand(2); 8981bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue RHS = Op.getOperand(3); 8991bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Dest = Op.getOperand(4); 900ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl (Op); 9011bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 9023926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov SDValue TargetCC; 9031bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 9041bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 9051bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(), 9063926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov Chain, Dest, TargetCC, Flag); 907ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov} 908ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 909d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const { 9108d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue LHS = Op.getOperand(0); 9118d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue RHS = Op.getOperand(1); 912ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl (Op); 9138d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov 9148d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // If we are doing an AND and testing against zero, then the CMP 9158d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // will not be generated. The AND (or BIT) will generate the condition codes, 9168d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // but they are different from CMP. 917cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov // FIXME: since we're doing a post-processing, use a pseudoinstr here, so 918cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov // lowering & isel wouldn't diverge. 9198d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov bool andCC = false; 9208d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) { 9218d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (RHSC->isNullValue() && LHS.hasOneUse() && 9228d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov (LHS.getOpcode() == ISD::AND || 9238d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov (LHS.getOpcode() == ISD::TRUNCATE && 9248d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov LHS.getOperand(0).getOpcode() == ISD::AND))) { 9258d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov andCC = true; 9268d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 9278d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 9288d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get(); 9298d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue TargetCC; 9308d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 9318d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov 9328d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Get the condition codes directly from the status register, if its easy. 9338d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Otherwise a branch will be generated. Note that the AND and BIT 9348d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // instructions generate different flags than CMP, the carry bit can be used 9358d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // for NE/EQ. 9368d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov bool Invert = false; 9378d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov bool Shift = false; 9388d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov bool Convert = true; 9398d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov switch (cast<ConstantSDNode>(TargetCC)->getZExtValue()) { 9408d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov default: 9418d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Convert = false; 9428d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 9438d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov case MSP430CC::COND_HS: 9448d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Res = SRW & 1, no processing is required 9458d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 946cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov case MSP430CC::COND_LO: 9478d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Res = ~(SRW & 1) 9488d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Invert = true; 9498d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 950cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov case MSP430CC::COND_NE: 9518d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (andCC) { 9528d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // C = ~Z, thus Res = SRW & 1, no processing is required 9538d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } else { 954455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov // Res = ~((SRW >> 1) & 1) 9558d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Shift = true; 956455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov Invert = true; 9578d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 9588d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 959cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov case MSP430CC::COND_E: 960455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov Shift = true; 961455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov // C = ~Z for AND instruction, thus we can put Res = ~(SRW & 1), however, 962455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov // Res = (SRW >> 1) & 1 is 1 word shorter. 9638d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 9648d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 9658d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov EVT VT = Op.getValueType(); 9668d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue One = DAG.getConstant(1, VT); 9678d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (Convert) { 9688d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SRW, 969cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov MVT::i16, Flag); 9708d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (Shift) 9718d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // FIXME: somewhere this is turned into a SRL, lower it MSP specific? 9728d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One); 9738d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SR = DAG.getNode(ISD::AND, dl, MVT::i16, SR, One); 9748d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (Invert) 9758d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SR = DAG.getNode(ISD::XOR, dl, MVT::i16, SR, One); 9768d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov return SR; 9778d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } else { 9788d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue Zero = DAG.getConstant(0, VT); 979f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue); 9808d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SmallVector<SDValue, 4> Ops; 9818d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Ops.push_back(One); 9828d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Ops.push_back(Zero); 9838d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Ops.push_back(TargetCC); 9848d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Ops.push_back(Flag); 985dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, Ops); 9868d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 9878d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov} 9888d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov 989d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op, 990d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 9911bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue LHS = Op.getOperand(0); 9921bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue RHS = Op.getOperand(1); 9931bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue TrueV = Op.getOperand(2); 9941bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue FalseV = Op.getOperand(3); 9951bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); 996ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl (Op); 9971bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 9983926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov SDValue TargetCC; 9991bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 10008b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 1001f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue); 10028b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov SmallVector<SDValue, 4> Ops; 10038b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov Ops.push_back(TrueV); 10048b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov Ops.push_back(FalseV); 10053926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov Ops.push_back(TargetCC); 10061bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov Ops.push_back(Flag); 10078b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 1008dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, Ops); 10098b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov} 10108b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 1011b78e214274d397407b6167a293b7cd7c3b526ddeAnton KorobeynikovSDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op, 1012d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 1013b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov SDValue Val = Op.getOperand(0); 1014e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Op.getValueType(); 1015ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 1016b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 1017825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson assert(VT == MVT::i16 && "Only support i16 for now!"); 1018b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 1019b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT, 1020b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val), 1021b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov DAG.getValueType(Val.getValueType())); 1022b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov} 1023b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 1024d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue 1025d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanMSP430TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) const { 102606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MachineFunction &MF = DAG.getMachineFunction(); 102706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>(); 102806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov int ReturnAddrIndex = FuncInfo->getRAIndex(); 102906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 103006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov if (ReturnAddrIndex == 0) { 103106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov // Set up a frame object for the return address. 1032cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint64_t SlotSize = getDataLayout()->getPointerSize(); 103306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(SlotSize, -SlotSize, 1034ed2ae136d29dd36122d2476801e7d7a86e8301e3Evan Cheng true); 103506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov FuncInfo->setRAIndex(ReturnAddrIndex); 103606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov } 103706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 103806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy()); 103906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov} 104006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 1041d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op, 1042d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 10432457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 10442457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng MFI->setReturnAddressIsTaken(true); 10452457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng 104636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (verifyReturnAddressArgumentIsConstant(Op, DAG)) 104736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return SDValue(); 104836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 104906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); 1050ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 105106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 105206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov if (Depth > 0) { 105306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue FrameAddr = LowerFRAMEADDR(Op, DAG); 105406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue Offset = 1055cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines DAG.getConstant(getDataLayout()->getPointerSize(), MVT::i16); 105606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), 105706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov DAG.getNode(ISD::ADD, dl, getPointerTy(), 105806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov FrameAddr, Offset), 1059d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper MachinePointerInfo(), false, false, false, 0); 106006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov } 106106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 106206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov // Just load the return address. 106306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue RetAddrFI = getReturnAddressFrameIndex(DAG); 106406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), 1065d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper RetAddrFI, MachinePointerInfo(), false, false, false, 0); 106606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov} 106706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 1068d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op, 1069d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 107006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 107106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MFI->setFrameAddressIsTaken(true); 10722457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng 107306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov EVT VT = Op.getValueType(); 1074ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); // FIXME probably not meaningful 107506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); 107606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, 107706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MSP430::FPW, VT); 107806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov while (Depth--) 1079d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr, 1080d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner MachinePointerInfo(), 1081d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper false, false, false, 0); 108206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return FrameAddr; 108306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov} 108406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 10850ae61240341ca76e1329f251c64d2f475fa89278Anton KorobeynikovSDValue MSP430TargetLowering::LowerVASTART(SDValue Op, 10860ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov SelectionDAG &DAG) const { 10870ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov MachineFunction &MF = DAG.getMachineFunction(); 10880ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>(); 10890ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov 10900ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov // Frame index of first vararg argument 10910ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov SDValue FrameIndex = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), 10920ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov getPointerTy()); 10930ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); 10940ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov 10950ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov // Create a store of the frame index to the location operand 1096ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick return DAG.getStore(Op.getOperand(0), SDLoc(Op), FrameIndex, 10970ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov Op.getOperand(1), MachinePointerInfo(SV), 10980ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov false, false, 0); 10990ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov} 11000ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov 110127253f5edd04791bfbd0b5dd6e228be1d8071fceAnton KorobeynikovSDValue MSP430TargetLowering::LowerJumpTable(SDValue Op, 110227253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov SelectionDAG &DAG) const { 110327253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov JumpTableSDNode *JT = cast<JumpTableSDNode>(Op); 110427253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov SDValue Result = DAG.getTargetJumpTable(JT->getIndex(), getPointerTy()); 1105a77f816c4c6e4c833ac9ab78e2e038dcfb861c73Anton Korobeynikov return DAG.getNode(MSP430ISD::Wrapper, SDLoc(JT), 1106a77f816c4c6e4c833ac9ab78e2e038dcfb861c73Anton Korobeynikov getPointerTy(), Result); 110727253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov} 110827253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov 11096534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// getPostIndexedAddressParts - returns true by value, base pointer and 11106534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// offset pointer and addressing mode by reference if this node can be 11116534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// combined with a load / store to form a post-indexed load / store. 11126534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikovbool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op, 11136534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SDValue &Base, 11146534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SDValue &Offset, 11156534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov ISD::MemIndexedMode &AM, 11166534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SelectionDAG &DAG) const { 11176534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 11186534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov LoadSDNode *LD = cast<LoadSDNode>(N); 11196534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (LD->getExtensionType() != ISD::NON_EXTLOAD) 11206534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 11216534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 11226534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov EVT VT = LD->getMemoryVT(); 11236534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (VT != MVT::i8 && VT != MVT::i16) 11246534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 11256534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 11266534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (Op->getOpcode() != ISD::ADD) 11276534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 11286534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 11296534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) { 11306534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov uint64_t RHSC = RHS->getZExtValue(); 11316534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if ((VT == MVT::i16 && RHSC != 2) || 11326534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov (VT == MVT::i8 && RHSC != 1)) 11336534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 11346534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 11356534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov Base = Op->getOperand(0); 11366534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov Offset = DAG.getConstant(RHSC, VT); 11376534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov AM = ISD::POST_INC; 11386534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return true; 11396534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov } 11406534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 11416534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 11426534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov} 11436534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 11446534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 1145fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikovconst char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const { 1146fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov switch (Opcode) { 1147dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines default: return nullptr; 1148fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov case MSP430ISD::RET_FLAG: return "MSP430ISD::RET_FLAG"; 11496bfcba7e137113e5f38cc4f937ad61cc7253ec74Anton Korobeynikov case MSP430ISD::RETI_FLAG: return "MSP430ISD::RETI_FLAG"; 1150d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov case MSP430ISD::RRA: return "MSP430ISD::RRA"; 1151e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case MSP430ISD::RLA: return "MSP430ISD::RLA"; 1152e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case MSP430ISD::RRC: return "MSP430ISD::RRC"; 1153b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov case MSP430ISD::CALL: return "MSP430ISD::CALL"; 11543513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov case MSP430ISD::Wrapper: return "MSP430ISD::Wrapper"; 11551bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case MSP430ISD::BR_CC: return "MSP430ISD::BR_CC"; 1156ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case MSP430ISD::CMP: return "MSP430ISD::CMP"; 11571bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case MSP430ISD::SELECT_CC: return "MSP430ISD::SELECT_CC"; 11582625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430ISD::SHL: return "MSP430ISD::SHL"; 11592625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430ISD::SRA: return "MSP430ISD::SRA"; 1160fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 1161fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov} 11628b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 1163db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattnerbool MSP430TargetLowering::isTruncateFree(Type *Ty1, 1164db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *Ty2) const { 1165b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy()) 11669afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return false; 11679afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 11689afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return (Ty1->getPrimitiveSizeInBits() > Ty2->getPrimitiveSizeInBits()); 11699afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov} 11709afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 11719afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikovbool MSP430TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const { 11729afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov if (!VT1.isInteger() || !VT2.isInteger()) 11739afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return false; 11749afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 11759afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return (VT1.getSizeInBits() > VT2.getSizeInBits()); 11769afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov} 11779afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 1178db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattnerbool MSP430TargetLowering::isZExtFree(Type *Ty1, Type *Ty2) const { 11799afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov // MSP430 implicitly zero-extends 8-bit results in 16-bit registers. 1180b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands return 0 && Ty1->isIntegerTy(8) && Ty2->isIntegerTy(16); 11819afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov} 11829afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 11839afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikovbool MSP430TargetLowering::isZExtFree(EVT VT1, EVT VT2) const { 11849afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov // MSP430 implicitly zero-extends 8-bit results in 16-bit registers. 11859afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return 0 && VT1 == MVT::i8 && VT2 == MVT::i16; 11869afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov} 11879afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 1188968b667e27d7fc9a5bf5da52191a7af629e174dcEli Benderskybool MSP430TargetLowering::isZExtFree(SDValue Val, EVT VT2) const { 1189968b667e27d7fc9a5bf5da52191a7af629e174dcEli Bendersky return isZExtFree(Val.getValueType(), VT2); 1190968b667e27d7fc9a5bf5da52191a7af629e174dcEli Bendersky} 1191968b667e27d7fc9a5bf5da52191a7af629e174dcEli Bendersky 11928b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===// 11938b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov// Other Lowering Code 11948b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===// 11958b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 11968b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMachineBasicBlock* 11972625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMSP430TargetLowering::EmitShiftInstr(MachineInstr *MI, 1198af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman MachineBasicBlock *BB) const { 11992625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineFunction *F = BB->getParent(); 12002625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineRegisterInfo &RI = F->getRegInfo(); 12012625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov DebugLoc dl = MI->getDebugLoc(); 12022625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); 12032625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 12042625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned Opc; 12052625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov const TargetRegisterClass * RC; 12062625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov switch (MI->getOpcode()) { 1207bc2198133a1836598b54b943420748e75d5dea94Craig Topper default: llvm_unreachable("Invalid shift opcode!"); 12082625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Shl8: 12092625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SHL8r1; 1210420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR8RegClass; 12112625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 12122625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Shl16: 12132625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SHL16r1; 1214420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR16RegClass; 12152625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 12162625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Sra8: 12172625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR8r1; 1218420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR8RegClass; 12192625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 12202625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Sra16: 12212625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR16r1; 1222420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR16RegClass; 12232625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 12242625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Srl8: 12252625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR8r1c; 1226420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR8RegClass; 12272625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 12282625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Srl16: 12292625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR16r1c; 1230420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR16RegClass; 12312625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 12322625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov } 12332625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 12342625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov const BasicBlock *LLVM_BB = BB->getBasicBlock(); 12352625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineFunction::iterator I = BB; 12362625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov ++I; 12372625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 12382625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Create loop block 12392625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB); 12402625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineBasicBlock *RemBB = F->CreateMachineBasicBlock(LLVM_BB); 12412625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 12422625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov F->insert(I, LoopBB); 12432625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov F->insert(I, RemBB); 12442625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 12452625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Update machine-CFG edges by transferring all successors of the current 12462625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // block to the block containing instructions after shift. 124736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RemBB->splice(RemBB->begin(), BB, std::next(MachineBasicBlock::iterator(MI)), 124814152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BB->end()); 124914152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman RemBB->transferSuccessorsAndUpdatePHIs(BB); 12502625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 12512625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Add adges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB 12522625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BB->addSuccessor(LoopBB); 12532625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BB->addSuccessor(RemBB); 12542625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov LoopBB->addSuccessor(RemBB); 12552625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov LoopBB->addSuccessor(LoopBB); 12562625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 1257420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper unsigned ShiftAmtReg = RI.createVirtualRegister(&MSP430::GR8RegClass); 1258420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper unsigned ShiftAmtReg2 = RI.createVirtualRegister(&MSP430::GR8RegClass); 12592625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned ShiftReg = RI.createVirtualRegister(RC); 12602625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned ShiftReg2 = RI.createVirtualRegister(RC); 12612625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned ShiftAmtSrcReg = MI->getOperand(2).getReg(); 12622625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned SrcReg = MI->getOperand(1).getReg(); 12632625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned DstReg = MI->getOperand(0).getReg(); 12642625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 12652625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // BB: 12662625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // cmp 0, N 12672625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // je RemBB 1268f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov BuildMI(BB, dl, TII.get(MSP430::CMP8ri)) 1269f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov .addReg(ShiftAmtSrcReg).addImm(0); 12702625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(BB, dl, TII.get(MSP430::JCC)) 12712625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addMBB(RemBB) 12722625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addImm(MSP430CC::COND_E); 12732625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 12742625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // LoopBB: 12752625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB] 12762625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // ShiftAmt = phi [%N, BB], [%ShiftAmt2, LoopBB] 12772625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // ShiftReg2 = shift ShiftReg 12782625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // ShiftAmt2 = ShiftAmt - 1; 12792625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftReg) 12802625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(SrcReg).addMBB(BB) 12812625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftReg2).addMBB(LoopBB); 12822625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg) 12832625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftAmtSrcReg).addMBB(BB) 12842625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftAmtReg2).addMBB(LoopBB); 12852625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2) 12862625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftReg); 12872625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2) 12882625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftAmtReg).addImm(1); 12892625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::JCC)) 12902625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addMBB(LoopBB) 12912625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addImm(MSP430CC::COND_NE); 12922625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 12932625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // RemBB: 12942625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB] 129514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BuildMI(*RemBB, RemBB->begin(), dl, TII.get(MSP430::PHI), DstReg) 12962625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(SrcReg).addMBB(BB) 12972625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftReg2).addMBB(LoopBB); 12982625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 129914152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman MI->eraseFromParent(); // The pseudo instruction is gone now. 13002625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return RemBB; 13012625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov} 13022625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 13032625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMachineBasicBlock* 13048b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 1305af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman MachineBasicBlock *BB) const { 13062625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned Opc = MI->getOpcode(); 13072625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 13082625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 || 13092625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc == MSP430::Sra8 || Opc == MSP430::Sra16 || 13102625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc == MSP430::Srl8 || Opc == MSP430::Srl16) 1311af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman return EmitShiftInstr(MI, BB); 13122625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 13138b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); 13148b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov DebugLoc dl = MI->getDebugLoc(); 13152625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 13162625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov assert((Opc == MSP430::Select16 || Opc == MSP430::Select8) && 13178b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov "Unexpected instr type to insert"); 13188b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 13198b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // To "insert" a SELECT instruction, we actually have to insert the diamond 13208b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // control-flow pattern. The incoming instruction knows the destination vreg 13218b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // to set, the condition code register to branch on, the true/false values to 13228b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // select between, and a branch opcode to use. 13238b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov const BasicBlock *LLVM_BB = BB->getBasicBlock(); 13248b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineFunction::iterator I = BB; 13258b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov ++I; 13268b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 13278b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // thisMBB: 13288b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // ... 13298b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // TrueVal = ... 13308b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // cmpTY ccX, r1, r2 13318b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // jCC copy1MBB 13328b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // fallthrough --> copy0MBB 13338b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *thisMBB = BB; 13348b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineFunction *F = BB->getParent(); 13358b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); 13368b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB); 13378b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov F->insert(I, copy0MBB); 13388b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov F->insert(I, copy1MBB); 13398b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Update machine-CFG edges by transferring all successors of the current 13408b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // block to the new block which will contain the Phi node for the select. 134114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman copy1MBB->splice(copy1MBB->begin(), BB, 134236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::next(MachineBasicBlock::iterator(MI)), BB->end()); 134314152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman copy1MBB->transferSuccessorsAndUpdatePHIs(BB); 13448b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Next, add the true and fallthrough blocks as its successors. 13458b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy0MBB); 13468b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy1MBB); 13478b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 134814152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BuildMI(BB, dl, TII.get(MSP430::JCC)) 134914152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman .addMBB(copy1MBB) 135014152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman .addImm(MI->getOperand(3).getImm()); 135114152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman 13528b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // copy0MBB: 13538b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // %FalseValue = ... 13548b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // # fallthrough to copy1MBB 13558b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB = copy0MBB; 13568b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 13578b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Update machine-CFG edges 13588b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy1MBB); 13598b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 13608b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // copy1MBB: 13618b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] 13628b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // ... 13638b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB = copy1MBB; 136414152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BuildMI(*BB, BB->begin(), dl, TII.get(MSP430::PHI), 13658b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MI->getOperand(0).getReg()) 13668b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB) 13678b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB); 13688b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 136914152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman MI->eraseFromParent(); // The pseudo instruction is gone now. 13708b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov return BB; 13718b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov} 1372