MSP430ISelLowering.cpp revision 6534f83ae8c39284ae51fbf478ce0c37d0c892a2
1f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//===-- MSP430ISelLowering.cpp - MSP430 DAG Lowering Implementation ------===// 2f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// 3f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// The LLVM Compiler Infrastructure 4f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// 5f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// This file is distributed under the University of Illinois Open Source 6f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// License. See LICENSE.TXT for details. 7f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// 8f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//===----------------------------------------------------------------------===// 9f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// 10f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// This file implements the MSP430TargetLowering class. 11f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov// 12f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov//===----------------------------------------------------------------------===// 13f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 14f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#define DEBUG_TYPE "msp430-lower" 15f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 16f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430ISelLowering.h" 17f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430.h" 18f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430TargetMachine.h" 19f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430Subtarget.h" 20f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/DerivedTypes.h" 21f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/Function.h" 22f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/Intrinsics.h" 23f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CallingConv.h" 24f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/GlobalVariable.h" 25f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/GlobalAlias.h" 26f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/CallingConvLower.h" 27f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h" 28f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineFunction.h" 29f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h" 30f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/MachineRegisterInfo.h" 31c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov#include "llvm/CodeGen/PseudoSourceValue.h" 32f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/SelectionDAGISel.h" 33f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/CodeGen/ValueTypes.h" 34f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner#include "llvm/Target/TargetLoweringObjectFile.h" 35f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/Support/Debug.h" 36804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin#include "llvm/Support/ErrorHandling.h" 374437ae213d5435390f0750213b53ec807c047f22Chris Lattner#include "llvm/Support/raw_ostream.h" 38f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/ADT/VectorExtras.h" 39f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovusing namespace llvm; 40f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 41f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovMSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) : 42f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner TargetLowering(tm, new TargetLoweringObjectFileELF()), 43f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner Subtarget(*tm.getSubtargetImpl()), TM(tm) { 44f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 45f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov // Set up the register classes. 46825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson addRegisterClass(MVT::i8, MSP430::GR8RegisterClass); 47825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson addRegisterClass(MVT::i16, MSP430::GR16RegisterClass); 48f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 49f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov // Compute derived properties from the register classes 50f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov computeRegisterProperties(); 51fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 521476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov // Provide all sorts of operation actions 531476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov 541476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov // Division is expensive 551476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov setIntDivIsCheap(false); 561476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov 57d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // Even if we have only 1 bit shift here, we can perform 58d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // shifts of the whole bitwidth 1 bit per step. 59825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setShiftAmountType(MVT::i8); 60d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 61c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov setStackPointerRegisterToSaveRestore(MSP430::SPW); 62c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov setBooleanContents(ZeroOrOneBooleanContent); 63c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov setSchedulingPreference(SchedulingForLatency); 64c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov 656534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov // We have post-incremented loads / stores 666534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setIndexedLoadAction(ISD::POST_INC, MVT::i8, Legal); 676534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setIndexedLoadAction(ISD::POST_INC, MVT::i16, Legal); 686534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 696534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); 706534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); 716534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); 726534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Expand); 73825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Expand); 7436b6e533c1aac85452438161f7034a9f54bd1830Anton Korobeynikov 7554f30d3fc94e055f13e6744378323d05c5c050baAnton Korobeynikov // We don't have any truncstores 76825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setTruncStoreAction(MVT::i16, MVT::i8, Expand); 77825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 78825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRA, MVT::i8, Custom); 79825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SHL, MVT::i8, Custom); 80825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRL, MVT::i8, Custom); 81825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRA, MVT::i16, Custom); 82825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SHL, MVT::i16, Custom); 83825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRL, MVT::i16, Custom); 84825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ROTL, MVT::i8, Expand); 85825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ROTR, MVT::i8, Expand); 86825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ROTL, MVT::i16, Expand); 87825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ROTR, MVT::i16, Expand); 88825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::GlobalAddress, MVT::i16, Custom); 89825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::ExternalSymbol, MVT::i16, Custom); 90825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BR_JT, MVT::Other, Expand); 91825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BRIND, MVT::Other, Expand); 92825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BR_CC, MVT::i8, Custom); 93825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BR_CC, MVT::i16, Custom); 94825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::BRCOND, MVT::Other, Expand); 95825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SETCC, MVT::i8, Expand); 96825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SETCC, MVT::i16, Expand); 97825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT, MVT::i8, Expand); 98825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT, MVT::i16, Expand); 99825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT_CC, MVT::i8, Custom); 100825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SELECT_CC, MVT::i16, Custom); 101825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SIGN_EXTEND, MVT::i16, Custom); 102379a087cc7175532ff0c24c60069da5eec596879Anton Korobeynikov setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i8, Expand); 103379a087cc7175532ff0c24c60069da5eec596879Anton Korobeynikov setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i16, Expand); 104825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 105825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTTZ, MVT::i8, Expand); 106825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTTZ, MVT::i16, Expand); 107825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTLZ, MVT::i8, Expand); 108825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTLZ, MVT::i16, Expand); 109825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTPOP, MVT::i8, Expand); 110825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::CTPOP, MVT::i16, Expand); 111825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 112825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SHL_PARTS, MVT::i8, Expand); 113825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SHL_PARTS, MVT::i16, Expand); 114825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRL_PARTS, MVT::i8, Expand); 115825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRL_PARTS, MVT::i16, Expand); 116825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRA_PARTS, MVT::i8, Expand); 117825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SRA_PARTS, MVT::i16, Expand); 118825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 119825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); 120e4ce880dfa340bf45ddce10bb1dbe856553677b6Eli Friedman 1218725bd22bf91c29e2351a127295c19fea996e2c7Anton Korobeynikov // FIXME: Implement efficiently multiplication by a constant 1228983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::MUL, MVT::i8, Expand); 1238983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::MULHS, MVT::i8, Expand); 1248983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::MULHU, MVT::i8, Expand); 1258983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::SMUL_LOHI, MVT::i8, Expand); 1268983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::UMUL_LOHI, MVT::i8, Expand); 127825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::MUL, MVT::i16, Expand); 128825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::MULHS, MVT::i16, Expand); 129825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::MULHU, MVT::i16, Expand); 130825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SMUL_LOHI, MVT::i16, Expand); 131825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UMUL_LOHI, MVT::i16, Expand); 132825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson 1338983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::UDIV, MVT::i8, Expand); 1348983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::UDIVREM, MVT::i8, Expand); 1358983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::UREM, MVT::i8, Expand); 1368983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::SDIV, MVT::i8, Expand); 1378983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::SDIVREM, MVT::i8, Expand); 1388983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov setOperationAction(ISD::SREM, MVT::i8, Expand); 139825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UDIV, MVT::i16, Expand); 140825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UDIVREM, MVT::i16, Expand); 141825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::UREM, MVT::i16, Expand); 142825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SDIV, MVT::i16, Expand); 143825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SDIVREM, MVT::i16, Expand); 144825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson setOperationAction(ISD::SREM, MVT::i16, Expand); 145f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 146f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 147b8639f52143c99a3902b83555db4c54766c783caAnton KorobeynikovSDValue MSP430TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { 148f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov switch (Op.getOpcode()) { 149ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov case ISD::SHL: // FALLTHROUGH 150e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case ISD::SRL: 1514428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case ISD::SRA: return LowerShifts(Op, DAG); 1523513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); 1535d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG); 1541bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case ISD::BR_CC: return LowerBR_CC(Op, DAG); 1551bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); 156b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov case ISD::SIGN_EXTEND: return LowerSIGN_EXTEND(Op, DAG); 157f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov default: 158c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("unimplemented operand"); 159f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov return SDValue(); 160f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov } 161f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 162f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 163b4202b84d7e54efe5e144885c7da63e6cc465f80Bill Wendling/// getFunctionAlignment - Return the Log2 alignment of this function. 16420c568f366be211323eeaf0e45ef053278ec9ddcBill Wendlingunsigned MSP430TargetLowering::getFunctionAlignment(const Function *F) const { 16520c568f366be211323eeaf0e45ef053278ec9ddcBill Wendling return F->hasFnAttr(Attribute::OptimizeForSize) ? 1 : 4; 16620c568f366be211323eeaf0e45ef053278ec9ddcBill Wendling} 16720c568f366be211323eeaf0e45ef053278ec9ddcBill Wendling 168c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===// 169cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov// MSP430 Inline Assembly Support 170cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===// 171cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 172cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// getConstraintType - Given a constraint letter, return the type of 173cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov/// constraint it is for this target. 174cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovTargetLowering::ConstraintType 175cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering::getConstraintType(const std::string &Constraint) const { 176cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov if (Constraint.size() == 1) { 177cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov switch (Constraint[0]) { 178cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov case 'r': 179cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return C_RegisterClass; 180cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov default: 181cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov break; 182cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 183cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 184cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return TargetLowering::getConstraintType(Constraint); 185cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov} 186cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 187cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikovstd::pair<unsigned, const TargetRegisterClass*> 188cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovMSP430TargetLowering:: 189cd76128f182b9a9f3986384523cf90f4c30e4d35Anton KorobeynikovgetRegForInlineAsmConstraint(const std::string &Constraint, 190cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov EVT VT) const { 191cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov if (Constraint.size() == 1) { 192cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov // GCC Constraint Letters 193cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov switch (Constraint[0]) { 194cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov default: break; 195cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov case 'r': // GENERAL_REGS 196cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov if (VT == MVT::i8) 197cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return std::make_pair(0U, MSP430::GR8RegisterClass); 198cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 199cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return std::make_pair(0U, MSP430::GR16RegisterClass); 200cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 201cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov } 202cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 203cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); 204cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov} 205cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov 206cd76128f182b9a9f3986384523cf90f4c30e4d35Anton Korobeynikov//===----------------------------------------------------------------------===// 207c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// Calling Convention Implementation 208c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===// 209c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 210f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430GenCallingConv.inc" 211c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 21298ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 21398ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerFormalArguments(SDValue Chain, 21465c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, 21598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isVarArg, 21698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> 21798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Ins, 21898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DebugLoc dl, 21998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SelectionDAG &DAG, 22098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SmallVectorImpl<SDValue> &InVals) { 22198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 22298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman switch (CallConv) { 223c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov default: 224c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Unsupported calling convention"); 225c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov case CallingConv::C: 226c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov case CallingConv::Fast: 22798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals); 228c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 229c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov} 230c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 23198ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 23298ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCall(SDValue Chain, SDValue Callee, 23365c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 23498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isTailCall, 23598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::OutputArg> &Outs, 23698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> &Ins, 23798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DebugLoc dl, SelectionDAG &DAG, 23898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SmallVectorImpl<SDValue> &InVals) { 23998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 24098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman switch (CallConv) { 2414428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov default: 242c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Unsupported calling convention"); 2434428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CallingConv::Fast: 2444428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CallingConv::C: 24598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall, 24698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman Outs, Ins, dl, DAG, InVals); 2474428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 2484428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 2494428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 250c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// LowerCCCArguments - transform physical registers into virtual registers and 251c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// generate load operations for arguments places on the stack. 252c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// FIXME: struct return stuff 253c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// FIXME: varargs 25498ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 25598ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCArguments(SDValue Chain, 25665c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, 25798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isVarArg, 25898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> 25998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Ins, 26098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DebugLoc dl, 26198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SelectionDAG &DAG, 26298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SmallVectorImpl<SDValue> &InVals) { 263c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineFunction &MF = DAG.getMachineFunction(); 264c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 265c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineRegisterInfo &RegInfo = MF.getRegInfo(); 266c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 267c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Assign locations to all of the incoming arguments. 268c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov SmallVector<CCValAssign, 16> ArgLocs; 26998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCState CCInfo(CallConv, isVarArg, getTargetMachine(), 27098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman ArgLocs, *DAG.getContext()); 27198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeFormalArguments(Ins, CC_MSP430); 272c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 273c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov assert(!isVarArg && "Varargs not supported yet"); 274c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 275c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 276c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov CCValAssign &VA = ArgLocs[i]; 277c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.isRegLoc()) { 278c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Arguments passed in registers 279e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT RegVT = VA.getLocVT(); 280825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson switch (RegVT.getSimpleVT().SimpleTy) { 281804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin default: 282804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin { 283dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#ifndef NDEBUG 2844437ae213d5435390f0750213b53ec807c047f22Chris Lattner errs() << "LowerFormalArguments Unhandled argument type: " 285825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson << RegVT.getSimpleVT().SimpleTy << "\n"; 286dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#endif 287c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable(0); 288804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin } 289825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i16: 290c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov unsigned VReg = 2911df221f2bb8e8380e255d1bec73ab07b388d01a2Anton Korobeynikov RegInfo.createVirtualRegister(MSP430::GR16RegisterClass); 292c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov RegInfo.addLiveIn(VA.getLocReg(), VReg); 29398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, RegVT); 294c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 295c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // If this is an 8-bit value, it is really passed promoted to 16 296c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // bits. Insert an assert[sz]ext to capture this, then truncate to the 297c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // right size. 298c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.getLocInfo() == CCValAssign::SExt) 299c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue, 300c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov DAG.getValueType(VA.getValVT())); 301c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov else if (VA.getLocInfo() == CCValAssign::ZExt) 302c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue, 303c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov DAG.getValueType(VA.getValVT())); 304c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 305c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.getLocInfo() != CCValAssign::Full) 306c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); 307c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 30898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman InVals.push_back(ArgValue); 309c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 310c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } else { 311c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Sanity check 312c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov assert(VA.isMemLoc()); 313c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Load the argument to a virtual register 314c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov unsigned ObjSize = VA.getLocVT().getSizeInBits()/8; 315c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (ObjSize > 2) { 3164437ae213d5435390f0750213b53ec807c047f22Chris Lattner errs() << "LowerFormalArguments Unhandled argument type: " 317825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson << VA.getLocVT().getSimpleVT().SimpleTy 318c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov << "\n"; 319c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 320c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Create the frame index object for this incoming parameter... 321c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset()); 322c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 323c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Create the SelectionDAG nodes corresponding to a load 324c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov //from this parameter 325825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue FIN = DAG.getFrameIndex(FI, MVT::i16); 32698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, 3276553155172a2e74feff1253837daa608123de54aEvan Cheng PseudoSourceValue::getFixedStack(FI), 0)); 328c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 329c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 330c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 33198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return Chain; 332c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov} 333fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 33498ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 33598ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerReturn(SDValue Chain, 33665c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 33798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::OutputArg> &Outs, 33898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DebugLoc dl, SelectionDAG &DAG) { 33998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 340fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // CCValAssign - represent the assignment of the return value to a location 341fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov SmallVector<CCValAssign, 16> RVLocs; 342fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 343fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // CCState - Info about the registers and stack slot. 34498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCState CCInfo(CallConv, isVarArg, getTargetMachine(), 34598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman RVLocs, *DAG.getContext()); 346fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 34798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman // Analize return values. 34898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeReturn(Outs, RetCC_MSP430); 349fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 350fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // If this is the first return lowered for this function, add the regs to the 351fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // liveout set for the function. 352fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (DAG.getMachineFunction().getRegInfo().liveout_empty()) { 353fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov for (unsigned i = 0; i != RVLocs.size(); ++i) 354fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (RVLocs[i].isRegLoc()) 355fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); 356fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 357fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 358fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov SDValue Flag; 359fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 360fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // Copy the result values into the output registers. 361fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov for (unsigned i = 0; i != RVLocs.size(); ++i) { 362fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov CCValAssign &VA = RVLocs[i]; 363fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov assert(VA.isRegLoc() && "Can only return in registers!"); 364fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 365fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), 36698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman Outs[i].Val, Flag); 367fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 368dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov // Guarantee that all emitted copies are stuck together, 369dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov // avoiding something bad. 370fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov Flag = Chain.getValue(1); 371fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 372fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 373fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (Flag.getNode()) 374825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson return DAG.getNode(MSP430ISD::RET_FLAG, dl, MVT::Other, Chain, Flag); 375fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 376fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // Return Void 377825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson return DAG.getNode(MSP430ISD::RET_FLAG, dl, MVT::Other, Chain); 378fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov} 379fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 3804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// LowerCCCCallTo - functions arguments are copied from virtual regs to 3814428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted. 3824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// TODO: sret. 38398ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 38498ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanMSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, 38565c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 38698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman bool isTailCall, 38798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::OutputArg> 38898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman &Outs, 38998ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> &Ins, 39098ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DebugLoc dl, SelectionDAG &DAG, 39198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SmallVectorImpl<SDValue> &InVals) { 3924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Analyze operands of the call, assigning locations to each operand. 3934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<CCValAssign, 16> ArgLocs; 39498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCState CCInfo(CallConv, isVarArg, getTargetMachine(), 39598ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman ArgLocs, *DAG.getContext()); 3964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 39798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeCallOperands(Outs, CC_MSP430); 3984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 3994428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Get a count of how many bytes are to be pushed on the stack. 4004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov unsigned NumBytes = CCInfo.getNextStackOffset(); 4014428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4024428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCALLSEQ_START(Chain ,DAG.getConstant(NumBytes, 4034428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov getPointerTy(), true)); 4044428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4054428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass; 4064428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<SDValue, 12> MemOpChains; 4074428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue StackPtr; 4084428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Walk the register/memloc assignments, inserting copies/loads. 4104428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 4114428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov CCValAssign &VA = ArgLocs[i]; 4124428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 41398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SDValue Arg = Outs[i].Val; 4144428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4154428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Promote the value if needed. 4164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov switch (VA.getLocInfo()) { 417c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Unknown loc info!"); 4184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::Full: break; 4194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::SExt: 4204428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); 4214428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 4224428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::ZExt: 4234428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg); 4244428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 4254428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::AExt: 4264428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); 4274428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 4284428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 4294428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4304428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Arguments that can be passed on register must be kept at RegsToPass 4314428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // vector 4324428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (VA.isRegLoc()) { 4334428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 4344428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } else { 4354428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov assert(VA.isMemLoc()); 4364428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4374428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (StackPtr.getNode() == 0) 4384428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SPW, getPointerTy()); 4394428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4404428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), 4414428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov StackPtr, 4424428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG.getIntPtrConstant(VA.getLocMemOffset())); 4434428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4444428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4454428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, 4464428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov PseudoSourceValue::getStack(), 4474428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov VA.getLocMemOffset())); 4484428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 4494428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 4504428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4514428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Transform all store nodes into one single node because all store nodes are 4524428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // independent of each other. 4534428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (!MemOpChains.empty()) 454825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 4554428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov &MemOpChains[0], MemOpChains.size()); 4564428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Build a sequence of copy-to-reg nodes chained together with token chain and 4584428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // flag operands which copy the outgoing args into registers. The InFlag in 4594428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // necessary since all emited instructions must be stuck together. 4604428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue InFlag; 4614428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 4624428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, 4634428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RegsToPass[i].second, InFlag); 4644428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(1); 4654428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 4664428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4674428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // If the callee is a GlobalAddress node (quite common, every direct call is) 4684428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 4694428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Likewise ExternalSymbol -> TargetExternalSymbol. 4704428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 471825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Callee = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i16); 4724428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) 473825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i16); 4744428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4754428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Returns a chain & a flag for retval copy to use. 476825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); 4774428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<SDValue, 8> Ops; 4784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(Chain); 4794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(Callee); 4804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4814428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Add argument registers to the end of the list so that they are 4824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // known live into the call. 4834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 4844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(DAG.getRegister(RegsToPass[i].first, 4854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RegsToPass[i].second.getValueType())); 4864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4874428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (InFlag.getNode()) 4884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(InFlag); 4894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getNode(MSP430ISD::CALL, dl, NodeTys, &Ops[0], Ops.size()); 4914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(1); 4924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Create the CALLSEQ_END node. 4944428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCALLSEQ_END(Chain, 4954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG.getConstant(NumBytes, getPointerTy(), true), 4964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG.getConstant(0, getPointerTy(), true), 4974428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag); 4984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(1); 4994428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Handle result values, copying them out of physregs into vregs that we 5014428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // return. 50298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl, 50398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DAG, InVals); 5044428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 5054428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 50698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// LowerCallResult - Lower the result values of a call into the 50798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// appropriate copies out of appropriate physical registers. 50898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman/// 50998ca4f2a325f72374a477f9deba7d09e8999c29bDan GohmanSDValue 5104428885c5acfffbbdd03ad2aab23960531c47753Anton KorobeynikovMSP430TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, 51165c3c8f323198b99b88b109654194540cf9b3fa5Sandeep Patel CallingConv::ID CallConv, bool isVarArg, 51298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman const SmallVectorImpl<ISD::InputArg> &Ins, 51398ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman DebugLoc dl, SelectionDAG &DAG, 51498ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman SmallVectorImpl<SDValue> &InVals) { 5154428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Assign locations to each value returned by this call. 5174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<CCValAssign, 16> RVLocs; 51898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCState CCInfo(CallConv, isVarArg, getTargetMachine(), 519e922c0201916e0b980ab3cfe91e1413e68d55647Owen Anderson RVLocs, *DAG.getContext()); 5204428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 52198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman CCInfo.AnalyzeCallResult(Ins, RetCC_MSP430); 5224428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 5234428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Copy all of the result registers out of their specified physreg. 5244428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0; i != RVLocs.size(); ++i) { 5254428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(), 5264428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RVLocs[i].getValVT(), InFlag).getValue(1); 5274428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(2); 52898ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman InVals.push_back(Chain.getValue(0)); 5294428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 5304428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 53198ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman return Chain; 5324428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 5334428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 534d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton KorobeynikovSDValue MSP430TargetLowering::LowerShifts(SDValue Op, 535d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov SelectionDAG &DAG) { 536ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov unsigned Opc = Op.getOpcode(); 537d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov SDNode* N = Op.getNode(); 538e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Op.getValueType(); 539d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov DebugLoc dl = N->getDebugLoc(); 540d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 541ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov // We currently only lower shifts of constant argument. 542d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov if (!isa<ConstantSDNode>(N->getOperand(1))) 543d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov return SDValue(); 544d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 545d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue(); 546d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 547d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // Expand the stuff into sequence of shifts. 548d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // FIXME: for some shift amounts this might be done better! 549d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N 550d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov SDValue Victim = N->getOperand(0); 551e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov 552e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov if (Opc == ISD::SRL && ShiftAmount) { 553e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov // Emit a special goodness here: 554e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov // srl A, 1 => clrc; rrc A 555bf8ef3f29de28529b5d65970af9015c41f7c809bAnton Korobeynikov Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim); 556e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov ShiftAmount -= 1; 557e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov } 558e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov 559d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov while (ShiftAmount--) 560aceb620de855485a4fb2eed343d880d76f6c701cAnton Korobeynikov Victim = DAG.getNode((Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA), 561ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov dl, VT, Victim); 562d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 563d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov return Victim; 564d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov} 565d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 5663513ca81c6beda087a281a66f1b0e612879c0aadAnton KorobeynikovSDValue MSP430TargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) { 5673513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); 5683513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset(); 5693513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov 5703513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov // Create the TargetGlobalAddress node, folding in the constant offset. 5713513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov SDValue Result = DAG.getTargetGlobalAddress(GV, getPointerTy(), Offset); 5723513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov return DAG.getNode(MSP430ISD::Wrapper, Op.getDebugLoc(), 5733513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov getPointerTy(), Result); 5743513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov} 5753513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov 5765d59f68ade7573175f1ace09061a94286e59076bAnton KorobeynikovSDValue MSP430TargetLowering::LowerExternalSymbol(SDValue Op, 5775d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov SelectionDAG &DAG) { 5785d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 5795d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol(); 5805d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov SDValue Result = DAG.getTargetExternalSymbol(Sym, getPointerTy()); 5815d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov 5825d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result);; 5835d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov} 5845d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov 5853926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikovstatic SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC, 5861bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC, 5871bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov DebugLoc dl, SelectionDAG &DAG) { 588ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov // FIXME: Handle bittests someday 589ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet"); 590ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 591ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov // FIXME: Handle jump negative someday 5923926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov MSP430CC::CondCodes TCC = MSP430CC::COND_INVALID; 593ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov switch (CC) { 594c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Invalid integer condition!"); 595ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETEQ: 5963926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_E; // aka COND_Z 597ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 598ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETNE: 5993926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_NE; // aka COND_NZ 600ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 601ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETULE: 602ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 603ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETUGE: 6043926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_HS; // aka COND_C 605ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 606ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETUGT: 607ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 608ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETULT: 6093926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_LO; // aka COND_NC 610ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 611ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETLE: 612ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 613ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETGE: 6143926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_GE; 615ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 616ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETGT: 617ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 618ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETLT: 6193926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TCC = MSP430CC::COND_L; 620ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 621ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov } 622ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 6233926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov TargetCC = DAG.getConstant(TCC, MVT::i8); 624825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson return DAG.getNode(MSP430ISD::CMP, dl, MVT::Flag, LHS, RHS); 625ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov} 626ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 6271bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 6281bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton KorobeynikovSDValue MSP430TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) { 629ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov SDValue Chain = Op.getOperand(0); 6301bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); 6311bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue LHS = Op.getOperand(2); 6321bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue RHS = Op.getOperand(3); 6331bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Dest = Op.getOperand(4); 6341bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 6351bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 6363926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov SDValue TargetCC; 6371bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 6381bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 6391bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(), 6403926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov Chain, Dest, TargetCC, Flag); 641ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov} 642ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 6431bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton KorobeynikovSDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) { 6441bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue LHS = Op.getOperand(0); 6451bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue RHS = Op.getOperand(1); 6461bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue TrueV = Op.getOperand(2); 6471bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue FalseV = Op.getOperand(3); 6481bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); 6498b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 6501bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 6513926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov SDValue TargetCC; 6521bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 6538b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 654825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Flag); 6558b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov SmallVector<SDValue, 4> Ops; 6568b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov Ops.push_back(TrueV); 6578b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov Ops.push_back(FalseV); 6583926fb63c24ceeefc0215b8e14eb81c85403639eAnton Korobeynikov Ops.push_back(TargetCC); 6591bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov Ops.push_back(Flag); 6608b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 6611bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size()); 6628b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov} 6638b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 664b78e214274d397407b6167a293b7cd7c3b526ddeAnton KorobeynikovSDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op, 665b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov SelectionDAG &DAG) { 666b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov SDValue Val = Op.getOperand(0); 667e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Op.getValueType(); 668b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 669b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 670825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson assert(VT == MVT::i16 && "Only support i16 for now!"); 671b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 672b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT, 673b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val), 674b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov DAG.getValueType(Val.getValueType())); 675b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov} 676b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 6776534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// getPostIndexedAddressParts - returns true by value, base pointer and 6786534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// offset pointer and addressing mode by reference if this node can be 6796534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov/// combined with a load / store to form a post-indexed load / store. 6806534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikovbool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op, 6816534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SDValue &Base, 6826534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SDValue &Offset, 6836534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov ISD::MemIndexedMode &AM, 6846534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov SelectionDAG &DAG) const { 6856534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 6866534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov LoadSDNode *LD = cast<LoadSDNode>(N); 6876534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (LD->getExtensionType() != ISD::NON_EXTLOAD) 6886534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 6896534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 6906534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov EVT VT = LD->getMemoryVT(); 6916534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (VT != MVT::i8 && VT != MVT::i16) 6926534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 6936534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 6946534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (Op->getOpcode() != ISD::ADD) 6956534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 6966534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 6976534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) { 6986534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov uint64_t RHSC = RHS->getZExtValue(); 6996534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov if ((VT == MVT::i16 && RHSC != 2) || 7006534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov (VT == MVT::i8 && RHSC != 1)) 7016534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 7026534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 7036534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov Base = Op->getOperand(0); 7046534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov Offset = DAG.getConstant(RHSC, VT); 7056534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov AM = ISD::POST_INC; 7066534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return true; 7076534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov } 7086534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 7096534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov return false; 7106534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov} 7116534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 7126534f83ae8c39284ae51fbf478ce0c37d0c892a2Anton Korobeynikov 713fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikovconst char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const { 714fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov switch (Opcode) { 715fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov default: return NULL; 716fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov case MSP430ISD::RET_FLAG: return "MSP430ISD::RET_FLAG"; 717d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov case MSP430ISD::RRA: return "MSP430ISD::RRA"; 718e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case MSP430ISD::RLA: return "MSP430ISD::RLA"; 719e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case MSP430ISD::RRC: return "MSP430ISD::RRC"; 720b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov case MSP430ISD::CALL: return "MSP430ISD::CALL"; 7213513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov case MSP430ISD::Wrapper: return "MSP430ISD::Wrapper"; 7221bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case MSP430ISD::BR_CC: return "MSP430ISD::BR_CC"; 723ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case MSP430ISD::CMP: return "MSP430ISD::CMP"; 7241bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case MSP430ISD::SELECT_CC: return "MSP430ISD::SELECT_CC"; 725fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 726fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov} 7278b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 7288b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===// 7298b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov// Other Lowering Code 7308b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===// 7318b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 7328b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMachineBasicBlock* 7338b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 734fb2e752e4175920d0531f2afc93a23d0cdf4db14Evan Cheng MachineBasicBlock *BB, 735fb2e752e4175920d0531f2afc93a23d0cdf4db14Evan Cheng DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const { 7368b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); 7378b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov DebugLoc dl = MI->getDebugLoc(); 738da4d2f63d8b138569ec732d970bb452a0403a3abAnton Korobeynikov assert((MI->getOpcode() == MSP430::Select16 || 739da4d2f63d8b138569ec732d970bb452a0403a3abAnton Korobeynikov MI->getOpcode() == MSP430::Select8) && 7408b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov "Unexpected instr type to insert"); 7418b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 7428b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // To "insert" a SELECT instruction, we actually have to insert the diamond 7438b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // control-flow pattern. The incoming instruction knows the destination vreg 7448b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // to set, the condition code register to branch on, the true/false values to 7458b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // select between, and a branch opcode to use. 7468b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov const BasicBlock *LLVM_BB = BB->getBasicBlock(); 7478b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineFunction::iterator I = BB; 7488b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov ++I; 7498b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 7508b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // thisMBB: 7518b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // ... 7528b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // TrueVal = ... 7538b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // cmpTY ccX, r1, r2 7548b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // jCC copy1MBB 7558b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // fallthrough --> copy0MBB 7568b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *thisMBB = BB; 7578b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineFunction *F = BB->getParent(); 7588b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); 7598b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB); 7608b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BuildMI(BB, dl, TII.get(MSP430::JCC)) 7618b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addMBB(copy1MBB) 7628b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addImm(MI->getOperand(3).getImm()); 7638b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov F->insert(I, copy0MBB); 7648b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov F->insert(I, copy1MBB); 765ce31910eae5bd4896fa6c27798e7b26885691d3bEvan Cheng // Inform sdisel of the edge changes. 766ce31910eae5bd4896fa6c27798e7b26885691d3bEvan Cheng for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), 767ce31910eae5bd4896fa6c27798e7b26885691d3bEvan Cheng SE = BB->succ_end(); SI != SE; ++SI) 768ce31910eae5bd4896fa6c27798e7b26885691d3bEvan Cheng EM->insert(std::make_pair(*SI, copy1MBB)); 7698b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Update machine-CFG edges by transferring all successors of the current 7708b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // block to the new block which will contain the Phi node for the select. 7718b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov copy1MBB->transferSuccessors(BB); 7728b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Next, add the true and fallthrough blocks as its successors. 7738b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy0MBB); 7748b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy1MBB); 7758b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 7768b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // copy0MBB: 7778b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // %FalseValue = ... 7788b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // # fallthrough to copy1MBB 7798b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB = copy0MBB; 7808b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 7818b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Update machine-CFG edges 7828b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy1MBB); 7838b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 7848b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // copy1MBB: 7858b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] 7868b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // ... 7878b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB = copy1MBB; 7888b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BuildMI(BB, dl, TII.get(MSP430::PHI), 7898b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MI->getOperand(0).getReg()) 7908b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB) 7918b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB); 7928b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 7938b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov F->DeleteMachineInstr(MI); // The pseudo instruction is gone now. 7948b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov return BB; 7958b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov} 796