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 60ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesMSP430TargetLowering::MSP430TargetLowering(const TargetMachine &TM, 61ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const MSP430Subtarget &STI) 6237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines : TargetLowering(TM) { 6306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 64f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov // Set up the register classes. 65420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper addRegisterClass(MVT::i8, &MSP430::GR8RegClass); 66420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper addRegisterClass(MVT::i16, &MSP430::GR16RegClass); 67f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 68f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov // Compute derived properties from the register classes 69ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines computeRegisterProperties(STI.getRegisterInfo()); 70fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 711476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov // Provide all sorts of operation actions 7237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines setStackPointerRegisterToSaveRestore(MSP430::SP); 73c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov setBooleanContents(ZeroOrOneBooleanContent); 7428b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct? 75c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov 7606ac0820a6cefa6896000054d8e4906326c0cce6Anton Korobeynikov // We have post-incremented loads / stores. 776534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setIndexedLoadAction(ISD::POST_INC, MVT::i8, Legal); 786534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setIndexedLoadAction(ISD::POST_INC, MVT::i16, Legal); 796534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 80ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (MVT VT : MVT::integer_valuetypes()) { 81ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines setLoadExtAction(ISD::EXTLOAD, VT, MVT::i1, Promote); 82ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Promote); 83ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines setLoadExtAction(ISD::ZEXTLOAD, VT, MVT::i1, Promote); 84ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i8, Expand); 85ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i16, Expand); 86ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 8736b6e533c1aac85452438161f7034a9f54bd1830Anton Korobeynikov 8854f30d3fc94e055f13e6744378323d05c5c050baAnton Korobeynikov // We don't have any truncstores 89825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setTruncStoreAction(MVT::i16, MVT::i8, Expand); 90825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 91825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRA, MVT::i8, Custom); 92825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SHL, MVT::i8, Custom); 93825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRL, MVT::i8, Custom); 94825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRA, MVT::i16, Custom); 95825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SHL, MVT::i16, Custom); 96825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRL, MVT::i16, Custom); 97825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ROTL, MVT::i8, Expand); 98825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ROTR, MVT::i8, Expand); 99825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ROTL, MVT::i16, Expand); 100825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ROTR, MVT::i16, Expand); 101825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::GlobalAddress, MVT::i16, Custom); 102825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ExternalSymbol, MVT::i16, Custom); 10369d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov setOperationAction(ISD::BlockAddress, MVT::i16, Custom); 104825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BR_JT, MVT::Other, Expand); 105825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BR_CC, MVT::i8, Custom); 106825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BR_CC, MVT::i16, Custom); 107825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BRCOND, MVT::Other, Expand); 1088d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov setOperationAction(ISD::SETCC, MVT::i8, Custom); 1098d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov setOperationAction(ISD::SETCC, MVT::i16, Custom); 110825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT, MVT::i8, Expand); 111825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT, MVT::i16, Expand); 112825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT_CC, MVT::i8, Custom); 113825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT_CC, MVT::i16, Custom); 114825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SIGN_EXTEND, MVT::i16, Custom); 115379a087cc7175532ff0c24c60069da5eec596879Anton Korobeynikov setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i8, Expand); 116379a087cc7175532ff0c24c60069da5eec596879Anton Korobeynikov setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i16, Expand); 117825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 118825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTTZ, MVT::i8, Expand); 119825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTTZ, MVT::i16, Expand); 12063974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i8, Expand); 12163974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i16, Expand); 122825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTLZ, MVT::i8, Expand); 123825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTLZ, MVT::i16, Expand); 12463974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i8, Expand); 12563974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i16, Expand); 126825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTPOP, MVT::i8, Expand); 127825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTPOP, MVT::i16, Expand); 128825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 129825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SHL_PARTS, MVT::i8, Expand); 130825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SHL_PARTS, MVT::i16, Expand); 131825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRL_PARTS, MVT::i8, Expand); 132825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRL_PARTS, MVT::i16, Expand); 133825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRA_PARTS, MVT::i8, Expand); 134825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRA_PARTS, MVT::i16, Expand); 135825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 136825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); 137e4ce880dfa340bf45ddce10bb1dbe856553677b6Eli Friedman 1388725bd22bf91c29e2351a127295c19fea996e2c7Anton Korobeynikov // FIXME: Implement efficiently multiplication by a constant 1398983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::MUL, MVT::i8, Expand); 1408983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::MULHS, MVT::i8, Expand); 1418983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::MULHU, MVT::i8, Expand); 1428983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::SMUL_LOHI, MVT::i8, Expand); 1438983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::UMUL_LOHI, MVT::i8, Expand); 144825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::MUL, MVT::i16, Expand); 145825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::MULHS, MVT::i16, Expand); 146825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::MULHU, MVT::i16, Expand); 147825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SMUL_LOHI, MVT::i16, Expand); 148825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UMUL_LOHI, MVT::i16, Expand); 149825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 1508983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::UDIV, MVT::i8, Expand); 1518983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::UDIVREM, MVT::i8, Expand); 1528983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::UREM, MVT::i8, Expand); 1538983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::SDIV, MVT::i8, Expand); 1548983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::SDIVREM, MVT::i8, Expand); 1558983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::SREM, MVT::i8, Expand); 156825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UDIV, MVT::i16, Expand); 157825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UDIVREM, MVT::i16, Expand); 158825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UREM, MVT::i16, Expand); 159825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SDIV, MVT::i16, Expand); 160825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SDIVREM, MVT::i16, Expand); 161825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SREM, MVT::i16, Expand); 162b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov 1630ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov // varargs support 1640ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov setOperationAction(ISD::VASTART, MVT::Other, Custom); 1650ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov setOperationAction(ISD::VAARG, MVT::Other, Expand); 1660ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov setOperationAction(ISD::VAEND, MVT::Other, Expand); 1670ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov setOperationAction(ISD::VACOPY, MVT::Other, Expand); 16827253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov setOperationAction(ISD::JumpTable, MVT::i16, Custom); 1690ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov 170b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov // Libcalls names. 171b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov if (HWMultMode == HWMultIntr) { 172b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I8, "__mulqi3hw"); 173b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I16, "__mulhi3hw"); 174b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov } else if (HWMultMode == HWMultNoIntr) { 175b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I8, "__mulqi3hw_noint"); 176b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov setLibcallName(RTLIB::MUL_I16, "__mulhi3hw_noint"); 177b2de1ea29bbb6cde06d34eb3cfea4df9f99b5b8dAnton Korobeynikov } 178fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman 179fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman setMinFunctionAlignment(1); 180fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman setPrefFunctionAlignment(2); 181f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 182f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 183d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerOperation(SDValue Op, 184d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 185f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov switch (Op.getOpcode()) { 186ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov case ISD::SHL: // FALLTHROUGH 187e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case ISD::SRL: 1884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case ISD::SRA: return LowerShifts(Op, DAG); 1893513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); 19069d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); 1915d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG); 1928d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov case ISD::SETCC: return LowerSETCC(Op, DAG); 1931bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case ISD::BR_CC: return LowerBR_CC(Op, DAG); 1941bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); 195b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov case ISD::SIGN_EXTEND: return LowerSIGN_EXTEND(Op, DAG); 19606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); 19706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); 1980ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov case ISD::VASTART: return LowerVASTART(Op, DAG); 19927253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov case ISD::JumpTable: return LowerJumpTable(Op, DAG); 200f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov default: 201c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("unimplemented operand"); 202f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov } 203f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 204f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 205c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===// 206cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov// MSP430 Inline Assembly Support 207cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===// 208cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 209cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// getConstraintType - Given a constraint letter, return the type of 210cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// constraint it is for this target. 211cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovTargetLowering::ConstraintType 212cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainarMSP430TargetLowering::getConstraintType(StringRef Constraint) const { 213cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov if (Constraint.size() == 1) { 214cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov switch (Constraint[0]) { 215cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov case 'r': 216cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return C_RegisterClass; 217cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov default: 218cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov break; 219cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 220cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 221cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return TargetLowering::getConstraintType(Constraint); 222cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov} 223cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 224ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstd::pair<unsigned, const TargetRegisterClass *> 225ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesMSP430TargetLowering::getRegForInlineAsmConstraint( 226cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const { 227cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov if (Constraint.size() == 1) { 228cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov // GCC Constraint Letters 229cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov switch (Constraint[0]) { 230cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov default: break; 231cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov case 'r': // GENERAL_REGS 232cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov if (VT == MVT::i8) 233420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper return std::make_pair(0U, &MSP430::GR8RegClass); 234cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 235420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper return std::make_pair(0U, &MSP430::GR16RegClass); 236cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 237cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 238cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 239ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT); 240cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov} 241cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 242cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===// 243c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// Calling Convention Implementation 244c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===// 245c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 246f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430GenCallingConv.inc" 247c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 2483edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman/// For each argument in a function store the number of pieces it is composed 2493edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman/// of. 2503edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormantemplate<typename ArgT> 2513edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void ParseFunctionArgs(const SmallVectorImpl<ArgT> &Args, 2523edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman SmallVectorImpl<unsigned> &Out) { 2533edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman unsigned CurrentArgIndex = ~0U; 2543edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman for (unsigned i = 0, e = Args.size(); i != e; i++) { 2553edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman if (CurrentArgIndex == Args[i].OrigArgIndex) { 2563edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman Out.back()++; 2573edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman } else { 2583edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman Out.push_back(1); 2593edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman CurrentArgIndex++; 2603edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman } 2613edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman } 2623edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman} 2633edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 2643edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void AnalyzeVarArgs(CCState &State, 2653edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman const SmallVectorImpl<ISD::OutputArg> &Outs) { 2663edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman State.AnalyzeCallOperands(Outs, CC_MSP430_AssignStack); 2673edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman} 2683edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 2693edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void AnalyzeVarArgs(CCState &State, 2703edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman const SmallVectorImpl<ISD::InputArg> &Ins) { 2713edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman State.AnalyzeFormalArguments(Ins, CC_MSP430_AssignStack); 2723edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman} 2733edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 2743edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman/// Analyze incoming and outgoing function arguments. We need custom C++ code 2753edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman/// to handle special constraints in the ABI like reversing the order of the 2763edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman/// pieces of splitted arguments. In addition, all pieces of a certain argument 2773edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman/// have to be passed either using registers or the stack but never mixing both. 2783edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormantemplate<typename ArgT> 2793edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void AnalyzeArguments(CCState &State, 2803edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman SmallVectorImpl<CCValAssign> &ArgLocs, 2813edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman const SmallVectorImpl<ArgT> &Args) { 282dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines static const MCPhysReg RegList[] = { 28337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines MSP430::R15, MSP430::R14, MSP430::R13, MSP430::R12 2843edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman }; 2853edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman static const unsigned NbRegs = array_lengthof(RegList); 2863edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 2873edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman if (State.isVarArg()) { 2883edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman AnalyzeVarArgs(State, Args); 2893edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman return; 2903edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman } 2913edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 2923edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman SmallVector<unsigned, 4> ArgsParts; 2933edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman ParseFunctionArgs(Args, ArgsParts); 2943edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 2953edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman unsigned RegsLeft = NbRegs; 2963edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman bool UseStack = false; 2973edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman unsigned ValNo = 0; 2983edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 2993edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman for (unsigned i = 0, e = ArgsParts.size(); i != e; i++) { 3003edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman MVT ArgVT = Args[ValNo].VT; 3013edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman ISD::ArgFlagsTy ArgFlags = Args[ValNo].Flags; 3023edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman MVT LocVT = ArgVT; 3033edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman CCValAssign::LocInfo LocInfo = CCValAssign::Full; 3043edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 3053edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman // Promote i8 to i16 3063edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman if (LocVT == MVT::i8) { 3073edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman LocVT = MVT::i16; 3083edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman if (ArgFlags.isSExt()) 3093edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman LocInfo = CCValAssign::SExt; 3103edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman else if (ArgFlags.isZExt()) 3113edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman LocInfo = CCValAssign::ZExt; 3123edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman else 3133edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman LocInfo = CCValAssign::AExt; 3143edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman } 3153edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 3163edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman // Handle byval arguments 3173edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman if (ArgFlags.isByVal()) { 3183edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman State.HandleByVal(ValNo++, ArgVT, LocVT, LocInfo, 2, 2, ArgFlags); 3193edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman continue; 3203edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman } 3213edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 3223edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman unsigned Parts = ArgsParts[i]; 3233edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 3243edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman if (!UseStack && Parts <= RegsLeft) { 3253edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman unsigned FirstVal = ValNo; 3263edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman for (unsigned j = 0; j < Parts; j++) { 327ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned Reg = State.AllocateReg(RegList); 3283edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman State.addLoc(CCValAssign::getReg(ValNo++, ArgVT, Reg, LocVT, LocInfo)); 3293edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman RegsLeft--; 3303edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman } 3313edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 3323edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman // Reverse the order of the pieces to agree with the "big endian" format 3333edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman // required in the calling convention ABI. 3343edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman SmallVectorImpl<CCValAssign>::iterator B = ArgLocs.begin() + FirstVal; 3353edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman std::reverse(B, B + Parts); 3363edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman } else { 3373edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman UseStack = true; 3383edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman for (unsigned j = 0; j < Parts; j++) 3393edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman CC_MSP430_AssignStack(ValNo++, ArgVT, LocVT, LocInfo, ArgFlags, State); 3403edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman } 3413edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman } 3423edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman} 3433edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 3443edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void AnalyzeRetResult(CCState &State, 3453edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman const SmallVectorImpl<ISD::InputArg> &Ins) { 3463edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman State.AnalyzeCallResult(Ins, RetCC_MSP430); 3473edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman} 3483edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 3493edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void AnalyzeRetResult(CCState &State, 3503edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman const SmallVectorImpl<ISD::OutputArg> &Outs) { 3513edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman State.AnalyzeReturn(Outs, RetCC_MSP430); 3523edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman} 3533edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 3543edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormantemplate<typename ArgT> 3553edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noormanstatic void AnalyzeReturnValues(CCState &State, 3563edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman SmallVectorImpl<CCValAssign> &RVLocs, 3573edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman const SmallVectorImpl<ArgT> &Args) { 3583edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman AnalyzeRetResult(State, Args); 3593edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 3603edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman // Reverse splitted return values to get the "big endian" format required 3613edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman // to agree with the calling convention ABI. 3623edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman std::reverse(RVLocs.begin(), RVLocs.end()); 3633edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman} 3643edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman 36598ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 36698ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerFormalArguments(SDValue Chain, 36765c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, 36898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isVarArg, 36998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> 37098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Ins, 371ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, 37298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SelectionDAG &DAG, 373d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) 374d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman const { 37598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 37698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman switch (CallConv) { 377c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov default: 378c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Unsupported calling convention"); 379c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov case CallingConv::C: 380c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov case CallingConv::Fast: 38198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals); 382e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov case CallingConv::MSP430_INTR: 3834d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie if (Ins.empty()) 3844d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie return Chain; 38575361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("ISRs cannot have arguments"); 386c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 387c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov} 388c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 38998ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 390d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin HolewinskiMSP430TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, 391d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) const { 392d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SelectionDAG &DAG = CLI.DAG; 393ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc &dl = CLI.DL; 394a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs; 395a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper SmallVectorImpl<SDValue> &OutVals = CLI.OutVals; 396a0ec3f9b7b826b9b40b80199923b664bad808cceCraig Topper SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins; 397d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SDValue Chain = CLI.Chain; 398d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SDValue Callee = CLI.Callee; 399d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski bool &isTailCall = CLI.IsTailCall; 400d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski CallingConv::ID CallConv = CLI.CallConv; 401d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski bool isVarArg = CLI.IsVarArg; 402d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski 4030c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng // MSP430 target does not yet support tail call optimization. 4040c439eb2c8397996cbccaf2798e598052d9982c8Evan Cheng isTailCall = false; 40598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 40698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman switch (CallConv) { 4074428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov default: 408c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Unsupported calling convention"); 4094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CallingConv::Fast: 4104428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CallingConv::C: 41198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall, 412c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman Outs, OutVals, Ins, dl, DAG, InVals); 413e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov case CallingConv::MSP430_INTR: 41475361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("ISRs cannot be called directly"); 4154428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 4164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 4174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 418c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// LowerCCCArguments - transform physical registers into virtual registers and 419c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// generate load operations for arguments places on the stack. 420c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// FIXME: struct return stuff 42198ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 42298ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCArguments(SDValue Chain, 42365c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, 42498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isVarArg, 42598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> 42698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Ins, 427ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, 42898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SelectionDAG &DAG, 429d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) 430d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman const { 431c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineFunction &MF = DAG.getMachineFunction(); 432c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 433c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineRegisterInfo &RegInfo = MF.getRegInfo(); 4340ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>(); 435c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 436c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Assign locations to all of the incoming arguments. 437c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov SmallVector<CCValAssign, 16> ArgLocs; 43837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs, 43937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines *DAG.getContext()); 4403edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman AnalyzeArguments(CCInfo, ArgLocs, Ins); 441c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 4420ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov // Create frame index for the start of the first vararg value 4430ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov if (isVarArg) { 4440ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov unsigned Offset = CCInfo.getNextStackOffset(); 4450ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov FuncInfo->setVarArgsFrameIndex(MFI->CreateFixedObject(1, Offset, true)); 4460ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov } 447c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 448c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 449c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov CCValAssign &VA = ArgLocs[i]; 450c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.isRegLoc()) { 451c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Arguments passed in registers 452e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT RegVT = VA.getLocVT(); 453825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson switch (RegVT.getSimpleVT().SimpleTy) { 45495771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson default: 455804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin { 456dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#ifndef NDEBUG 4574437ae213d5435390f0750213b53ec807c047f22Chris Lattner errs() << "LowerFormalArguments Unhandled argument type: " 458825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson << RegVT.getSimpleVT().SimpleTy << "\n"; 459dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#endif 460dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines llvm_unreachable(nullptr); 461804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin } 462825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i16: 463420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper unsigned VReg = RegInfo.createVirtualRegister(&MSP430::GR16RegClass); 464c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov RegInfo.addLiveIn(VA.getLocReg(), VReg); 46598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, RegVT); 466c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 467c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // If this is an 8-bit value, it is really passed promoted to 16 468c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // bits. Insert an assert[sz]ext to capture this, then truncate to the 469c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // right size. 470c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.getLocInfo() == CCValAssign::SExt) 471c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue, 472c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov DAG.getValueType(VA.getValVT())); 473c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov else if (VA.getLocInfo() == CCValAssign::ZExt) 474c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue, 475c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov DAG.getValueType(VA.getValVT())); 476c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 477c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.getLocInfo() != CCValAssign::Full) 478c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); 479c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 48098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman InVals.push_back(ArgValue); 481c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 482c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } else { 483c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Sanity check 484c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov assert(VA.isMemLoc()); 4856cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov 4866cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov SDValue InVal; 4876cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov ISD::ArgFlagsTy Flags = Ins[i].Flags; 4886cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov 4896cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov if (Flags.isByVal()) { 4906cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov int FI = MFI->CreateFixedObject(Flags.getByValSize(), 4916cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov VA.getLocMemOffset(), true); 492cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar InVal = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout())); 4936cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov } else { 4946cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov // Load the argument to a virtual register 4956cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov unsigned ObjSize = VA.getLocVT().getSizeInBits()/8; 4966cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov if (ObjSize > 2) { 4976cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov errs() << "LowerFormalArguments Unhandled argument type: " 4986cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov << EVT(VA.getLocVT()).getEVTString() 4996cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov << "\n"; 5006cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov } 5016cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov // Create the frame index object for this incoming parameter... 5026cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true); 5036cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov 5046cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov // Create the SelectionDAG nodes corresponding to a load 5056cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov //from this parameter 5066cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov SDValue FIN = DAG.getFrameIndex(FI, MVT::i16); 507cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar InVal = DAG.getLoad( 508cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar VA.getLocVT(), dl, Chain, FIN, 509cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI), 510cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar false, false, false, 0); 511c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 5126cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov 5136cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov InVals.push_back(InVal); 514c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 515c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 516c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 51798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return Chain; 518c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov} 519fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 52098ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 52198ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerReturn(SDValue Chain, 52265c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 52398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::OutputArg> &Outs, 524c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman const SmallVectorImpl<SDValue> &OutVals, 525ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, SelectionDAG &DAG) const { 52698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 527fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // CCValAssign - represent the assignment of the return value to a location 528fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov SmallVector<CCValAssign, 16> RVLocs; 529fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 530e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov // ISRs cannot return any value. 5314d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie if (CallConv == CallingConv::MSP430_INTR && !Outs.empty()) 53275361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("ISRs cannot return any value"); 533e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov 534fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // CCState - Info about the registers and stack slot. 53537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs, 53637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines *DAG.getContext()); 537fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 53898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman // Analize return values. 5393edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman AnalyzeReturnValues(CCInfo, RVLocs, Outs); 540fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 541fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov SDValue Flag; 542294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen SmallVector<SDValue, 4> RetOps(1, Chain); 543fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 544fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // Copy the result values into the output registers. 545fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov for (unsigned i = 0; i != RVLocs.size(); ++i) { 546fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov CCValAssign &VA = RVLocs[i]; 547fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov assert(VA.isRegLoc() && "Can only return in registers!"); 548fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 549fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), 550c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman OutVals[i], Flag); 551fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 552dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov // Guarantee that all emitted copies are stuck together, 553dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov // avoiding something bad. 554fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov Flag = Chain.getValue(1); 555294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); 556fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 557fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 558e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov unsigned Opc = (CallConv == CallingConv::MSP430_INTR ? 559e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG); 560e662f7a8b22e7d31fb55e6502af94d49b78bc942Anton Korobeynikov 561294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen RetOps[0] = Chain; // Update chain. 562294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen 563294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen // Add the flag if we have it. 564fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (Flag.getNode()) 565294014e1585ef5e0c1bf17a9cf79039ce662b64fJakob Stoklund Olesen RetOps.push_back(Flag); 566fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 567dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return DAG.getNode(Opc, dl, MVT::Other, RetOps); 568fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov} 569fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 5704428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// LowerCCCCallTo - functions arguments are copied from virtual regs to 5714428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted. 5720bf3c99886bed6796eada8f65942ee6023fc6e89Job Noorman// TODO: sret. 57398ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 57498ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, 57565c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 57698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isTailCall, 57798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::OutputArg> 57898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Outs, 579c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman const SmallVectorImpl<SDValue> &OutVals, 58098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> &Ins, 581ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, SelectionDAG &DAG, 582d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) const { 5834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Analyze operands of the call, assigning locations to each operand. 5844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<CCValAssign, 16> ArgLocs; 58537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs, 58637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines *DAG.getContext()); 5873edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman AnalyzeArguments(CCInfo, ArgLocs, Outs); 5884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Get a count of how many bytes are to be pushed on the stack. 5904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov unsigned NumBytes = CCInfo.getNextStackOffset(); 591cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar auto PtrVT = getPointerTy(DAG.getDataLayout()); 5924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 593cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Chain = DAG.getCALLSEQ_START(Chain, 594cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar DAG.getConstant(NumBytes, dl, PtrVT, true), dl); 5954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass; 5974428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<SDValue, 12> MemOpChains; 5984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue StackPtr; 5994428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 6004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Walk the register/memloc assignments, inserting copies/loads. 6014428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 6024428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov CCValAssign &VA = ArgLocs[i]; 6034428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 604c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman SDValue Arg = OutVals[i]; 6054428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 6064428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Promote the value if needed. 6074428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov switch (VA.getLocInfo()) { 608c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Unknown loc info!"); 6094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::Full: break; 6104428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::SExt: 6114428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); 6124428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 6134428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::ZExt: 6144428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg); 6154428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 6164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::AExt: 6174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); 6184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 6194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 6204428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 6214428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Arguments that can be passed on register must be kept at RegsToPass 6224428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // vector 6234428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (VA.isRegLoc()) { 6244428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 6254428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } else { 6264428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov assert(VA.isMemLoc()); 6274428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 628dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!StackPtr.getNode()) 629cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SP, PtrVT); 6304428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 631cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar SDValue PtrOff = 632cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr, 633cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar DAG.getIntPtrConstant(VA.getLocMemOffset(), dl)); 6344428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 6356cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov SDValue MemOp; 6366cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov ISD::ArgFlagsTy Flags = Outs[i].Flags; 6376cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov 6386cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov if (Flags.isByVal()) { 6396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), dl, MVT::i16); 6406cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov MemOp = DAG.getMemcpy(Chain, dl, PtrOff, Arg, SizeNode, 6416cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov Flags.getByValAlign(), 6426cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov /*isVolatile*/false, 6436cbeb4d839a7fc465c651f0df0b090052cd87a5cAnton Korobeynikov /*AlwaysInline=*/true, 6440c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar /*isTailCall=*/false, 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. 698cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Chain = DAG.getCALLSEQ_END(Chain, DAG.getConstant(NumBytes, dl, PtrVT, true), 699cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar DAG.getConstant(0, dl, PtrVT, true), InFlag, dl); 7004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(1); 7014428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 7024428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Handle result values, copying them out of physregs into vregs that we 7034428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // return. 70498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl, 70598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DAG, InVals); 7064428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 7074428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 70898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// LowerCallResult - Lower the result values of a call into the 70998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// appropriate copies out of appropriate physical registers. 71098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// 71198ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 7124428885c5acfffbbdd03ad2aab23960531c47753Anton KorobeynikovMSP430TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, 71365c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 71498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> &Ins, 715ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, SelectionDAG &DAG, 716d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) const { 7174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 7184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Assign locations to each value returned by this call. 7194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<CCValAssign, 16> RVLocs; 72037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs, 72137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines *DAG.getContext()); 7224428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 7233edacfa97001b1eda9126bcabd68b15c7d8065f2Job Noorman AnalyzeReturnValues(CCInfo, RVLocs, Ins); 7244428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 7254428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Copy all of the result registers out of their specified physreg. 7264428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0; i != RVLocs.size(); ++i) { 7274428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(), 7284428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RVLocs[i].getValVT(), InFlag).getValue(1); 7294428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(2); 73098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman InVals.push_back(Chain.getValue(0)); 7314428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 7324428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 73398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return Chain; 7344428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 7354428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 736d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton KorobeynikovSDValue MSP430TargetLowering::LowerShifts(SDValue Op, 737d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 738ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov unsigned Opc = Op.getOpcode(); 739d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov SDNode* N = Op.getNode(); 740e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Op.getValueType(); 741ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(N); 742d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 7432625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Expand non-constant shifts to loops: 744d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov if (!isa<ConstantSDNode>(N->getOperand(1))) 7452625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov switch (Opc) { 746bc2198133a1836598b54b943420748e75d5dea94Craig Topper default: llvm_unreachable("Invalid shift opcode!"); 7472625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case ISD::SHL: 7482625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return DAG.getNode(MSP430ISD::SHL, dl, 7492625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov VT, N->getOperand(0), N->getOperand(1)); 7502625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case ISD::SRA: 7512625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return DAG.getNode(MSP430ISD::SRA, dl, 7522625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov VT, N->getOperand(0), N->getOperand(1)); 7532625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case ISD::SRL: 7542625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return DAG.getNode(MSP430ISD::SRL, dl, 7552625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov VT, N->getOperand(0), N->getOperand(1)); 7562625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov } 757d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 758d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue(); 759d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 760d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // Expand the stuff into sequence of shifts. 761d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // FIXME: for some shift amounts this might be done better! 762d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N 763d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov SDValue Victim = N->getOperand(0); 764e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov 765e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov if (Opc == ISD::SRL && ShiftAmount) { 766e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov // Emit a special goodness here: 767e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov // srl A, 1 => clrc; rrc A 768bf8ef3f29de28529b5d65970af9015c41f7c809bAnton Korobeynikov Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim); 769e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov ShiftAmount -= 1; 770e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov } 771e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov 772d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov while (ShiftAmount--) 773aceb620de855485a4fb2eed343d880d76f6c701cAnton Korobeynikov Victim = DAG.getNode((Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA), 774ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov dl, VT, Victim); 775d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 776d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov return Victim; 777d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov} 778d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 779d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerGlobalAddress(SDValue Op, 780d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 7813513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); 7823513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset(); 783cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar auto PtrVT = getPointerTy(DAG.getDataLayout()); 7843513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov 7853513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov // Create the TargetGlobalAddress node, folding in the constant offset. 786cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar SDValue Result = DAG.getTargetGlobalAddress(GV, SDLoc(Op), PtrVT, Offset); 787cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return DAG.getNode(MSP430ISD::Wrapper, SDLoc(Op), PtrVT, Result); 7883513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov} 7893513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov 7905d59f68ade7573175f1ace09061a94286e59076bAnton KorobeynikovSDValue MSP430TargetLowering::LowerExternalSymbol(SDValue Op, 791d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 792ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 7935d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol(); 794cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar auto PtrVT = getPointerTy(DAG.getDataLayout()); 795cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar SDValue Result = DAG.getTargetExternalSymbol(Sym, PtrVT); 7965d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov 797cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return DAG.getNode(MSP430ISD::Wrapper, dl, PtrVT, Result); 7985d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov} 7995d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov 80069d5b48bc31b7a443355cdf1506005804b4f63e6Anton KorobeynikovSDValue MSP430TargetLowering::LowerBlockAddress(SDValue Op, 80169d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov SelectionDAG &DAG) const { 802ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 803cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar auto PtrVT = getPointerTy(DAG.getDataLayout()); 80469d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress(); 805cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar SDValue Result = DAG.getTargetBlockAddress(BA, PtrVT); 80669d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov 807cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return DAG.getNode(MSP430ISD::Wrapper, dl, PtrVT, Result); 80869d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov} 80969d5b48bc31b7a443355cdf1506005804b4f63e6Anton Korobeynikov 8103926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikovstatic SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC, 8111bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC, 812ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl, SelectionDAG &DAG) { 813ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov // FIXME: Handle bittests someday 814ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet"); 815ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 816ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov // FIXME: Handle jump negative someday 8173926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov MSP430CC::CondCodes TCC = MSP430CC::COND_INVALID; 818ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov switch (CC) { 819c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Invalid integer condition!"); 820ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETEQ: 8213926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_E; // aka COND_Z 822f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov // Minor optimization: if LHS is a constant, swap operands, then the 8231722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov // constant can be folded into comparison. 824f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov if (LHS.getOpcode() == ISD::Constant) 8251722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov std::swap(LHS, RHS); 826ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 827ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETNE: 8283926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_NE; // aka COND_NZ 829f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov // Minor optimization: if LHS is a constant, swap operands, then the 8301722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov // constant can be folded into comparison. 831f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov if (LHS.getOpcode() == ISD::Constant) 8321722f061a3e7c2f6ef8be9f2f0f7c81ab763c7beAnton Korobeynikov std::swap(LHS, RHS); 833ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 834ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETULE: 835ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 836ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETUGE: 8370c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // Turn lhs u>= rhs with lhs constant into rhs u< lhs+1, this allows us to 8380c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // fold constant into instruction. 8390c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 8400c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov LHS = RHS; 8416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar RHS = DAG.getConstant(C->getSExtValue() + 1, dl, C->getValueType(0)); 8420c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_LO; 8430c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov break; 8440c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov } 8453926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_HS; // aka COND_C 846ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 847ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETUGT: 848ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 849ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETULT: 8500c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // Turn lhs u< rhs with lhs constant into rhs u>= lhs+1, this allows us to 8510c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // fold constant into instruction. 8520c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 8530c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov LHS = RHS; 8546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar RHS = DAG.getConstant(C->getSExtValue() + 1, dl, C->getValueType(0)); 8550c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_HS; 8560c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov break; 8570c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov } 8583926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_LO; // aka COND_NC 859ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 860ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETLE: 861ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 862ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETGE: 8630c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // Turn lhs >= rhs with lhs constant into rhs < lhs+1, this allows us to 8640c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // fold constant into instruction. 8650c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 8660c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov LHS = RHS; 8676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar RHS = DAG.getConstant(C->getSExtValue() + 1, dl, C->getValueType(0)); 8680c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_L; 8690c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov break; 8700c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov } 8713926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_GE; 872ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 873ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETGT: 874ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 875ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETLT: 8760c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to 8770c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov // fold constant into instruction. 8780c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 8790c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov LHS = RHS; 8806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar RHS = DAG.getConstant(C->getSExtValue() + 1, dl, C->getValueType(0)); 8810c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov TCC = MSP430CC::COND_GE; 8820c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov break; 8830c1ba91a54e7088fab3a3b9820f8b8366be0e11bAnton Korobeynikov } 8843926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_L; 885ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 886ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov } 887ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 8886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar TargetCC = DAG.getConstant(TCC, dl, MVT::i8); 889f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner return DAG.getNode(MSP430ISD::CMP, dl, MVT::Glue, LHS, RHS); 890ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov} 891ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 8921bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 893d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const { 894ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov SDValue Chain = Op.getOperand(0); 8951bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); 8961bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue LHS = Op.getOperand(2); 8971bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue RHS = Op.getOperand(3); 8981bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Dest = Op.getOperand(4); 899ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl (Op); 9001bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 9013926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov SDValue TargetCC; 9021bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 9031bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 9041bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(), 9053926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov Chain, Dest, TargetCC, Flag); 906ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov} 907ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 908d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const { 9098d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue LHS = Op.getOperand(0); 9108d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue RHS = Op.getOperand(1); 911ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl (Op); 9128d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov 9138d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // If we are doing an AND and testing against zero, then the CMP 9148d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // will not be generated. The AND (or BIT) will generate the condition codes, 9158d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // but they are different from CMP. 916cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov // FIXME: since we're doing a post-processing, use a pseudoinstr here, so 917cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov // lowering & isel wouldn't diverge. 9188d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov bool andCC = false; 9198d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) { 9208d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (RHSC->isNullValue() && LHS.hasOneUse() && 9218d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov (LHS.getOpcode() == ISD::AND || 9228d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov (LHS.getOpcode() == ISD::TRUNCATE && 9238d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov LHS.getOperand(0).getOpcode() == ISD::AND))) { 9248d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov andCC = true; 9258d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 9268d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 9278d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get(); 9288d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue TargetCC; 9298d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 9308d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov 9318d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Get the condition codes directly from the status register, if its easy. 9328d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // Otherwise a branch will be generated. Note that the AND and BIT 9338d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // instructions generate different flags than CMP, the carry bit can be used 9348d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // for NE/EQ. 9358d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov bool Invert = false; 9368d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov bool Shift = false; 9378d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov bool Convert = true; 9388d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov switch (cast<ConstantSDNode>(TargetCC)->getZExtValue()) { 9398d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov default: 9408d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Convert = false; 9418d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 9428d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov case MSP430CC::COND_HS: 94337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Res = SR & 1, no processing is required 9448d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 945cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov case MSP430CC::COND_LO: 94637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Res = ~(SR & 1) 9478d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Invert = true; 9488d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 949cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov case MSP430CC::COND_NE: 9508d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (andCC) { 95137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // C = ~Z, thus Res = SR & 1, no processing is required 9528d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } else { 95337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Res = ~((SR >> 1) & 1) 9548d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov Shift = true; 955455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov Invert = true; 9568d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 9578d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 958cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov case MSP430CC::COND_E: 959455080ff100c9383bc2619ae8ad86a02f61c3b00Anton Korobeynikov Shift = true; 96037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // C = ~Z for AND instruction, thus we can put Res = ~(SR & 1), however, 96137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Res = (SR >> 1) & 1 is 1 word shorter. 9628d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov break; 9638d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 9648d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov EVT VT = Op.getValueType(); 9656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SDValue One = DAG.getConstant(1, dl, VT); 9668d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (Convert) { 96737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SR, 968cb50e0bd60167440e2e41274f9d3c3c0e88d90adAnton Korobeynikov MVT::i16, Flag); 9698d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (Shift) 9708d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov // FIXME: somewhere this is turned into a SRL, lower it MSP specific? 9718d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One); 9728d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SR = DAG.getNode(ISD::AND, dl, MVT::i16, SR, One); 9738d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov if (Invert) 9748d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov SR = DAG.getNode(ISD::XOR, dl, MVT::i16, SR, One); 9758d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov return SR; 9768d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } else { 9776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SDValue Zero = DAG.getConstant(0, dl, VT); 978f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue); 979ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SDValue Ops[] = {One, Zero, TargetCC, Flag}; 980dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, Ops); 9818d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov } 9828d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov} 9838d1ffbd1adad453fe330be4951400bfd25fab666Anton Korobeynikov 984d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op, 985d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 9861bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue LHS = Op.getOperand(0); 9871bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue RHS = Op.getOperand(1); 9881bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue TrueV = Op.getOperand(2); 9891bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue FalseV = Op.getOperand(3); 9901bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); 991ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl (Op); 9921bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 9933926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov SDValue TargetCC; 9941bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 9958b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 996f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue); 997ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SDValue Ops[] = {TrueV, FalseV, TargetCC, Flag}; 9988b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 999dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, Ops); 10008b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov} 10018b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 1002b78e214274d397407b6167a293b7cd7c3b526ddeAnton KorobeynikovSDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op, 1003d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 1004b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov SDValue Val = Op.getOperand(0); 1005e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Op.getValueType(); 1006ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 1007b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 1008825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson assert(VT == MVT::i16 && "Only support i16 for now!"); 1009b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 1010b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT, 1011b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val), 1012b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov DAG.getValueType(Val.getValueType())); 1013b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov} 1014b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 1015d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue 1016d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanMSP430TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) const { 101706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MachineFunction &MF = DAG.getMachineFunction(); 101806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>(); 101906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov int ReturnAddrIndex = FuncInfo->getRAIndex(); 1020cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar auto PtrVT = getPointerTy(MF.getDataLayout()); 102106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 102206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov if (ReturnAddrIndex == 0) { 102306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov // Set up a frame object for the return address. 1024cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar uint64_t SlotSize = MF.getDataLayout().getPointerSize(); 102506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(SlotSize, -SlotSize, 1026ed2ae136d29dd36122d2476801e7d7a86e8301e3Evan Cheng true); 102706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov FuncInfo->setRAIndex(ReturnAddrIndex); 102806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov } 102906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 1030cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return DAG.getFrameIndex(ReturnAddrIndex, PtrVT); 103106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov} 103206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 1033d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op, 1034d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 10352457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 10362457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng MFI->setReturnAddressIsTaken(true); 10372457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng 103836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (verifyReturnAddressArgumentIsConstant(Op, DAG)) 103936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return SDValue(); 104036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 104106ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); 1042ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); 1043cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar auto PtrVT = getPointerTy(DAG.getDataLayout()); 104406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 104506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov if (Depth > 0) { 104606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue FrameAddr = LowerFRAMEADDR(Op, DAG); 104706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue Offset = 1048cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar DAG.getConstant(DAG.getDataLayout().getPointerSize(), dl, MVT::i16); 1049cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), 1050cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar DAG.getNode(ISD::ADD, dl, PtrVT, FrameAddr, Offset), 1051d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper MachinePointerInfo(), false, false, false, 0); 105206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov } 105306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 105406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov // Just load the return address. 105506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue RetAddrFI = getReturnAddressFrameIndex(DAG); 1056cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), RetAddrFI, 1057cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar MachinePointerInfo(), false, false, false, 0); 105806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov} 105906ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 1060d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op, 1061d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 106206ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 106306ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov MFI->setFrameAddressIsTaken(true); 10642457f2c66184e978d4ed8fa9e2128effff26cb0bEvan Cheng 106506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov EVT VT = Op.getValueType(); 1066ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick SDLoc dl(Op); // FIXME probably not meaningful 106706ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); 106806ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, 106937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines MSP430::FP, VT); 107006ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov while (Depth--) 1071d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr, 1072d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner MachinePointerInfo(), 1073d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper false, false, false, 0); 107406ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov return FrameAddr; 107506ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov} 107606ccca5f70ef5f9c3e4add60b6fc842916705029Anton Korobeynikov 10770ae61240341ca76e1329f251c64d2f475fa89278Anton KorobeynikovSDValue MSP430TargetLowering::LowerVASTART(SDValue Op, 10780ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov SelectionDAG &DAG) const { 10790ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov MachineFunction &MF = DAG.getMachineFunction(); 10800ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>(); 1081cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar auto PtrVT = getPointerTy(DAG.getDataLayout()); 10820ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov 10830ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov // Frame index of first vararg argument 1084cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar SDValue FrameIndex = 1085cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT); 10860ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); 10870ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov 10880ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov // Create a store of the frame index to the location operand 1089ac6d9bec671252dd1e596fa71180ff6b39d06b5dAndrew Trick return DAG.getStore(Op.getOperand(0), SDLoc(Op), FrameIndex, 10900ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov Op.getOperand(1), MachinePointerInfo(SV), 10910ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov false, false, 0); 10920ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov} 10930ae61240341ca76e1329f251c64d2f475fa89278Anton Korobeynikov 109427253f5edd04791bfbd0b5dd6e228be1d8071fceAnton KorobeynikovSDValue MSP430TargetLowering::LowerJumpTable(SDValue Op, 109527253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov SelectionDAG &DAG) const { 109627253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov JumpTableSDNode *JT = cast<JumpTableSDNode>(Op); 1097cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar auto PtrVT = getPointerTy(DAG.getDataLayout()); 1098cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar SDValue Result = DAG.getTargetJumpTable(JT->getIndex(), PtrVT); 1099cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return DAG.getNode(MSP430ISD::Wrapper, SDLoc(JT), PtrVT, Result); 110027253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov} 110127253f5edd04791bfbd0b5dd6e228be1d8071fceAnton Korobeynikov 11026534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// getPostIndexedAddressParts - returns true by value, base pointer and 11036534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// offset pointer and addressing mode by reference if this node can be 11046534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// combined with a load / store to form a post-indexed load / store. 11056534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikovbool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op, 11066534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SDValue &Base, 11076534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SDValue &Offset, 11086534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov ISD::MemIndexedMode &AM, 11096534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SelectionDAG &DAG) const { 11106534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 11116534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov LoadSDNode *LD = cast<LoadSDNode>(N); 11126534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (LD->getExtensionType() != ISD::NON_EXTLOAD) 11136534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 11146534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 11156534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov EVT VT = LD->getMemoryVT(); 11166534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (VT != MVT::i8 && VT != MVT::i16) 11176534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 11186534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 11196534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (Op->getOpcode() != ISD::ADD) 11206534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 11216534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 11226534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) { 11236534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov uint64_t RHSC = RHS->getZExtValue(); 11246534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if ((VT == MVT::i16 && RHSC != 2) || 11256534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov (VT == MVT::i8 && RHSC != 1)) 11266534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 11276534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 11286534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov Base = Op->getOperand(0); 11296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Offset = DAG.getConstant(RHSC, SDLoc(N), VT); 11306534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov AM = ISD::POST_INC; 11316534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return true; 11326534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov } 11336534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 11346534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 11356534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov} 11366534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 11376534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 1138fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikovconst char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const { 11396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar switch ((MSP430ISD::NodeType)Opcode) { 11406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case MSP430ISD::FIRST_NUMBER: break; 1141fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov case MSP430ISD::RET_FLAG: return "MSP430ISD::RET_FLAG"; 11426bfcba7e137113e5f38cc4f937ad61cc7253ec74Anton Korobeynikov case MSP430ISD::RETI_FLAG: return "MSP430ISD::RETI_FLAG"; 1143d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov case MSP430ISD::RRA: return "MSP430ISD::RRA"; 1144e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case MSP430ISD::RLA: return "MSP430ISD::RLA"; 1145e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case MSP430ISD::RRC: return "MSP430ISD::RRC"; 1146b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov case MSP430ISD::CALL: return "MSP430ISD::CALL"; 11473513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov case MSP430ISD::Wrapper: return "MSP430ISD::Wrapper"; 11481bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case MSP430ISD::BR_CC: return "MSP430ISD::BR_CC"; 1149ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case MSP430ISD::CMP: return "MSP430ISD::CMP"; 11506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case MSP430ISD::SETCC: return "MSP430ISD::SETCC"; 11511bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case MSP430ISD::SELECT_CC: return "MSP430ISD::SELECT_CC"; 11522625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430ISD::SHL: return "MSP430ISD::SHL"; 11532625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430ISD::SRA: return "MSP430ISD::SRA"; 11546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case MSP430ISD::SRL: return "MSP430ISD::SRL"; 1155fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 11566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return nullptr; 1157fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov} 11588b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 1159db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattnerbool MSP430TargetLowering::isTruncateFree(Type *Ty1, 1160db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *Ty2) const { 1161b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy()) 11629afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return false; 11639afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 11649afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return (Ty1->getPrimitiveSizeInBits() > Ty2->getPrimitiveSizeInBits()); 11659afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov} 11669afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 11679afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikovbool MSP430TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const { 11689afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov if (!VT1.isInteger() || !VT2.isInteger()) 11699afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return false; 11709afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 11719afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return (VT1.getSizeInBits() > VT2.getSizeInBits()); 11729afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov} 11739afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 1174db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattnerbool MSP430TargetLowering::isZExtFree(Type *Ty1, Type *Ty2) const { 11759afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov // MSP430 implicitly zero-extends 8-bit results in 16-bit registers. 1176b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands return 0 && Ty1->isIntegerTy(8) && Ty2->isIntegerTy(16); 11779afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov} 11789afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 11799afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikovbool MSP430TargetLowering::isZExtFree(EVT VT1, EVT VT2) const { 11809afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov // MSP430 implicitly zero-extends 8-bit results in 16-bit registers. 11819afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov return 0 && VT1 == MVT::i8 && VT2 == MVT::i16; 11829afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov} 11839afb7c5fb3dfbbe207c87f69bc80098b83308785Anton Korobeynikov 1184968b667e27d7fc9a5bf5da52191a7af629e174dcEli Benderskybool MSP430TargetLowering::isZExtFree(SDValue Val, EVT VT2) const { 1185968b667e27d7fc9a5bf5da52191a7af629e174dcEli Bendersky return isZExtFree(Val.getValueType(), VT2); 1186968b667e27d7fc9a5bf5da52191a7af629e174dcEli Bendersky} 1187968b667e27d7fc9a5bf5da52191a7af629e174dcEli Bendersky 11888b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===// 11898b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov// Other Lowering Code 11908b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===// 11918b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 11928b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMachineBasicBlock* 11932625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMSP430TargetLowering::EmitShiftInstr(MachineInstr *MI, 1194af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman MachineBasicBlock *BB) const { 11952625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineFunction *F = BB->getParent(); 11962625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineRegisterInfo &RI = F->getRegInfo(); 11972625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov DebugLoc dl = MI->getDebugLoc(); 1198ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const TargetInstrInfo &TII = *F->getSubtarget().getInstrInfo(); 11992625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 12002625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned Opc; 12012625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov const TargetRegisterClass * RC; 12022625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov switch (MI->getOpcode()) { 1203bc2198133a1836598b54b943420748e75d5dea94Craig Topper default: llvm_unreachable("Invalid shift opcode!"); 12042625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Shl8: 12052625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SHL8r1; 1206420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR8RegClass; 12072625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 12082625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Shl16: 12092625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SHL16r1; 1210420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR16RegClass; 12112625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 12122625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Sra8: 12132625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR8r1; 1214420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR8RegClass; 12152625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 12162625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Sra16: 12172625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR16r1; 1218420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR16RegClass; 12192625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 12202625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Srl8: 12212625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR8r1c; 1222420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR8RegClass; 12232625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 12242625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov case MSP430::Srl16: 12252625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc = MSP430::SAR16r1c; 1226420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MSP430::GR16RegClass; 12272625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov break; 12282625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov } 12292625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 12302625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov const BasicBlock *LLVM_BB = BB->getBasicBlock(); 1231cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar MachineFunction::iterator I = ++BB->getIterator(); 12322625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 12332625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Create loop block 12342625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB); 12352625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov MachineBasicBlock *RemBB = F->CreateMachineBasicBlock(LLVM_BB); 12362625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 12372625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov F->insert(I, LoopBB); 12382625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov F->insert(I, RemBB); 12392625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 12402625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Update machine-CFG edges by transferring all successors of the current 12412625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // block to the block containing instructions after shift. 124236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RemBB->splice(RemBB->begin(), BB, std::next(MachineBasicBlock::iterator(MI)), 124314152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BB->end()); 124414152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman RemBB->transferSuccessorsAndUpdatePHIs(BB); 12452625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 12462625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // Add adges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB 12472625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BB->addSuccessor(LoopBB); 12482625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BB->addSuccessor(RemBB); 12492625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov LoopBB->addSuccessor(RemBB); 12502625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov LoopBB->addSuccessor(LoopBB); 12512625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 1252420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper unsigned ShiftAmtReg = RI.createVirtualRegister(&MSP430::GR8RegClass); 1253420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper unsigned ShiftAmtReg2 = RI.createVirtualRegister(&MSP430::GR8RegClass); 12542625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned ShiftReg = RI.createVirtualRegister(RC); 12552625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned ShiftReg2 = RI.createVirtualRegister(RC); 12562625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned ShiftAmtSrcReg = MI->getOperand(2).getReg(); 12572625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned SrcReg = MI->getOperand(1).getReg(); 12582625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned DstReg = MI->getOperand(0).getReg(); 12592625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 12602625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // BB: 12612625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // cmp 0, N 12622625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // je RemBB 1263f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov BuildMI(BB, dl, TII.get(MSP430::CMP8ri)) 1264f7ed979257726fe1566c243a3174da76a18c4f19Anton Korobeynikov .addReg(ShiftAmtSrcReg).addImm(0); 12652625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(BB, dl, TII.get(MSP430::JCC)) 12662625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addMBB(RemBB) 12672625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addImm(MSP430CC::COND_E); 12682625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 12692625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // LoopBB: 12702625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB] 12712625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // ShiftAmt = phi [%N, BB], [%ShiftAmt2, LoopBB] 12722625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // ShiftReg2 = shift ShiftReg 12732625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // ShiftAmt2 = ShiftAmt - 1; 12742625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftReg) 12752625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(SrcReg).addMBB(BB) 12762625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftReg2).addMBB(LoopBB); 12772625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg) 12782625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftAmtSrcReg).addMBB(BB) 12792625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftAmtReg2).addMBB(LoopBB); 12802625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2) 12812625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftReg); 12822625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2) 12832625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftAmtReg).addImm(1); 12842625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov BuildMI(LoopBB, dl, TII.get(MSP430::JCC)) 12852625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addMBB(LoopBB) 12862625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addImm(MSP430CC::COND_NE); 12872625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 12882625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // RemBB: 12892625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB] 129014152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BuildMI(*RemBB, RemBB->begin(), dl, TII.get(MSP430::PHI), DstReg) 12912625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(SrcReg).addMBB(BB) 12922625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov .addReg(ShiftReg2).addMBB(LoopBB); 12932625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 129414152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman MI->eraseFromParent(); // The pseudo instruction is gone now. 12952625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov return RemBB; 12962625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov} 12972625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 12982625de35eda2aec28bdec3370a81f533f9721736Anton KorobeynikovMachineBasicBlock* 12998b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 1300af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman MachineBasicBlock *BB) const { 13012625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov unsigned Opc = MI->getOpcode(); 13022625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 13032625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 || 13042625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc == MSP430::Sra8 || Opc == MSP430::Sra16 || 13052625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov Opc == MSP430::Srl8 || Opc == MSP430::Srl16) 1306af1d8ca44a18f304f207e209b3bdb94b590f86ffDan Gohman return EmitShiftInstr(MI, BB); 13072625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 1308ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const TargetInstrInfo &TII = *BB->getParent()->getSubtarget().getInstrInfo(); 13098b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov DebugLoc dl = MI->getDebugLoc(); 13102625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov 13112625de35eda2aec28bdec3370a81f533f9721736Anton Korobeynikov assert((Opc == MSP430::Select16 || Opc == MSP430::Select8) && 13128b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov "Unexpected instr type to insert"); 13138b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 13148b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // To "insert" a SELECT instruction, we actually have to insert the diamond 13158b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // control-flow pattern. The incoming instruction knows the destination vreg 13168b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // to set, the condition code register to branch on, the true/false values to 13178b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // select between, and a branch opcode to use. 13188b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov const BasicBlock *LLVM_BB = BB->getBasicBlock(); 1319cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar MachineFunction::iterator I = ++BB->getIterator(); 13208b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 13218b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // thisMBB: 13228b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // ... 13238b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // TrueVal = ... 13248b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // cmpTY ccX, r1, r2 13258b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // jCC copy1MBB 13268b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // fallthrough --> copy0MBB 13278b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *thisMBB = BB; 13288b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineFunction *F = BB->getParent(); 13298b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); 13308b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB); 13318b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov F->insert(I, copy0MBB); 13328b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov F->insert(I, copy1MBB); 13338b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Update machine-CFG edges by transferring all successors of the current 13348b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // block to the new block which will contain the Phi node for the select. 133514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman copy1MBB->splice(copy1MBB->begin(), BB, 133636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::next(MachineBasicBlock::iterator(MI)), BB->end()); 133714152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman copy1MBB->transferSuccessorsAndUpdatePHIs(BB); 13388b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Next, add the true and fallthrough blocks as its successors. 13398b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy0MBB); 13408b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy1MBB); 13418b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 134214152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BuildMI(BB, dl, TII.get(MSP430::JCC)) 134314152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman .addMBB(copy1MBB) 134414152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman .addImm(MI->getOperand(3).getImm()); 134514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman 13468b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // copy0MBB: 13478b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // %FalseValue = ... 13488b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // # fallthrough to copy1MBB 13498b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB = copy0MBB; 13508b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 13518b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Update machine-CFG edges 13528b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy1MBB); 13538b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 13548b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // copy1MBB: 13558b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] 13568b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // ... 13578b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB = copy1MBB; 135814152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman BuildMI(*BB, BB->begin(), dl, TII.get(MSP430::PHI), 13598b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MI->getOperand(0).getReg()) 13608b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB) 13618b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB); 13628b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 136314152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman MI->eraseFromParent(); // The pseudo instruction is gone now. 13648b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov return BB; 13658b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov} 1366