MSP430ISelLowering.cpp revision 20c568f366be211323eeaf0e45ef053278ec9ddc
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" 34f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/Support/Debug.h" 35f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "llvm/ADT/VectorExtras.h" 36f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikovusing namespace llvm; 37f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 38f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton KorobeynikovMSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) : 39f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov TargetLowering(tm), Subtarget(*tm.getSubtargetImpl()), TM(tm) { 40f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 41f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov // Set up the register classes. 4254f30d3fc94e055f13e6744378323d05c5c050baAnton Korobeynikov addRegisterClass(MVT::i8, MSP430::GR8RegisterClass); 431df221f2bb8e8380e255d1bec73ab07b388d01a2Anton Korobeynikov addRegisterClass(MVT::i16, MSP430::GR16RegisterClass); 44f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 45f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov // Compute derived properties from the register classes 46f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov computeRegisterProperties(); 47fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 481476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov // Provide all sorts of operation actions 491476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov 501476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov // Division is expensive 511476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov setIntDivIsCheap(false); 521476d97037e07d17635468fcd3a2ee0111972574Anton Korobeynikov 53d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // Even if we have only 1 bit shift here, we can perform 54d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // shifts of the whole bitwidth 1 bit per step. 55d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov setShiftAmountType(MVT::i8); 56d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 57c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov setStackPointerRegisterToSaveRestore(MSP430::SPW); 58c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov setBooleanContents(ZeroOrOneBooleanContent); 59c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov setSchedulingPreference(SchedulingForLatency); 60c08163e72dca43ff5421a13505503314e0d7074aAnton Korobeynikov 618b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); 6236b6e533c1aac85452438161f7034a9f54bd1830Anton Korobeynikov setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); 6336b6e533c1aac85452438161f7034a9f54bd1830Anton Korobeynikov setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); 6436b6e533c1aac85452438161f7034a9f54bd1830Anton Korobeynikov setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Expand); 6536b6e533c1aac85452438161f7034a9f54bd1830Anton Korobeynikov setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Expand); 6636b6e533c1aac85452438161f7034a9f54bd1830Anton Korobeynikov 6754f30d3fc94e055f13e6744378323d05c5c050baAnton Korobeynikov // We don't have any truncstores 6854f30d3fc94e055f13e6744378323d05c5c050baAnton Korobeynikov setTruncStoreAction(MVT::i16, MVT::i8, Expand); 6954f30d3fc94e055f13e6744378323d05c5c050baAnton Korobeynikov 70bf8ef3f29de28529b5d65970af9015c41f7c809bAnton Korobeynikov setOperationAction(ISD::SRA, MVT::i8, Custom); 71bf8ef3f29de28529b5d65970af9015c41f7c809bAnton Korobeynikov setOperationAction(ISD::SHL, MVT::i8, Custom); 72bf8ef3f29de28529b5d65970af9015c41f7c809bAnton Korobeynikov setOperationAction(ISD::SRL, MVT::i8, Custom); 738b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov setOperationAction(ISD::SRA, MVT::i16, Custom); 74ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov setOperationAction(ISD::SHL, MVT::i16, Custom); 75e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov setOperationAction(ISD::SRL, MVT::i16, Custom); 76e4fdb8b8ffddc1be3f6f796964bed03a77770829Anton Korobeynikov setOperationAction(ISD::ROTL, MVT::i8, Expand); 77e4fdb8b8ffddc1be3f6f796964bed03a77770829Anton Korobeynikov setOperationAction(ISD::ROTR, MVT::i8, Expand); 78e4fdb8b8ffddc1be3f6f796964bed03a77770829Anton Korobeynikov setOperationAction(ISD::ROTL, MVT::i16, Expand); 79e4fdb8b8ffddc1be3f6f796964bed03a77770829Anton Korobeynikov setOperationAction(ISD::ROTR, MVT::i16, Expand); 808b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov setOperationAction(ISD::RET, MVT::Other, Custom); 818b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov setOperationAction(ISD::GlobalAddress, MVT::i16, Custom); 825d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov setOperationAction(ISD::ExternalSymbol, MVT::i16, Custom); 830dbf292f6888e04c7f53dbb485f251b7cde4541aAnton Korobeynikov setOperationAction(ISD::BR_JT, MVT::Other, Expand); 840dbf292f6888e04c7f53dbb485f251b7cde4541aAnton Korobeynikov setOperationAction(ISD::BRIND, MVT::Other, Expand); 851bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov setOperationAction(ISD::BR_CC, MVT::i8, Custom); 861bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov setOperationAction(ISD::BR_CC, MVT::i16, Custom); 871bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov setOperationAction(ISD::BRCOND, MVT::Other, Expand); 881bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov setOperationAction(ISD::SETCC, MVT::i8, Expand); 891bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov setOperationAction(ISD::SETCC, MVT::i16, Expand); 901bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov setOperationAction(ISD::SELECT, MVT::i8, Expand); 911bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov setOperationAction(ISD::SELECT, MVT::i16, Expand); 921bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov setOperationAction(ISD::SELECT_CC, MVT::i8, Custom); 931bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov setOperationAction(ISD::SELECT_CC, MVT::i16, Custom); 94b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov setOperationAction(ISD::SIGN_EXTEND, MVT::i16, Custom); 958725bd22bf91c29e2351a127295c19fea996e2c7Anton Korobeynikov 968725bd22bf91c29e2351a127295c19fea996e2c7Anton Korobeynikov // FIXME: Implement efficiently multiplication by a constant 978725bd22bf91c29e2351a127295c19fea996e2c7Anton Korobeynikov setOperationAction(ISD::MUL, MVT::i16, Expand); 988725bd22bf91c29e2351a127295c19fea996e2c7Anton Korobeynikov setOperationAction(ISD::MULHS, MVT::i16, Expand); 998725bd22bf91c29e2351a127295c19fea996e2c7Anton Korobeynikov setOperationAction(ISD::MULHU, MVT::i16, Expand); 1008725bd22bf91c29e2351a127295c19fea996e2c7Anton Korobeynikov setOperationAction(ISD::SMUL_LOHI, MVT::i16, Expand); 1018725bd22bf91c29e2351a127295c19fea996e2c7Anton Korobeynikov setOperationAction(ISD::UMUL_LOHI, MVT::i16, Expand); 102f2f540261b187bb3fd14646a08f7e79afa1b5d96Anton Korobeynikov 103f2f540261b187bb3fd14646a08f7e79afa1b5d96Anton Korobeynikov setOperationAction(ISD::UDIV, MVT::i16, Expand); 104f2f540261b187bb3fd14646a08f7e79afa1b5d96Anton Korobeynikov setOperationAction(ISD::UDIVREM, MVT::i16, Expand); 1050616c3b678e441f235f80247bb66d59c9cd85226Anton Korobeynikov setOperationAction(ISD::UREM, MVT::i16, Expand); 106f2f540261b187bb3fd14646a08f7e79afa1b5d96Anton Korobeynikov setOperationAction(ISD::SDIV, MVT::i16, Expand); 107f2f540261b187bb3fd14646a08f7e79afa1b5d96Anton Korobeynikov setOperationAction(ISD::SDIVREM, MVT::i16, Expand); 1080616c3b678e441f235f80247bb66d59c9cd85226Anton Korobeynikov setOperationAction(ISD::SREM, MVT::i16, Expand); 109f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 110f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 111b8639f52143c99a3902b83555db4c54766c783caAnton KorobeynikovSDValue MSP430TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { 112f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov switch (Op.getOpcode()) { 113c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG); 114ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov case ISD::SHL: // FALLTHROUGH 115e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case ISD::SRL: 1164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case ISD::SRA: return LowerShifts(Op, DAG); 1174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case ISD::RET: return LowerRET(Op, DAG); 1184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case ISD::CALL: return LowerCALL(Op, DAG); 1193513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); 1205d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG); 1211bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case ISD::BR_CC: return LowerBR_CC(Op, DAG); 1221bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); 123b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov case ISD::SIGN_EXTEND: return LowerSIGN_EXTEND(Op, DAG); 124f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov default: 125f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov assert(0 && "unimplemented operand"); 126f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov return SDValue(); 127f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov } 128f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov} 129f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov 13020c568f366be211323eeaf0e45ef053278ec9ddcBill Wendling/// getFunctionAlignment - Return the alignment of this function. 13120c568f366be211323eeaf0e45ef053278ec9ddcBill Wendlingunsigned MSP430TargetLowering::getFunctionAlignment(const Function *F) const { 13220c568f366be211323eeaf0e45ef053278ec9ddcBill Wendling return F->hasFnAttr(Attribute::OptimizeForSize) ? 1 : 4; 13320c568f366be211323eeaf0e45ef053278ec9ddcBill Wendling} 13420c568f366be211323eeaf0e45ef053278ec9ddcBill Wendling 135c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===// 136c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// Calling Convention Implementation 137c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov//===----------------------------------------------------------------------===// 138c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 139f2c3e179ecc2a6ebc259382828a5e5dc5a61d2f8Anton Korobeynikov#include "MSP430GenCallingConv.inc" 140c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 141c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton KorobeynikovSDValue MSP430TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, 142c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov SelectionDAG &DAG) { 143c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov unsigned CC = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); 144c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov switch (CC) { 145c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov default: 146c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov assert(0 && "Unsupported calling convention"); 147c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov case CallingConv::C: 148c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov case CallingConv::Fast: 149c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov return LowerCCCArguments(Op, DAG); 150c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 151c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov} 152c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 1534428885c5acfffbbdd03ad2aab23960531c47753Anton KorobeynikovSDValue MSP430TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { 1544428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); 1554428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov unsigned CallingConv = TheCall->getCallingConv(); 1564428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov switch (CallingConv) { 1574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov default: 1584428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov assert(0 && "Unsupported calling convention"); 1594428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CallingConv::Fast: 1604428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CallingConv::C: 1614428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov return LowerCCCCallTo(Op, DAG, CallingConv); 1624428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 1634428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 1644428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 165c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// LowerCCCArguments - transform physical registers into virtual registers and 166c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov/// generate load operations for arguments places on the stack. 167c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// FIXME: struct return stuff 168c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov// FIXME: varargs 169dcb802cf7be8e540e487c699f25d89c4821536abAnton KorobeynikovSDValue MSP430TargetLowering::LowerCCCArguments(SDValue Op, 170dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov SelectionDAG &DAG) { 171c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineFunction &MF = DAG.getMachineFunction(); 172c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 173c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MachineRegisterInfo &RegInfo = MF.getRegInfo(); 174c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov SDValue Root = Op.getOperand(0); 175c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0; 176c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov unsigned CC = MF.getFunction()->getCallingConv(); 177c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 178c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 179c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Assign locations to all of the incoming arguments. 180c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov SmallVector<CCValAssign, 16> ArgLocs; 181c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); 182c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov CCInfo.AnalyzeFormalArguments(Op.getNode(), CC_MSP430); 183c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 184c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov assert(!isVarArg && "Varargs not supported yet"); 185c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 186c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov SmallVector<SDValue, 16> ArgValues; 187c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 188c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov CCValAssign &VA = ArgLocs[i]; 189c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.isRegLoc()) { 190c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Arguments passed in registers 191c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov MVT RegVT = VA.getLocVT(); 192c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov switch (RegVT.getSimpleVT()) { 193c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov default: 194c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: " 195c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov << RegVT.getSimpleVT() 196c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov << "\n"; 197c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov abort(); 198c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov case MVT::i16: 199c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov unsigned VReg = 2001df221f2bb8e8380e255d1bec73ab07b388d01a2Anton Korobeynikov RegInfo.createVirtualRegister(MSP430::GR16RegisterClass); 201c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov RegInfo.addLiveIn(VA.getLocReg(), VReg); 202c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov SDValue ArgValue = DAG.getCopyFromReg(Root, dl, VReg, RegVT); 203c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 204c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // If this is an 8-bit value, it is really passed promoted to 16 205c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // bits. Insert an assert[sz]ext to capture this, then truncate to the 206c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // right size. 207c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.getLocInfo() == CCValAssign::SExt) 208c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue, 209c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov DAG.getValueType(VA.getValVT())); 210c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov else if (VA.getLocInfo() == CCValAssign::ZExt) 211c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue, 212c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov DAG.getValueType(VA.getValVT())); 213c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 214c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (VA.getLocInfo() != CCValAssign::Full) 215c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); 216c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 217c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValues.push_back(ArgValue); 218c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 219c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } else { 220c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Sanity check 221c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov assert(VA.isMemLoc()); 222c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Load the argument to a virtual register 223c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov unsigned ObjSize = VA.getLocVT().getSizeInBits()/8; 224c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov if (ObjSize > 2) { 225c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: " 226c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov << VA.getLocVT().getSimpleVT() 227c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov << "\n"; 228c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 229c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Create the frame index object for this incoming parameter... 230c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset()); 231c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 232c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Create the SelectionDAG nodes corresponding to a load 233c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov //from this parameter 234c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov SDValue FIN = DAG.getFrameIndex(FI, MVT::i16); 235c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValues.push_back(DAG.getLoad(VA.getLocVT(), dl, Root, FIN, 236c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov PseudoSourceValue::getFixedStack(FI), 0)); 237c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 238c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov } 239c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 240c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov ArgValues.push_back(Root); 241c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov 242c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov // Return the new list of results. 243c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(), 244c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov &ArgValues[0], ArgValues.size()).getValue(Op.getResNo()); 245c8fbb6ae2041f17285e4ba73d54d388e703b9689Anton Korobeynikov} 246fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 247fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton KorobeynikovSDValue MSP430TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { 248fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // CCValAssign - represent the assignment of the return value to a location 249fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov SmallVector<CCValAssign, 16> RVLocs; 250fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv(); 251fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg(); 252fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 253fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 254fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // CCState - Info about the registers and stack slot. 255fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov CCState CCInfo(CC, isVarArg, getTargetMachine(), RVLocs); 256fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 257fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // Analize return values of ISD::RET 258fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov CCInfo.AnalyzeReturn(Op.getNode(), RetCC_MSP430); 259fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 260fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // If this is the first return lowered for this function, add the regs to the 261fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // liveout set for the function. 262fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (DAG.getMachineFunction().getRegInfo().liveout_empty()) { 263fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov for (unsigned i = 0; i != RVLocs.size(); ++i) 264fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (RVLocs[i].isRegLoc()) 265fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); 266fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 267fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 268fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // The chain is always operand #0 269fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov SDValue Chain = Op.getOperand(0); 270fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov SDValue Flag; 271fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 272fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // Copy the result values into the output registers. 273fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov for (unsigned i = 0; i != RVLocs.size(); ++i) { 274fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov CCValAssign &VA = RVLocs[i]; 275fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov assert(VA.isRegLoc() && "Can only return in registers!"); 276fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 277fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // ISD::RET => ret chain, (regnum1,val1), ... 278fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // So i*2+1 index only the regnums 279fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), 280fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov Op.getOperand(i*2+1), Flag); 281fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 282dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov // Guarantee that all emitted copies are stuck together, 283dcb802cf7be8e540e487c699f25d89c4821536abAnton Korobeynikov // avoiding something bad. 284fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov Flag = Chain.getValue(1); 285fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 286fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 287fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov if (Flag.getNode()) 288fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov return DAG.getNode(MSP430ISD::RET_FLAG, dl, MVT::Other, Chain, Flag); 289fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 290fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov // Return Void 291fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov return DAG.getNode(MSP430ISD::RET_FLAG, dl, MVT::Other, Chain); 292fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov} 293fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov 2944428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// LowerCCCCallTo - functions arguments are copied from virtual regs to 2954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted. 2964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// TODO: sret. 2974428885c5acfffbbdd03ad2aab23960531c47753Anton KorobeynikovSDValue MSP430TargetLowering::LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, 2984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov unsigned CC) { 2994428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); 3004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue Chain = TheCall->getChain(); 3014428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue Callee = TheCall->getCallee(); 3024428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov bool isVarArg = TheCall->isVarArg(); 3034428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 3044428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 3054428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Analyze operands of the call, assigning locations to each operand. 3064428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<CCValAssign, 16> ArgLocs; 3074428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); 3084428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 3094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov CCInfo.AnalyzeCallOperands(TheCall, CC_MSP430); 3104428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 3114428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Get a count of how many bytes are to be pushed on the stack. 3124428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov unsigned NumBytes = CCInfo.getNextStackOffset(); 3134428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 3144428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCALLSEQ_START(Chain ,DAG.getConstant(NumBytes, 3154428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov getPointerTy(), true)); 3164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 3174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass; 3184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<SDValue, 12> MemOpChains; 3194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue StackPtr; 3204428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 3214428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Walk the register/memloc assignments, inserting copies/loads. 3224428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 3234428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov CCValAssign &VA = ArgLocs[i]; 3244428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 3254428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Arguments start after the 5 first operands of ISD::CALL 3264428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue Arg = TheCall->getArg(i); 3274428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 3284428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Promote the value if needed. 3294428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov switch (VA.getLocInfo()) { 3304428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov default: assert(0 && "Unknown loc info!"); 3314428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::Full: break; 3324428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::SExt: 3334428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); 3344428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 3354428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::ZExt: 3364428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg); 3374428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 3384428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov case CCValAssign::AExt: 3394428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); 3404428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov break; 3414428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 3424428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 3434428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Arguments that can be passed on register must be kept at RegsToPass 3444428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // vector 3454428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (VA.isRegLoc()) { 3464428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 3474428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } else { 3484428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov assert(VA.isMemLoc()); 3494428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 3504428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (StackPtr.getNode() == 0) 3514428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SPW, getPointerTy()); 3524428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 3534428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), 3544428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov StackPtr, 3554428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG.getIntPtrConstant(VA.getLocMemOffset())); 3564428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 3574428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 3584428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, 3594428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov PseudoSourceValue::getStack(), 3604428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov VA.getLocMemOffset())); 3614428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 3624428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 3634428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 3644428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Transform all store nodes into one single node because all store nodes are 3654428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // independent of each other. 3664428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (!MemOpChains.empty()) 3674428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 3684428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov &MemOpChains[0], MemOpChains.size()); 3694428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 3704428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Build a sequence of copy-to-reg nodes chained together with token chain and 3714428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // flag operands which copy the outgoing args into registers. The InFlag in 3724428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // necessary since all emited instructions must be stuck together. 3734428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDValue InFlag; 3744428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 3754428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, 3764428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RegsToPass[i].second, InFlag); 3774428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(1); 3784428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 3794428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 3804428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // If the callee is a GlobalAddress node (quite common, every direct call is) 3814428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 3824428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Likewise ExternalSymbol -> TargetExternalSymbol. 3834428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 3844428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Callee = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i16); 3854428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) 3864428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i16); 3874428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 3884428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Returns a chain & a flag for retval copy to use. 3894428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); 3904428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<SDValue, 8> Ops; 3914428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(Chain); 3924428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(Callee); 3934428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 3944428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Add argument registers to the end of the list so that they are 3954428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // known live into the call. 3964428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 3974428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(DAG.getRegister(RegsToPass[i].first, 3984428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RegsToPass[i].second.getValueType())); 3994428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4004428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov if (InFlag.getNode()) 4014428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Ops.push_back(InFlag); 4024428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4034428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getNode(MSP430ISD::CALL, dl, NodeTys, &Ops[0], Ops.size()); 4044428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(1); 4054428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4064428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Create the CALLSEQ_END node. 4074428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCALLSEQ_END(Chain, 4084428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG.getConstant(NumBytes, getPointerTy(), true), 4094428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DAG.getConstant(0, getPointerTy(), true), 4104428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag); 4114428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(1); 4124428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4134428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Handle result values, copying them out of physregs into vregs that we 4144428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // return. 4154428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov return SDValue(LowerCallResult(Chain, InFlag, TheCall, CC, DAG), 4164428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Op.getResNo()); 4174428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 4184428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4194428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// LowerCallResult - Lower the result values of an ISD::CALL into the 4204428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// appropriate copies out of appropriate physical registers. This assumes that 4214428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// Chain/InFlag are the input chain/flag to use, and that TheCall is the call 4224428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// being lowered. Returns a SDNode with the same number of values as the 4234428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov/// ISD::CALL. 4244428885c5acfffbbdd03ad2aab23960531c47753Anton KorobeynikovSDNode* 4254428885c5acfffbbdd03ad2aab23960531c47753Anton KorobeynikovMSP430TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, 4264428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov CallSDNode *TheCall, 4274428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov unsigned CallingConv, 4284428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SelectionDAG &DAG) { 4294428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov bool isVarArg = TheCall->isVarArg(); 4304428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov DebugLoc dl = TheCall->getDebugLoc(); 4314428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4324428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Assign locations to each value returned by this call. 4334428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<CCValAssign, 16> RVLocs; 4344428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov CCState CCInfo(CallingConv, isVarArg, getTargetMachine(), RVLocs); 4354428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4364428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov CCInfo.AnalyzeCallResult(TheCall, RetCC_MSP430); 4374428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov SmallVector<SDValue, 8> ResultVals; 4384428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4394428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Copy all of the result registers out of their specified physreg. 4404428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov for (unsigned i = 0; i != RVLocs.size(); ++i) { 4414428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(), 4424428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov RVLocs[i].getValVT(), InFlag).getValue(1); 4434428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov InFlag = Chain.getValue(2); 4444428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov ResultVals.push_back(Chain.getValue(0)); 4454428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov } 4464428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4474428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov ResultVals.push_back(Chain); 4484428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 4494428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov // Merge everything together with a MERGE_VALUES node. 4504428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov return DAG.getNode(ISD::MERGE_VALUES, dl, TheCall->getVTList(), 4514428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov &ResultVals[0], ResultVals.size()).getNode(); 4524428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov} 4534428885c5acfffbbdd03ad2aab23960531c47753Anton Korobeynikov 454d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton KorobeynikovSDValue MSP430TargetLowering::LowerShifts(SDValue Op, 455d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov SelectionDAG &DAG) { 456ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov unsigned Opc = Op.getOpcode(); 457d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov SDNode* N = Op.getNode(); 458d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov MVT VT = Op.getValueType(); 459d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov DebugLoc dl = N->getDebugLoc(); 460d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 461ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov // We currently only lower shifts of constant argument. 462d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov if (!isa<ConstantSDNode>(N->getOperand(1))) 463d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov return SDValue(); 464d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 465d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue(); 466d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 467d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // Expand the stuff into sequence of shifts. 468d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // FIXME: for some shift amounts this might be done better! 469d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N 470d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov SDValue Victim = N->getOperand(0); 471e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov 472e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov if (Opc == ISD::SRL && ShiftAmount) { 473e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov // Emit a special goodness here: 474e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov // srl A, 1 => clrc; rrc A 475bf8ef3f29de28529b5d65970af9015c41f7c809bAnton Korobeynikov Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim); 476e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov ShiftAmount -= 1; 477e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov } 478e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov 479d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov while (ShiftAmount--) 480aceb620de855485a4fb2eed343d880d76f6c701cAnton Korobeynikov Victim = DAG.getNode((Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA), 481ea54c9846b2973cafa8ffd40626f5676ba9ccfeeAnton Korobeynikov dl, VT, Victim); 482d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 483d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov return Victim; 484d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov} 485d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov 4863513ca81c6beda087a281a66f1b0e612879c0aadAnton KorobeynikovSDValue MSP430TargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) { 4873513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); 4883513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset(); 4893513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov 4903513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov // Create the TargetGlobalAddress node, folding in the constant offset. 4913513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov SDValue Result = DAG.getTargetGlobalAddress(GV, getPointerTy(), Offset); 4923513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov return DAG.getNode(MSP430ISD::Wrapper, Op.getDebugLoc(), 4933513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov getPointerTy(), Result); 4943513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov} 4953513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov 4965d59f68ade7573175f1ace09061a94286e59076bAnton KorobeynikovSDValue MSP430TargetLowering::LowerExternalSymbol(SDValue Op, 4975d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov SelectionDAG &DAG) { 4985d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 4995d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol(); 5005d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov SDValue Result = DAG.getTargetExternalSymbol(Sym, getPointerTy()); 5015d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov 5025d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result);; 5035d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov} 5045d59f68ade7573175f1ace09061a94286e59076bAnton Korobeynikov 5051bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikovstatic SDValue EmitCMP(SDValue &LHS, SDValue &RHS, unsigned &TargetCC, 5061bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC, 5071bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov DebugLoc dl, SelectionDAG &DAG) { 508ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov // FIXME: Handle bittests someday 509ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet"); 510ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 511ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov // FIXME: Handle jump negative someday 5121bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov TargetCC = MSP430::COND_INVALID; 513ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov switch (CC) { 514ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov default: assert(0 && "Invalid integer condition!"); 515ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETEQ: 516ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov TargetCC = MSP430::COND_E; // aka COND_Z 517ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 518ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETNE: 519ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov TargetCC = MSP430::COND_NE; // aka COND_NZ 520ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 521ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETULE: 522ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 523ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETUGE: 524ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov TargetCC = MSP430::COND_HS; // aka COND_C 525ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 526ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETUGT: 527ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 528ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETULT: 529ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov TargetCC = MSP430::COND_LO; // aka COND_NC 530ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 531ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETLE: 532ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 533ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETGE: 534ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov TargetCC = MSP430::COND_GE; 535ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 536ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETGT: 537ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov std::swap(LHS, RHS); // FALLTHROUGH 538ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case ISD::SETLT: 539ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov TargetCC = MSP430::COND_L; 540ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov break; 541ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov } 542ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 5431bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov return DAG.getNode(MSP430ISD::CMP, dl, MVT::Flag, LHS, RHS); 544ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov} 545ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 5461bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 5471bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton KorobeynikovSDValue MSP430TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) { 548ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov SDValue Chain = Op.getOperand(0); 5491bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); 5501bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue LHS = Op.getOperand(2); 5511bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue RHS = Op.getOperand(3); 5521bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Dest = Op.getOperand(4); 5531bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 5541bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 5551bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov unsigned TargetCC = MSP430::COND_INVALID; 5561bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 5571bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 5581bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(), 5591bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov Chain, 5601bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov Dest, DAG.getConstant(TargetCC, MVT::i8), 5611bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov Flag); 562ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov} 563ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov 5641bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton KorobeynikovSDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) { 5651bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue LHS = Op.getOperand(0); 5661bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue RHS = Op.getOperand(1); 5671bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue TrueV = Op.getOperand(2); 5681bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue FalseV = Op.getOperand(3); 5691bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); 5708b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 5711bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov 5721bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov unsigned TargetCC = MSP430::COND_INVALID; 5731bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 5748b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 5758b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Flag); 5768b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov SmallVector<SDValue, 4> Ops; 5778b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov Ops.push_back(TrueV); 5788b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov Ops.push_back(FalseV); 5791bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov Ops.push_back(DAG.getConstant(TargetCC, MVT::i8)); 5801bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov Ops.push_back(Flag); 5818b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 5821bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size()); 5838b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov} 5848b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 585b78e214274d397407b6167a293b7cd7c3b526ddeAnton KorobeynikovSDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op, 586b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov SelectionDAG &DAG) { 587b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov SDValue Val = Op.getOperand(0); 588b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov MVT VT = Op.getValueType(); 589b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov DebugLoc dl = Op.getDebugLoc(); 590b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 591b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov assert(VT == MVT::i16 && "Only support i16 for now!"); 592b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 593b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT, 594b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val), 595b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov DAG.getValueType(Val.getValueType())); 596b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov} 597b78e214274d397407b6167a293b7cd7c3b526ddeAnton Korobeynikov 598fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikovconst char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const { 599fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov switch (Opcode) { 600fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov default: return NULL; 601fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov case MSP430ISD::RET_FLAG: return "MSP430ISD::RET_FLAG"; 602d2c94ae49e546e68b591e838cdfc2fd016d928d9Anton Korobeynikov case MSP430ISD::RRA: return "MSP430ISD::RRA"; 603e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case MSP430ISD::RLA: return "MSP430ISD::RLA"; 604e699d0f549151a2cca993c21407aea4a6eff7d3fAnton Korobeynikov case MSP430ISD::RRC: return "MSP430ISD::RRC"; 605b561264d2b2e33e1e6322a99d600b5daece5bbdeAnton Korobeynikov case MSP430ISD::CALL: return "MSP430ISD::CALL"; 6063513ca81c6beda087a281a66f1b0e612879c0aadAnton Korobeynikov case MSP430ISD::Wrapper: return "MSP430ISD::Wrapper"; 6071bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case MSP430ISD::BR_CC: return "MSP430ISD::BR_CC"; 608ed1a51af376b9027db60ff060e0a2572493df07bAnton Korobeynikov case MSP430ISD::CMP: return "MSP430ISD::CMP"; 6091bb8cd723d9fc89701fd3e54951c6bb419f798d3Anton Korobeynikov case MSP430ISD::SELECT_CC: return "MSP430ISD::SELECT_CC"; 610fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov } 611fd1b7c778c0c332a676b1003115d2b4bc6f9a46aAnton Korobeynikov} 6128b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 6138b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===// 6148b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov// Other Lowering Code 6158b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov//===----------------------------------------------------------------------===// 6168b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 6178b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMachineBasicBlock* 6188b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton KorobeynikovMSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 6198b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *BB) const { 6208b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); 6218b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov DebugLoc dl = MI->getDebugLoc(); 622da4d2f63d8b138569ec732d970bb452a0403a3abAnton Korobeynikov assert((MI->getOpcode() == MSP430::Select16 || 623da4d2f63d8b138569ec732d970bb452a0403a3abAnton Korobeynikov MI->getOpcode() == MSP430::Select8) && 6248b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov "Unexpected instr type to insert"); 6258b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 6268b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // To "insert" a SELECT instruction, we actually have to insert the diamond 6278b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // control-flow pattern. The incoming instruction knows the destination vreg 6288b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // to set, the condition code register to branch on, the true/false values to 6298b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // select between, and a branch opcode to use. 6308b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov const BasicBlock *LLVM_BB = BB->getBasicBlock(); 6318b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineFunction::iterator I = BB; 6328b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov ++I; 6338b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 6348b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // thisMBB: 6358b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // ... 6368b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // TrueVal = ... 6378b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // cmpTY ccX, r1, r2 6388b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // jCC copy1MBB 6398b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // fallthrough --> copy0MBB 6408b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *thisMBB = BB; 6418b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineFunction *F = BB->getParent(); 6428b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); 6438b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB); 6448b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BuildMI(BB, dl, TII.get(MSP430::JCC)) 6458b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addMBB(copy1MBB) 6468b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addImm(MI->getOperand(3).getImm()); 6478b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov F->insert(I, copy0MBB); 6488b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov F->insert(I, copy1MBB); 6498b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Update machine-CFG edges by transferring all successors of the current 6508b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // block to the new block which will contain the Phi node for the select. 6518b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov copy1MBB->transferSuccessors(BB); 6528b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Next, add the true and fallthrough blocks as its successors. 6538b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy0MBB); 6548b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy1MBB); 6558b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 6568b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // copy0MBB: 6578b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // %FalseValue = ... 6588b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // # fallthrough to copy1MBB 6598b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB = copy0MBB; 6608b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 6618b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // Update machine-CFG edges 6628b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB->addSuccessor(copy1MBB); 6638b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 6648b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // copy1MBB: 6658b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] 6668b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov // ... 6678b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BB = copy1MBB; 6688b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov BuildMI(BB, dl, TII.get(MSP430::PHI), 6698b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov MI->getOperand(0).getReg()) 6708b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB) 6718b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB); 6728b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov 6738b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov F->DeleteMachineInstr(MI); // The pseudo instruction is gone now. 6748b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov return BB; 6758b528e52ee6018b0d0e7e46b3b4cf6f41fdaa0d9Anton Korobeynikov} 676