1193323Sed//===-- MSP430ISelLowering.cpp - MSP430 DAG Lowering Implementation ------===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file implements the MSP430TargetLowering class. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14193323Sed#define DEBUG_TYPE "msp430-lower" 15193323Sed 16193323Sed#include "MSP430ISelLowering.h" 17193323Sed#include "MSP430.h" 18200581Srdivacky#include "MSP430MachineFunctionInfo.h" 19249423Sdim#include "MSP430Subtarget.h" 20193323Sed#include "MSP430TargetMachine.h" 21193323Sed#include "llvm/CodeGen/CallingConvLower.h" 22193323Sed#include "llvm/CodeGen/MachineFrameInfo.h" 23193323Sed#include "llvm/CodeGen/MachineFunction.h" 24193323Sed#include "llvm/CodeGen/MachineInstrBuilder.h" 25193323Sed#include "llvm/CodeGen/MachineRegisterInfo.h" 26193323Sed#include "llvm/CodeGen/SelectionDAGISel.h" 27203954Srdivacky#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 28193323Sed#include "llvm/CodeGen/ValueTypes.h" 29249423Sdim#include "llvm/IR/CallingConv.h" 30249423Sdim#include "llvm/IR/DerivedTypes.h" 31249423Sdim#include "llvm/IR/Function.h" 32249423Sdim#include "llvm/IR/GlobalAlias.h" 33249423Sdim#include "llvm/IR/GlobalVariable.h" 34249423Sdim#include "llvm/IR/Intrinsics.h" 35200581Srdivacky#include "llvm/Support/CommandLine.h" 36193323Sed#include "llvm/Support/Debug.h" 37198090Srdivacky#include "llvm/Support/ErrorHandling.h" 38198090Srdivacky#include "llvm/Support/raw_ostream.h" 39193323Sedusing namespace llvm; 40193323Sed 41200581Srdivackytypedef enum { 42200581Srdivacky NoHWMult, 43200581Srdivacky HWMultIntr, 44200581Srdivacky HWMultNoIntr 45200581Srdivacky} HWMultUseMode; 46200581Srdivacky 47200581Srdivackystatic cl::opt<HWMultUseMode> 48200581SrdivackyHWMultMode("msp430-hwmult-mode", 49200581Srdivacky cl::desc("Hardware multiplier use mode"), 50200581Srdivacky cl::init(HWMultNoIntr), 51200581Srdivacky cl::values( 52200581Srdivacky clEnumValN(NoHWMult, "no", 53200581Srdivacky "Do not use hardware multiplier"), 54200581Srdivacky clEnumValN(HWMultIntr, "interrupts", 55200581Srdivacky "Assume hardware multiplier can be used inside interrupts"), 56200581Srdivacky clEnumValN(HWMultNoIntr, "use", 57200581Srdivacky "Assume hardware multiplier cannot be used inside interrupts"), 58200581Srdivacky clEnumValEnd)); 59200581Srdivacky 60193323SedMSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) : 61198090Srdivacky TargetLowering(tm, new TargetLoweringObjectFileELF()), 62239462Sdim Subtarget(*tm.getSubtargetImpl()) { 63193323Sed 64243830Sdim TD = getDataLayout(); 65200581Srdivacky 66193323Sed // Set up the register classes. 67239462Sdim addRegisterClass(MVT::i8, &MSP430::GR8RegClass); 68239462Sdim addRegisterClass(MVT::i16, &MSP430::GR16RegClass); 69193323Sed 70193323Sed // Compute derived properties from the register classes 71193323Sed computeRegisterProperties(); 72193323Sed 73193323Sed // Provide all sorts of operation actions 74193323Sed 75193323Sed // Division is expensive 76193323Sed setIntDivIsCheap(false); 77193323Sed 78193323Sed setStackPointerRegisterToSaveRestore(MSP430::SPW); 79193323Sed setBooleanContents(ZeroOrOneBooleanContent); 80226633Sdim setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct? 81193323Sed 82199481Srdivacky // We have post-incremented loads / stores. 83199481Srdivacky setIndexedLoadAction(ISD::POST_INC, MVT::i8, Legal); 84199481Srdivacky setIndexedLoadAction(ISD::POST_INC, MVT::i16, Legal); 85199481Srdivacky 86199481Srdivacky setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); 87199481Srdivacky setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); 88199481Srdivacky setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); 89199481Srdivacky setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Expand); 90193323Sed setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Expand); 91193323Sed 92193323Sed // We don't have any truncstores 93193323Sed setTruncStoreAction(MVT::i16, MVT::i8, Expand); 94193323Sed 95193323Sed setOperationAction(ISD::SRA, MVT::i8, Custom); 96193323Sed setOperationAction(ISD::SHL, MVT::i8, Custom); 97193323Sed setOperationAction(ISD::SRL, MVT::i8, Custom); 98193323Sed setOperationAction(ISD::SRA, MVT::i16, Custom); 99193323Sed setOperationAction(ISD::SHL, MVT::i16, Custom); 100193323Sed setOperationAction(ISD::SRL, MVT::i16, Custom); 101193323Sed setOperationAction(ISD::ROTL, MVT::i8, Expand); 102193323Sed setOperationAction(ISD::ROTR, MVT::i8, Expand); 103193323Sed setOperationAction(ISD::ROTL, MVT::i16, Expand); 104193323Sed setOperationAction(ISD::ROTR, MVT::i16, Expand); 105193323Sed setOperationAction(ISD::GlobalAddress, MVT::i16, Custom); 106193323Sed setOperationAction(ISD::ExternalSymbol, MVT::i16, Custom); 107207618Srdivacky setOperationAction(ISD::BlockAddress, MVT::i16, Custom); 108193323Sed setOperationAction(ISD::BR_JT, MVT::Other, Expand); 109193323Sed setOperationAction(ISD::BR_CC, MVT::i8, Custom); 110193323Sed setOperationAction(ISD::BR_CC, MVT::i16, Custom); 111193323Sed setOperationAction(ISD::BRCOND, MVT::Other, Expand); 112200581Srdivacky setOperationAction(ISD::SETCC, MVT::i8, Custom); 113200581Srdivacky setOperationAction(ISD::SETCC, MVT::i16, Custom); 114193323Sed setOperationAction(ISD::SELECT, MVT::i8, Expand); 115193323Sed setOperationAction(ISD::SELECT, MVT::i16, Expand); 116193323Sed setOperationAction(ISD::SELECT_CC, MVT::i8, Custom); 117193323Sed setOperationAction(ISD::SELECT_CC, MVT::i16, Custom); 118193323Sed setOperationAction(ISD::SIGN_EXTEND, MVT::i16, Custom); 119198090Srdivacky setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i8, Expand); 120198090Srdivacky setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i16, Expand); 121193323Sed 122198090Srdivacky setOperationAction(ISD::CTTZ, MVT::i8, Expand); 123198090Srdivacky setOperationAction(ISD::CTTZ, MVT::i16, Expand); 124234353Sdim setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i8, Expand); 125234353Sdim setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i16, Expand); 126198090Srdivacky setOperationAction(ISD::CTLZ, MVT::i8, Expand); 127198090Srdivacky setOperationAction(ISD::CTLZ, MVT::i16, Expand); 128234353Sdim setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i8, Expand); 129234353Sdim setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i16, Expand); 130198090Srdivacky setOperationAction(ISD::CTPOP, MVT::i8, Expand); 131198090Srdivacky setOperationAction(ISD::CTPOP, MVT::i16, Expand); 132198090Srdivacky 133198090Srdivacky setOperationAction(ISD::SHL_PARTS, MVT::i8, Expand); 134198090Srdivacky setOperationAction(ISD::SHL_PARTS, MVT::i16, Expand); 135198090Srdivacky setOperationAction(ISD::SRL_PARTS, MVT::i8, Expand); 136198090Srdivacky setOperationAction(ISD::SRL_PARTS, MVT::i16, Expand); 137198090Srdivacky setOperationAction(ISD::SRA_PARTS, MVT::i8, Expand); 138198090Srdivacky setOperationAction(ISD::SRA_PARTS, MVT::i16, Expand); 139198090Srdivacky 140198090Srdivacky setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); 141198090Srdivacky 142193323Sed // FIXME: Implement efficiently multiplication by a constant 143199481Srdivacky setOperationAction(ISD::MUL, MVT::i8, Expand); 144199481Srdivacky setOperationAction(ISD::MULHS, MVT::i8, Expand); 145199481Srdivacky setOperationAction(ISD::MULHU, MVT::i8, Expand); 146199481Srdivacky setOperationAction(ISD::SMUL_LOHI, MVT::i8, Expand); 147199481Srdivacky setOperationAction(ISD::UMUL_LOHI, MVT::i8, Expand); 148193323Sed setOperationAction(ISD::MUL, MVT::i16, Expand); 149193323Sed setOperationAction(ISD::MULHS, MVT::i16, Expand); 150193323Sed setOperationAction(ISD::MULHU, MVT::i16, Expand); 151193323Sed setOperationAction(ISD::SMUL_LOHI, MVT::i16, Expand); 152193323Sed setOperationAction(ISD::UMUL_LOHI, MVT::i16, Expand); 153193323Sed 154199481Srdivacky setOperationAction(ISD::UDIV, MVT::i8, Expand); 155199481Srdivacky setOperationAction(ISD::UDIVREM, MVT::i8, Expand); 156199481Srdivacky setOperationAction(ISD::UREM, MVT::i8, Expand); 157199481Srdivacky setOperationAction(ISD::SDIV, MVT::i8, Expand); 158199481Srdivacky setOperationAction(ISD::SDIVREM, MVT::i8, Expand); 159199481Srdivacky setOperationAction(ISD::SREM, MVT::i8, Expand); 160193323Sed setOperationAction(ISD::UDIV, MVT::i16, Expand); 161193323Sed setOperationAction(ISD::UDIVREM, MVT::i16, Expand); 162193323Sed setOperationAction(ISD::UREM, MVT::i16, Expand); 163193323Sed setOperationAction(ISD::SDIV, MVT::i16, Expand); 164193323Sed setOperationAction(ISD::SDIVREM, MVT::i16, Expand); 165193323Sed setOperationAction(ISD::SREM, MVT::i16, Expand); 166200581Srdivacky 167249423Sdim // varargs support 168249423Sdim setOperationAction(ISD::VASTART, MVT::Other, Custom); 169249423Sdim setOperationAction(ISD::VAARG, MVT::Other, Expand); 170249423Sdim setOperationAction(ISD::VAEND, MVT::Other, Expand); 171249423Sdim setOperationAction(ISD::VACOPY, MVT::Other, Expand); 172249423Sdim 173200581Srdivacky // Libcalls names. 174200581Srdivacky if (HWMultMode == HWMultIntr) { 175200581Srdivacky setLibcallName(RTLIB::MUL_I8, "__mulqi3hw"); 176200581Srdivacky setLibcallName(RTLIB::MUL_I16, "__mulhi3hw"); 177200581Srdivacky } else if (HWMultMode == HWMultNoIntr) { 178200581Srdivacky setLibcallName(RTLIB::MUL_I8, "__mulqi3hw_noint"); 179200581Srdivacky setLibcallName(RTLIB::MUL_I16, "__mulhi3hw_noint"); 180200581Srdivacky } 181223017Sdim 182223017Sdim setMinFunctionAlignment(1); 183223017Sdim setPrefFunctionAlignment(2); 184193323Sed} 185193323Sed 186207618SrdivackySDValue MSP430TargetLowering::LowerOperation(SDValue Op, 187207618Srdivacky SelectionDAG &DAG) const { 188193323Sed switch (Op.getOpcode()) { 189193323Sed case ISD::SHL: // FALLTHROUGH 190193323Sed case ISD::SRL: 191193323Sed case ISD::SRA: return LowerShifts(Op, DAG); 192193323Sed case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); 193207618Srdivacky case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); 194193323Sed case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG); 195200581Srdivacky case ISD::SETCC: return LowerSETCC(Op, DAG); 196193323Sed case ISD::BR_CC: return LowerBR_CC(Op, DAG); 197193323Sed case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); 198193323Sed case ISD::SIGN_EXTEND: return LowerSIGN_EXTEND(Op, DAG); 199200581Srdivacky case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); 200200581Srdivacky case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); 201249423Sdim case ISD::VASTART: return LowerVASTART(Op, DAG); 202193323Sed default: 203198090Srdivacky llvm_unreachable("unimplemented operand"); 204193323Sed } 205193323Sed} 206193323Sed 207193323Sed//===----------------------------------------------------------------------===// 208198090Srdivacky// MSP430 Inline Assembly Support 209198090Srdivacky//===----------------------------------------------------------------------===// 210198090Srdivacky 211198090Srdivacky/// getConstraintType - Given a constraint letter, return the type of 212198090Srdivacky/// constraint it is for this target. 213198090SrdivackyTargetLowering::ConstraintType 214198090SrdivackyMSP430TargetLowering::getConstraintType(const std::string &Constraint) const { 215198090Srdivacky if (Constraint.size() == 1) { 216198090Srdivacky switch (Constraint[0]) { 217198090Srdivacky case 'r': 218198090Srdivacky return C_RegisterClass; 219198090Srdivacky default: 220198090Srdivacky break; 221198090Srdivacky } 222198090Srdivacky } 223198090Srdivacky return TargetLowering::getConstraintType(Constraint); 224198090Srdivacky} 225198090Srdivacky 226198090Srdivackystd::pair<unsigned, const TargetRegisterClass*> 227198090SrdivackyMSP430TargetLowering:: 228198090SrdivackygetRegForInlineAsmConstraint(const std::string &Constraint, 229198090Srdivacky EVT VT) const { 230198090Srdivacky if (Constraint.size() == 1) { 231198090Srdivacky // GCC Constraint Letters 232198090Srdivacky switch (Constraint[0]) { 233198090Srdivacky default: break; 234198090Srdivacky case 'r': // GENERAL_REGS 235198090Srdivacky if (VT == MVT::i8) 236239462Sdim return std::make_pair(0U, &MSP430::GR8RegClass); 237198090Srdivacky 238239462Sdim return std::make_pair(0U, &MSP430::GR16RegClass); 239198090Srdivacky } 240198090Srdivacky } 241198090Srdivacky 242198090Srdivacky return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); 243198090Srdivacky} 244198090Srdivacky 245198090Srdivacky//===----------------------------------------------------------------------===// 246193323Sed// Calling Convention Implementation 247193323Sed//===----------------------------------------------------------------------===// 248193323Sed 249193323Sed#include "MSP430GenCallingConv.inc" 250193323Sed 251198090SrdivackySDValue 252198090SrdivackyMSP430TargetLowering::LowerFormalArguments(SDValue Chain, 253198090Srdivacky CallingConv::ID CallConv, 254198090Srdivacky bool isVarArg, 255198090Srdivacky const SmallVectorImpl<ISD::InputArg> 256198090Srdivacky &Ins, 257198090Srdivacky DebugLoc dl, 258198090Srdivacky SelectionDAG &DAG, 259207618Srdivacky SmallVectorImpl<SDValue> &InVals) 260207618Srdivacky const { 261198090Srdivacky 262198090Srdivacky switch (CallConv) { 263193323Sed default: 264198090Srdivacky llvm_unreachable("Unsupported calling convention"); 265193323Sed case CallingConv::C: 266193323Sed case CallingConv::Fast: 267198090Srdivacky return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals); 268200581Srdivacky case CallingConv::MSP430_INTR: 269234353Sdim if (Ins.empty()) 270234353Sdim return Chain; 271207618Srdivacky report_fatal_error("ISRs cannot have arguments"); 272193323Sed } 273193323Sed} 274193323Sed 275198090SrdivackySDValue 276239462SdimMSP430TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, 277207618Srdivacky SmallVectorImpl<SDValue> &InVals) const { 278239462Sdim SelectionDAG &DAG = CLI.DAG; 279239462Sdim DebugLoc &dl = CLI.DL; 280239462Sdim SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs; 281239462Sdim SmallVector<SDValue, 32> &OutVals = CLI.OutVals; 282239462Sdim SmallVector<ISD::InputArg, 32> &Ins = CLI.Ins; 283239462Sdim SDValue Chain = CLI.Chain; 284239462Sdim SDValue Callee = CLI.Callee; 285239462Sdim bool &isTailCall = CLI.IsTailCall; 286239462Sdim CallingConv::ID CallConv = CLI.CallConv; 287239462Sdim bool isVarArg = CLI.IsVarArg; 288239462Sdim 289203954Srdivacky // MSP430 target does not yet support tail call optimization. 290203954Srdivacky isTailCall = false; 291198090Srdivacky 292198090Srdivacky switch (CallConv) { 293193323Sed default: 294198090Srdivacky llvm_unreachable("Unsupported calling convention"); 295193323Sed case CallingConv::Fast: 296193323Sed case CallingConv::C: 297198090Srdivacky return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall, 298210299Sed Outs, OutVals, Ins, dl, DAG, InVals); 299200581Srdivacky case CallingConv::MSP430_INTR: 300207618Srdivacky report_fatal_error("ISRs cannot be called directly"); 301193323Sed } 302193323Sed} 303193323Sed 304193323Sed/// LowerCCCArguments - transform physical registers into virtual registers and 305193323Sed/// generate load operations for arguments places on the stack. 306193323Sed// FIXME: struct return stuff 307198090SrdivackySDValue 308198090SrdivackyMSP430TargetLowering::LowerCCCArguments(SDValue Chain, 309198090Srdivacky CallingConv::ID CallConv, 310198090Srdivacky bool isVarArg, 311198090Srdivacky const SmallVectorImpl<ISD::InputArg> 312198090Srdivacky &Ins, 313198090Srdivacky DebugLoc dl, 314198090Srdivacky SelectionDAG &DAG, 315207618Srdivacky SmallVectorImpl<SDValue> &InVals) 316207618Srdivacky const { 317193323Sed MachineFunction &MF = DAG.getMachineFunction(); 318193323Sed MachineFrameInfo *MFI = MF.getFrameInfo(); 319193323Sed MachineRegisterInfo &RegInfo = MF.getRegInfo(); 320249423Sdim MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>(); 321193323Sed 322193323Sed // Assign locations to all of the incoming arguments. 323193323Sed SmallVector<CCValAssign, 16> ArgLocs; 324223017Sdim CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 325239462Sdim getTargetMachine(), ArgLocs, *DAG.getContext()); 326198090Srdivacky CCInfo.AnalyzeFormalArguments(Ins, CC_MSP430); 327193323Sed 328249423Sdim // Create frame index for the start of the first vararg value 329249423Sdim if (isVarArg) { 330249423Sdim unsigned Offset = CCInfo.getNextStackOffset(); 331249423Sdim FuncInfo->setVarArgsFrameIndex(MFI->CreateFixedObject(1, Offset, true)); 332249423Sdim } 333193323Sed 334193323Sed for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 335193323Sed CCValAssign &VA = ArgLocs[i]; 336193323Sed if (VA.isRegLoc()) { 337193323Sed // Arguments passed in registers 338198090Srdivacky EVT RegVT = VA.getLocVT(); 339198090Srdivacky switch (RegVT.getSimpleVT().SimpleTy) { 340219077Sdim default: 341198090Srdivacky { 342198090Srdivacky#ifndef NDEBUG 343198090Srdivacky errs() << "LowerFormalArguments Unhandled argument type: " 344198090Srdivacky << RegVT.getSimpleVT().SimpleTy << "\n"; 345198090Srdivacky#endif 346198090Srdivacky llvm_unreachable(0); 347198090Srdivacky } 348193323Sed case MVT::i16: 349239462Sdim unsigned VReg = RegInfo.createVirtualRegister(&MSP430::GR16RegClass); 350193323Sed RegInfo.addLiveIn(VA.getLocReg(), VReg); 351198090Srdivacky SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, RegVT); 352193323Sed 353193323Sed // If this is an 8-bit value, it is really passed promoted to 16 354193323Sed // bits. Insert an assert[sz]ext to capture this, then truncate to the 355193323Sed // right size. 356193323Sed if (VA.getLocInfo() == CCValAssign::SExt) 357193323Sed ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue, 358193323Sed DAG.getValueType(VA.getValVT())); 359193323Sed else if (VA.getLocInfo() == CCValAssign::ZExt) 360193323Sed ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue, 361193323Sed DAG.getValueType(VA.getValVT())); 362193323Sed 363193323Sed if (VA.getLocInfo() != CCValAssign::Full) 364193323Sed ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); 365193323Sed 366198090Srdivacky InVals.push_back(ArgValue); 367193323Sed } 368193323Sed } else { 369193323Sed // Sanity check 370193323Sed assert(VA.isMemLoc()); 371249423Sdim 372249423Sdim SDValue InVal; 373249423Sdim ISD::ArgFlagsTy Flags = Ins[i].Flags; 374249423Sdim 375249423Sdim if (Flags.isByVal()) { 376249423Sdim int FI = MFI->CreateFixedObject(Flags.getByValSize(), 377249423Sdim VA.getLocMemOffset(), true); 378249423Sdim InVal = DAG.getFrameIndex(FI, getPointerTy()); 379249423Sdim } else { 380249423Sdim // Load the argument to a virtual register 381249423Sdim unsigned ObjSize = VA.getLocVT().getSizeInBits()/8; 382249423Sdim if (ObjSize > 2) { 383249423Sdim errs() << "LowerFormalArguments Unhandled argument type: " 384249423Sdim << EVT(VA.getLocVT()).getEVTString() 385249423Sdim << "\n"; 386249423Sdim } 387249423Sdim // Create the frame index object for this incoming parameter... 388249423Sdim int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true); 389249423Sdim 390249423Sdim // Create the SelectionDAG nodes corresponding to a load 391249423Sdim //from this parameter 392249423Sdim SDValue FIN = DAG.getFrameIndex(FI, MVT::i16); 393249423Sdim InVal = DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, 394249423Sdim MachinePointerInfo::getFixedStack(FI), 395249423Sdim false, false, false, 0); 396193323Sed } 397193323Sed 398249423Sdim InVals.push_back(InVal); 399193323Sed } 400193323Sed } 401193323Sed 402198090Srdivacky return Chain; 403193323Sed} 404193323Sed 405198090SrdivackySDValue 406198090SrdivackyMSP430TargetLowering::LowerReturn(SDValue Chain, 407198090Srdivacky CallingConv::ID CallConv, bool isVarArg, 408198090Srdivacky const SmallVectorImpl<ISD::OutputArg> &Outs, 409210299Sed const SmallVectorImpl<SDValue> &OutVals, 410207618Srdivacky DebugLoc dl, SelectionDAG &DAG) const { 411198090Srdivacky 412193323Sed // CCValAssign - represent the assignment of the return value to a location 413193323Sed SmallVector<CCValAssign, 16> RVLocs; 414193323Sed 415200581Srdivacky // ISRs cannot return any value. 416234353Sdim if (CallConv == CallingConv::MSP430_INTR && !Outs.empty()) 417207618Srdivacky report_fatal_error("ISRs cannot return any value"); 418200581Srdivacky 419193323Sed // CCState - Info about the registers and stack slot. 420223017Sdim CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 421239462Sdim getTargetMachine(), RVLocs, *DAG.getContext()); 422193323Sed 423198090Srdivacky // Analize return values. 424198090Srdivacky CCInfo.AnalyzeReturn(Outs, RetCC_MSP430); 425193323Sed 426193323Sed SDValue Flag; 427249423Sdim SmallVector<SDValue, 4> RetOps(1, Chain); 428193323Sed 429193323Sed // Copy the result values into the output registers. 430193323Sed for (unsigned i = 0; i != RVLocs.size(); ++i) { 431193323Sed CCValAssign &VA = RVLocs[i]; 432193323Sed assert(VA.isRegLoc() && "Can only return in registers!"); 433193323Sed 434193323Sed Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), 435210299Sed OutVals[i], Flag); 436193323Sed 437193323Sed // Guarantee that all emitted copies are stuck together, 438193323Sed // avoiding something bad. 439193323Sed Flag = Chain.getValue(1); 440249423Sdim RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); 441193323Sed } 442193323Sed 443200581Srdivacky unsigned Opc = (CallConv == CallingConv::MSP430_INTR ? 444200581Srdivacky MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG); 445200581Srdivacky 446249423Sdim RetOps[0] = Chain; // Update chain. 447249423Sdim 448249423Sdim // Add the flag if we have it. 449193323Sed if (Flag.getNode()) 450249423Sdim RetOps.push_back(Flag); 451193323Sed 452249423Sdim return DAG.getNode(Opc, dl, MVT::Other, &RetOps[0], RetOps.size()); 453193323Sed} 454193323Sed 455193323Sed/// LowerCCCCallTo - functions arguments are copied from virtual regs to 456193323Sed/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted. 457193323Sed/// TODO: sret. 458198090SrdivackySDValue 459198090SrdivackyMSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, 460198090Srdivacky CallingConv::ID CallConv, bool isVarArg, 461198090Srdivacky bool isTailCall, 462198090Srdivacky const SmallVectorImpl<ISD::OutputArg> 463198090Srdivacky &Outs, 464210299Sed const SmallVectorImpl<SDValue> &OutVals, 465198090Srdivacky const SmallVectorImpl<ISD::InputArg> &Ins, 466198090Srdivacky DebugLoc dl, SelectionDAG &DAG, 467207618Srdivacky SmallVectorImpl<SDValue> &InVals) const { 468193323Sed // Analyze operands of the call, assigning locations to each operand. 469193323Sed SmallVector<CCValAssign, 16> ArgLocs; 470223017Sdim CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 471239462Sdim getTargetMachine(), ArgLocs, *DAG.getContext()); 472193323Sed 473198090Srdivacky CCInfo.AnalyzeCallOperands(Outs, CC_MSP430); 474193323Sed 475193323Sed // Get a count of how many bytes are to be pushed on the stack. 476193323Sed unsigned NumBytes = CCInfo.getNextStackOffset(); 477193323Sed 478193323Sed Chain = DAG.getCALLSEQ_START(Chain ,DAG.getConstant(NumBytes, 479193323Sed getPointerTy(), true)); 480193323Sed 481193323Sed SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass; 482193323Sed SmallVector<SDValue, 12> MemOpChains; 483193323Sed SDValue StackPtr; 484193323Sed 485193323Sed // Walk the register/memloc assignments, inserting copies/loads. 486193323Sed for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 487193323Sed CCValAssign &VA = ArgLocs[i]; 488193323Sed 489210299Sed SDValue Arg = OutVals[i]; 490193323Sed 491193323Sed // Promote the value if needed. 492193323Sed switch (VA.getLocInfo()) { 493198090Srdivacky default: llvm_unreachable("Unknown loc info!"); 494193323Sed case CCValAssign::Full: break; 495193323Sed case CCValAssign::SExt: 496193323Sed Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); 497193323Sed break; 498193323Sed case CCValAssign::ZExt: 499193323Sed Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg); 500193323Sed break; 501193323Sed case CCValAssign::AExt: 502193323Sed Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); 503193323Sed break; 504193323Sed } 505193323Sed 506193323Sed // Arguments that can be passed on register must be kept at RegsToPass 507193323Sed // vector 508193323Sed if (VA.isRegLoc()) { 509193323Sed RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 510193323Sed } else { 511193323Sed assert(VA.isMemLoc()); 512193323Sed 513193323Sed if (StackPtr.getNode() == 0) 514193323Sed StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SPW, getPointerTy()); 515193323Sed 516193323Sed SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), 517193323Sed StackPtr, 518193323Sed DAG.getIntPtrConstant(VA.getLocMemOffset())); 519193323Sed 520249423Sdim SDValue MemOp; 521249423Sdim ISD::ArgFlagsTy Flags = Outs[i].Flags; 522193323Sed 523249423Sdim if (Flags.isByVal()) { 524249423Sdim SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), MVT::i16); 525249423Sdim MemOp = DAG.getMemcpy(Chain, dl, PtrOff, Arg, SizeNode, 526249423Sdim Flags.getByValAlign(), 527249423Sdim /*isVolatile*/false, 528249423Sdim /*AlwaysInline=*/true, 529249423Sdim MachinePointerInfo(), 530249423Sdim MachinePointerInfo()); 531249423Sdim } else { 532249423Sdim MemOp = DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo(), 533249423Sdim false, false, 0); 534249423Sdim } 535249423Sdim 536249423Sdim MemOpChains.push_back(MemOp); 537193323Sed } 538193323Sed } 539193323Sed 540193323Sed // Transform all store nodes into one single node because all store nodes are 541193323Sed // independent of each other. 542193323Sed if (!MemOpChains.empty()) 543193323Sed Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 544193323Sed &MemOpChains[0], MemOpChains.size()); 545193323Sed 546193323Sed // Build a sequence of copy-to-reg nodes chained together with token chain and 547193323Sed // flag operands which copy the outgoing args into registers. The InFlag in 548221345Sdim // necessary since all emitted instructions must be stuck together. 549193323Sed SDValue InFlag; 550193323Sed for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 551193323Sed Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, 552193323Sed RegsToPass[i].second, InFlag); 553193323Sed InFlag = Chain.getValue(1); 554193323Sed } 555193323Sed 556193323Sed // If the callee is a GlobalAddress node (quite common, every direct call is) 557193323Sed // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 558193323Sed // Likewise ExternalSymbol -> TargetExternalSymbol. 559193323Sed if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 560210299Sed Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i16); 561193323Sed else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) 562193323Sed Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i16); 563193323Sed 564193323Sed // Returns a chain & a flag for retval copy to use. 565218893Sdim SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 566193323Sed SmallVector<SDValue, 8> Ops; 567193323Sed Ops.push_back(Chain); 568193323Sed Ops.push_back(Callee); 569193323Sed 570193323Sed // Add argument registers to the end of the list so that they are 571193323Sed // known live into the call. 572193323Sed for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 573193323Sed Ops.push_back(DAG.getRegister(RegsToPass[i].first, 574193323Sed RegsToPass[i].second.getValueType())); 575193323Sed 576193323Sed if (InFlag.getNode()) 577193323Sed Ops.push_back(InFlag); 578193323Sed 579193323Sed Chain = DAG.getNode(MSP430ISD::CALL, dl, NodeTys, &Ops[0], Ops.size()); 580193323Sed InFlag = Chain.getValue(1); 581193323Sed 582193323Sed // Create the CALLSEQ_END node. 583193323Sed Chain = DAG.getCALLSEQ_END(Chain, 584193323Sed DAG.getConstant(NumBytes, getPointerTy(), true), 585193323Sed DAG.getConstant(0, getPointerTy(), true), 586193323Sed InFlag); 587193323Sed InFlag = Chain.getValue(1); 588193323Sed 589193323Sed // Handle result values, copying them out of physregs into vregs that we 590193323Sed // return. 591198090Srdivacky return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl, 592198090Srdivacky DAG, InVals); 593193323Sed} 594193323Sed 595198090Srdivacky/// LowerCallResult - Lower the result values of a call into the 596198090Srdivacky/// appropriate copies out of appropriate physical registers. 597198090Srdivacky/// 598198090SrdivackySDValue 599193323SedMSP430TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, 600198090Srdivacky CallingConv::ID CallConv, bool isVarArg, 601198090Srdivacky const SmallVectorImpl<ISD::InputArg> &Ins, 602198090Srdivacky DebugLoc dl, SelectionDAG &DAG, 603207618Srdivacky SmallVectorImpl<SDValue> &InVals) const { 604193323Sed 605193323Sed // Assign locations to each value returned by this call. 606193323Sed SmallVector<CCValAssign, 16> RVLocs; 607223017Sdim CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 608239462Sdim getTargetMachine(), RVLocs, *DAG.getContext()); 609193323Sed 610198090Srdivacky CCInfo.AnalyzeCallResult(Ins, RetCC_MSP430); 611193323Sed 612193323Sed // Copy all of the result registers out of their specified physreg. 613193323Sed for (unsigned i = 0; i != RVLocs.size(); ++i) { 614193323Sed Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(), 615193323Sed RVLocs[i].getValVT(), InFlag).getValue(1); 616193323Sed InFlag = Chain.getValue(2); 617198090Srdivacky InVals.push_back(Chain.getValue(0)); 618193323Sed } 619193323Sed 620198090Srdivacky return Chain; 621193323Sed} 622193323Sed 623193323SedSDValue MSP430TargetLowering::LowerShifts(SDValue Op, 624207618Srdivacky SelectionDAG &DAG) const { 625193323Sed unsigned Opc = Op.getOpcode(); 626193323Sed SDNode* N = Op.getNode(); 627198090Srdivacky EVT VT = Op.getValueType(); 628193323Sed DebugLoc dl = N->getDebugLoc(); 629193323Sed 630200581Srdivacky // Expand non-constant shifts to loops: 631193323Sed if (!isa<ConstantSDNode>(N->getOperand(1))) 632200581Srdivacky switch (Opc) { 633234353Sdim default: llvm_unreachable("Invalid shift opcode!"); 634200581Srdivacky case ISD::SHL: 635200581Srdivacky return DAG.getNode(MSP430ISD::SHL, dl, 636200581Srdivacky VT, N->getOperand(0), N->getOperand(1)); 637200581Srdivacky case ISD::SRA: 638200581Srdivacky return DAG.getNode(MSP430ISD::SRA, dl, 639200581Srdivacky VT, N->getOperand(0), N->getOperand(1)); 640200581Srdivacky case ISD::SRL: 641200581Srdivacky return DAG.getNode(MSP430ISD::SRL, dl, 642200581Srdivacky VT, N->getOperand(0), N->getOperand(1)); 643200581Srdivacky } 644193323Sed 645193323Sed uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue(); 646193323Sed 647193323Sed // Expand the stuff into sequence of shifts. 648193323Sed // FIXME: for some shift amounts this might be done better! 649193323Sed // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N 650193323Sed SDValue Victim = N->getOperand(0); 651193323Sed 652193323Sed if (Opc == ISD::SRL && ShiftAmount) { 653193323Sed // Emit a special goodness here: 654193323Sed // srl A, 1 => clrc; rrc A 655193323Sed Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim); 656193323Sed ShiftAmount -= 1; 657193323Sed } 658193323Sed 659193323Sed while (ShiftAmount--) 660193323Sed Victim = DAG.getNode((Opc == ISD::SHL ? MSP430ISD::RLA : MSP430ISD::RRA), 661193323Sed dl, VT, Victim); 662193323Sed 663193323Sed return Victim; 664193323Sed} 665193323Sed 666207618SrdivackySDValue MSP430TargetLowering::LowerGlobalAddress(SDValue Op, 667207618Srdivacky SelectionDAG &DAG) const { 668193323Sed const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); 669193323Sed int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset(); 670193323Sed 671193323Sed // Create the TargetGlobalAddress node, folding in the constant offset. 672210299Sed SDValue Result = DAG.getTargetGlobalAddress(GV, Op.getDebugLoc(), 673210299Sed getPointerTy(), Offset); 674193323Sed return DAG.getNode(MSP430ISD::Wrapper, Op.getDebugLoc(), 675193323Sed getPointerTy(), Result); 676193323Sed} 677193323Sed 678193323SedSDValue MSP430TargetLowering::LowerExternalSymbol(SDValue Op, 679207618Srdivacky SelectionDAG &DAG) const { 680193323Sed DebugLoc dl = Op.getDebugLoc(); 681193323Sed const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol(); 682193323Sed SDValue Result = DAG.getTargetExternalSymbol(Sym, getPointerTy()); 683193323Sed 684234353Sdim return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result); 685193323Sed} 686193323Sed 687207618SrdivackySDValue MSP430TargetLowering::LowerBlockAddress(SDValue Op, 688207618Srdivacky SelectionDAG &DAG) const { 689207618Srdivacky DebugLoc dl = Op.getDebugLoc(); 690207618Srdivacky const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress(); 691243830Sdim SDValue Result = DAG.getTargetBlockAddress(BA, getPointerTy()); 692207618Srdivacky 693234353Sdim return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result); 694207618Srdivacky} 695207618Srdivacky 696198396Srdivackystatic SDValue EmitCMP(SDValue &LHS, SDValue &RHS, SDValue &TargetCC, 697193323Sed ISD::CondCode CC, 698193323Sed DebugLoc dl, SelectionDAG &DAG) { 699193323Sed // FIXME: Handle bittests someday 700193323Sed assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet"); 701193323Sed 702193323Sed // FIXME: Handle jump negative someday 703198396Srdivacky MSP430CC::CondCodes TCC = MSP430CC::COND_INVALID; 704193323Sed switch (CC) { 705198090Srdivacky default: llvm_unreachable("Invalid integer condition!"); 706193323Sed case ISD::SETEQ: 707198396Srdivacky TCC = MSP430CC::COND_E; // aka COND_Z 708202375Srdivacky // Minor optimization: if LHS is a constant, swap operands, then the 709199989Srdivacky // constant can be folded into comparison. 710202375Srdivacky if (LHS.getOpcode() == ISD::Constant) 711199989Srdivacky std::swap(LHS, RHS); 712193323Sed break; 713193323Sed case ISD::SETNE: 714198396Srdivacky TCC = MSP430CC::COND_NE; // aka COND_NZ 715202375Srdivacky // Minor optimization: if LHS is a constant, swap operands, then the 716199989Srdivacky // constant can be folded into comparison. 717202375Srdivacky if (LHS.getOpcode() == ISD::Constant) 718199989Srdivacky std::swap(LHS, RHS); 719193323Sed break; 720193323Sed case ISD::SETULE: 721193323Sed std::swap(LHS, RHS); // FALLTHROUGH 722193323Sed case ISD::SETUGE: 723202878Srdivacky // Turn lhs u>= rhs with lhs constant into rhs u< lhs+1, this allows us to 724202878Srdivacky // fold constant into instruction. 725202878Srdivacky if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 726202878Srdivacky LHS = RHS; 727202878Srdivacky RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 728202878Srdivacky TCC = MSP430CC::COND_LO; 729202878Srdivacky break; 730202878Srdivacky } 731198396Srdivacky TCC = MSP430CC::COND_HS; // aka COND_C 732193323Sed break; 733193323Sed case ISD::SETUGT: 734193323Sed std::swap(LHS, RHS); // FALLTHROUGH 735193323Sed case ISD::SETULT: 736202878Srdivacky // Turn lhs u< rhs with lhs constant into rhs u>= lhs+1, this allows us to 737202878Srdivacky // fold constant into instruction. 738202878Srdivacky if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 739202878Srdivacky LHS = RHS; 740202878Srdivacky RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 741202878Srdivacky TCC = MSP430CC::COND_HS; 742202878Srdivacky break; 743202878Srdivacky } 744198396Srdivacky TCC = MSP430CC::COND_LO; // aka COND_NC 745193323Sed break; 746193323Sed case ISD::SETLE: 747193323Sed std::swap(LHS, RHS); // FALLTHROUGH 748193323Sed case ISD::SETGE: 749202878Srdivacky // Turn lhs >= rhs with lhs constant into rhs < lhs+1, this allows us to 750202878Srdivacky // fold constant into instruction. 751202878Srdivacky if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 752202878Srdivacky LHS = RHS; 753202878Srdivacky RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 754202878Srdivacky TCC = MSP430CC::COND_L; 755202878Srdivacky break; 756202878Srdivacky } 757198396Srdivacky TCC = MSP430CC::COND_GE; 758193323Sed break; 759193323Sed case ISD::SETGT: 760193323Sed std::swap(LHS, RHS); // FALLTHROUGH 761193323Sed case ISD::SETLT: 762202878Srdivacky // Turn lhs < rhs with lhs constant into rhs >= lhs+1, this allows us to 763202878Srdivacky // fold constant into instruction. 764202878Srdivacky if (const ConstantSDNode * C = dyn_cast<ConstantSDNode>(LHS)) { 765202878Srdivacky LHS = RHS; 766202878Srdivacky RHS = DAG.getConstant(C->getSExtValue() + 1, C->getValueType(0)); 767202878Srdivacky TCC = MSP430CC::COND_GE; 768202878Srdivacky break; 769202878Srdivacky } 770198396Srdivacky TCC = MSP430CC::COND_L; 771193323Sed break; 772193323Sed } 773193323Sed 774198396Srdivacky TargetCC = DAG.getConstant(TCC, MVT::i8); 775218893Sdim return DAG.getNode(MSP430ISD::CMP, dl, MVT::Glue, LHS, RHS); 776193323Sed} 777193323Sed 778193323Sed 779207618SrdivackySDValue MSP430TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const { 780193323Sed SDValue Chain = Op.getOperand(0); 781193323Sed ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); 782193323Sed SDValue LHS = Op.getOperand(2); 783193323Sed SDValue RHS = Op.getOperand(3); 784193323Sed SDValue Dest = Op.getOperand(4); 785193323Sed DebugLoc dl = Op.getDebugLoc(); 786193323Sed 787198396Srdivacky SDValue TargetCC; 788193323Sed SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 789193323Sed 790193323Sed return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(), 791198396Srdivacky Chain, Dest, TargetCC, Flag); 792193323Sed} 793193323Sed 794207618SrdivackySDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const { 795200581Srdivacky SDValue LHS = Op.getOperand(0); 796200581Srdivacky SDValue RHS = Op.getOperand(1); 797200581Srdivacky DebugLoc dl = Op.getDebugLoc(); 798200581Srdivacky 799200581Srdivacky // If we are doing an AND and testing against zero, then the CMP 800200581Srdivacky // will not be generated. The AND (or BIT) will generate the condition codes, 801200581Srdivacky // but they are different from CMP. 802202878Srdivacky // FIXME: since we're doing a post-processing, use a pseudoinstr here, so 803202878Srdivacky // lowering & isel wouldn't diverge. 804200581Srdivacky bool andCC = false; 805200581Srdivacky if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) { 806200581Srdivacky if (RHSC->isNullValue() && LHS.hasOneUse() && 807200581Srdivacky (LHS.getOpcode() == ISD::AND || 808200581Srdivacky (LHS.getOpcode() == ISD::TRUNCATE && 809200581Srdivacky LHS.getOperand(0).getOpcode() == ISD::AND))) { 810200581Srdivacky andCC = true; 811200581Srdivacky } 812200581Srdivacky } 813200581Srdivacky ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get(); 814200581Srdivacky SDValue TargetCC; 815200581Srdivacky SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 816200581Srdivacky 817200581Srdivacky // Get the condition codes directly from the status register, if its easy. 818200581Srdivacky // Otherwise a branch will be generated. Note that the AND and BIT 819200581Srdivacky // instructions generate different flags than CMP, the carry bit can be used 820200581Srdivacky // for NE/EQ. 821200581Srdivacky bool Invert = false; 822200581Srdivacky bool Shift = false; 823200581Srdivacky bool Convert = true; 824200581Srdivacky switch (cast<ConstantSDNode>(TargetCC)->getZExtValue()) { 825200581Srdivacky default: 826200581Srdivacky Convert = false; 827200581Srdivacky break; 828200581Srdivacky case MSP430CC::COND_HS: 829200581Srdivacky // Res = SRW & 1, no processing is required 830200581Srdivacky break; 831202878Srdivacky case MSP430CC::COND_LO: 832200581Srdivacky // Res = ~(SRW & 1) 833200581Srdivacky Invert = true; 834200581Srdivacky break; 835202878Srdivacky case MSP430CC::COND_NE: 836200581Srdivacky if (andCC) { 837200581Srdivacky // C = ~Z, thus Res = SRW & 1, no processing is required 838200581Srdivacky } else { 839204642Srdivacky // Res = ~((SRW >> 1) & 1) 840200581Srdivacky Shift = true; 841204642Srdivacky Invert = true; 842200581Srdivacky } 843200581Srdivacky break; 844202878Srdivacky case MSP430CC::COND_E: 845204642Srdivacky Shift = true; 846204642Srdivacky // C = ~Z for AND instruction, thus we can put Res = ~(SRW & 1), however, 847204642Srdivacky // Res = (SRW >> 1) & 1 is 1 word shorter. 848200581Srdivacky break; 849200581Srdivacky } 850200581Srdivacky EVT VT = Op.getValueType(); 851200581Srdivacky SDValue One = DAG.getConstant(1, VT); 852200581Srdivacky if (Convert) { 853200581Srdivacky SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SRW, 854202878Srdivacky MVT::i16, Flag); 855200581Srdivacky if (Shift) 856200581Srdivacky // FIXME: somewhere this is turned into a SRL, lower it MSP specific? 857200581Srdivacky SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One); 858200581Srdivacky SR = DAG.getNode(ISD::AND, dl, MVT::i16, SR, One); 859200581Srdivacky if (Invert) 860200581Srdivacky SR = DAG.getNode(ISD::XOR, dl, MVT::i16, SR, One); 861200581Srdivacky return SR; 862200581Srdivacky } else { 863200581Srdivacky SDValue Zero = DAG.getConstant(0, VT); 864218893Sdim SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue); 865200581Srdivacky SmallVector<SDValue, 4> Ops; 866200581Srdivacky Ops.push_back(One); 867200581Srdivacky Ops.push_back(Zero); 868200581Srdivacky Ops.push_back(TargetCC); 869200581Srdivacky Ops.push_back(Flag); 870200581Srdivacky return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size()); 871200581Srdivacky } 872200581Srdivacky} 873200581Srdivacky 874207618SrdivackySDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op, 875207618Srdivacky SelectionDAG &DAG) const { 876193323Sed SDValue LHS = Op.getOperand(0); 877193323Sed SDValue RHS = Op.getOperand(1); 878193323Sed SDValue TrueV = Op.getOperand(2); 879193323Sed SDValue FalseV = Op.getOperand(3); 880193323Sed ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); 881193323Sed DebugLoc dl = Op.getDebugLoc(); 882193323Sed 883198396Srdivacky SDValue TargetCC; 884193323Sed SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG); 885193323Sed 886218893Sdim SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue); 887193323Sed SmallVector<SDValue, 4> Ops; 888193323Sed Ops.push_back(TrueV); 889193323Sed Ops.push_back(FalseV); 890198396Srdivacky Ops.push_back(TargetCC); 891193323Sed Ops.push_back(Flag); 892193323Sed 893193323Sed return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size()); 894193323Sed} 895193323Sed 896193323SedSDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op, 897207618Srdivacky SelectionDAG &DAG) const { 898193323Sed SDValue Val = Op.getOperand(0); 899198090Srdivacky EVT VT = Op.getValueType(); 900193323Sed DebugLoc dl = Op.getDebugLoc(); 901193323Sed 902193323Sed assert(VT == MVT::i16 && "Only support i16 for now!"); 903193323Sed 904193323Sed return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT, 905193323Sed DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val), 906193323Sed DAG.getValueType(Val.getValueType())); 907193323Sed} 908193323Sed 909207618SrdivackySDValue 910207618SrdivackyMSP430TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) const { 911200581Srdivacky MachineFunction &MF = DAG.getMachineFunction(); 912200581Srdivacky MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>(); 913200581Srdivacky int ReturnAddrIndex = FuncInfo->getRAIndex(); 914200581Srdivacky 915200581Srdivacky if (ReturnAddrIndex == 0) { 916200581Srdivacky // Set up a frame object for the return address. 917200581Srdivacky uint64_t SlotSize = TD->getPointerSize(); 918200581Srdivacky ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(SlotSize, -SlotSize, 919210299Sed true); 920200581Srdivacky FuncInfo->setRAIndex(ReturnAddrIndex); 921200581Srdivacky } 922200581Srdivacky 923200581Srdivacky return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy()); 924200581Srdivacky} 925200581Srdivacky 926207618SrdivackySDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op, 927207618Srdivacky SelectionDAG &DAG) const { 928208599Srdivacky MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 929208599Srdivacky MFI->setReturnAddressIsTaken(true); 930208599Srdivacky 931200581Srdivacky unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); 932200581Srdivacky DebugLoc dl = Op.getDebugLoc(); 933200581Srdivacky 934200581Srdivacky if (Depth > 0) { 935200581Srdivacky SDValue FrameAddr = LowerFRAMEADDR(Op, DAG); 936200581Srdivacky SDValue Offset = 937200581Srdivacky DAG.getConstant(TD->getPointerSize(), MVT::i16); 938200581Srdivacky return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), 939200581Srdivacky DAG.getNode(ISD::ADD, dl, getPointerTy(), 940200581Srdivacky FrameAddr, Offset), 941234353Sdim MachinePointerInfo(), false, false, false, 0); 942200581Srdivacky } 943200581Srdivacky 944200581Srdivacky // Just load the return address. 945200581Srdivacky SDValue RetAddrFI = getReturnAddressFrameIndex(DAG); 946200581Srdivacky return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), 947234353Sdim RetAddrFI, MachinePointerInfo(), false, false, false, 0); 948200581Srdivacky} 949200581Srdivacky 950207618SrdivackySDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op, 951207618Srdivacky SelectionDAG &DAG) const { 952200581Srdivacky MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); 953200581Srdivacky MFI->setFrameAddressIsTaken(true); 954208599Srdivacky 955200581Srdivacky EVT VT = Op.getValueType(); 956200581Srdivacky DebugLoc dl = Op.getDebugLoc(); // FIXME probably not meaningful 957200581Srdivacky unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); 958200581Srdivacky SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, 959200581Srdivacky MSP430::FPW, VT); 960200581Srdivacky while (Depth--) 961218893Sdim FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr, 962218893Sdim MachinePointerInfo(), 963234353Sdim false, false, false, 0); 964200581Srdivacky return FrameAddr; 965200581Srdivacky} 966200581Srdivacky 967249423SdimSDValue MSP430TargetLowering::LowerVASTART(SDValue Op, 968249423Sdim SelectionDAG &DAG) const { 969249423Sdim MachineFunction &MF = DAG.getMachineFunction(); 970249423Sdim MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>(); 971249423Sdim 972249423Sdim // Frame index of first vararg argument 973249423Sdim SDValue FrameIndex = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), 974249423Sdim getPointerTy()); 975249423Sdim const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); 976249423Sdim 977249423Sdim // Create a store of the frame index to the location operand 978249423Sdim return DAG.getStore(Op.getOperand(0), Op.getDebugLoc(), FrameIndex, 979249423Sdim Op.getOperand(1), MachinePointerInfo(SV), 980249423Sdim false, false, 0); 981249423Sdim} 982249423Sdim 983199481Srdivacky/// getPostIndexedAddressParts - returns true by value, base pointer and 984199481Srdivacky/// offset pointer and addressing mode by reference if this node can be 985199481Srdivacky/// combined with a load / store to form a post-indexed load / store. 986199481Srdivackybool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op, 987199481Srdivacky SDValue &Base, 988199481Srdivacky SDValue &Offset, 989199481Srdivacky ISD::MemIndexedMode &AM, 990199481Srdivacky SelectionDAG &DAG) const { 991199481Srdivacky 992199481Srdivacky LoadSDNode *LD = cast<LoadSDNode>(N); 993199481Srdivacky if (LD->getExtensionType() != ISD::NON_EXTLOAD) 994199481Srdivacky return false; 995199481Srdivacky 996199481Srdivacky EVT VT = LD->getMemoryVT(); 997199481Srdivacky if (VT != MVT::i8 && VT != MVT::i16) 998199481Srdivacky return false; 999199481Srdivacky 1000199481Srdivacky if (Op->getOpcode() != ISD::ADD) 1001199481Srdivacky return false; 1002199481Srdivacky 1003199481Srdivacky if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(Op->getOperand(1))) { 1004199481Srdivacky uint64_t RHSC = RHS->getZExtValue(); 1005199481Srdivacky if ((VT == MVT::i16 && RHSC != 2) || 1006199481Srdivacky (VT == MVT::i8 && RHSC != 1)) 1007199481Srdivacky return false; 1008199481Srdivacky 1009199481Srdivacky Base = Op->getOperand(0); 1010199481Srdivacky Offset = DAG.getConstant(RHSC, VT); 1011199481Srdivacky AM = ISD::POST_INC; 1012199481Srdivacky return true; 1013199481Srdivacky } 1014199481Srdivacky 1015199481Srdivacky return false; 1016199481Srdivacky} 1017199481Srdivacky 1018199481Srdivacky 1019193323Sedconst char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const { 1020193323Sed switch (Opcode) { 1021193323Sed default: return NULL; 1022193323Sed case MSP430ISD::RET_FLAG: return "MSP430ISD::RET_FLAG"; 1023200581Srdivacky case MSP430ISD::RETI_FLAG: return "MSP430ISD::RETI_FLAG"; 1024193323Sed case MSP430ISD::RRA: return "MSP430ISD::RRA"; 1025193323Sed case MSP430ISD::RLA: return "MSP430ISD::RLA"; 1026193323Sed case MSP430ISD::RRC: return "MSP430ISD::RRC"; 1027193323Sed case MSP430ISD::CALL: return "MSP430ISD::CALL"; 1028193323Sed case MSP430ISD::Wrapper: return "MSP430ISD::Wrapper"; 1029193323Sed case MSP430ISD::BR_CC: return "MSP430ISD::BR_CC"; 1030193323Sed case MSP430ISD::CMP: return "MSP430ISD::CMP"; 1031193323Sed case MSP430ISD::SELECT_CC: return "MSP430ISD::SELECT_CC"; 1032200581Srdivacky case MSP430ISD::SHL: return "MSP430ISD::SHL"; 1033200581Srdivacky case MSP430ISD::SRA: return "MSP430ISD::SRA"; 1034193323Sed } 1035193323Sed} 1036193323Sed 1037226633Sdimbool MSP430TargetLowering::isTruncateFree(Type *Ty1, 1038226633Sdim Type *Ty2) const { 1039203954Srdivacky if (!Ty1->isIntegerTy() || !Ty2->isIntegerTy()) 1040202878Srdivacky return false; 1041202878Srdivacky 1042202878Srdivacky return (Ty1->getPrimitiveSizeInBits() > Ty2->getPrimitiveSizeInBits()); 1043202878Srdivacky} 1044202878Srdivacky 1045202878Srdivackybool MSP430TargetLowering::isTruncateFree(EVT VT1, EVT VT2) const { 1046202878Srdivacky if (!VT1.isInteger() || !VT2.isInteger()) 1047202878Srdivacky return false; 1048202878Srdivacky 1049202878Srdivacky return (VT1.getSizeInBits() > VT2.getSizeInBits()); 1050202878Srdivacky} 1051202878Srdivacky 1052226633Sdimbool MSP430TargetLowering::isZExtFree(Type *Ty1, Type *Ty2) const { 1053202878Srdivacky // MSP430 implicitly zero-extends 8-bit results in 16-bit registers. 1054203954Srdivacky return 0 && Ty1->isIntegerTy(8) && Ty2->isIntegerTy(16); 1055202878Srdivacky} 1056202878Srdivacky 1057202878Srdivackybool MSP430TargetLowering::isZExtFree(EVT VT1, EVT VT2) const { 1058202878Srdivacky // MSP430 implicitly zero-extends 8-bit results in 16-bit registers. 1059202878Srdivacky return 0 && VT1 == MVT::i8 && VT2 == MVT::i16; 1060202878Srdivacky} 1061202878Srdivacky 1062249423Sdimbool MSP430TargetLowering::isZExtFree(SDValue Val, EVT VT2) const { 1063249423Sdim return isZExtFree(Val.getValueType(), VT2); 1064249423Sdim} 1065249423Sdim 1066193323Sed//===----------------------------------------------------------------------===// 1067193323Sed// Other Lowering Code 1068193323Sed//===----------------------------------------------------------------------===// 1069193323Sed 1070193323SedMachineBasicBlock* 1071200581SrdivackyMSP430TargetLowering::EmitShiftInstr(MachineInstr *MI, 1072207618Srdivacky MachineBasicBlock *BB) const { 1073200581Srdivacky MachineFunction *F = BB->getParent(); 1074200581Srdivacky MachineRegisterInfo &RI = F->getRegInfo(); 1075200581Srdivacky DebugLoc dl = MI->getDebugLoc(); 1076200581Srdivacky const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); 1077200581Srdivacky 1078200581Srdivacky unsigned Opc; 1079200581Srdivacky const TargetRegisterClass * RC; 1080200581Srdivacky switch (MI->getOpcode()) { 1081234353Sdim default: llvm_unreachable("Invalid shift opcode!"); 1082200581Srdivacky case MSP430::Shl8: 1083200581Srdivacky Opc = MSP430::SHL8r1; 1084239462Sdim RC = &MSP430::GR8RegClass; 1085200581Srdivacky break; 1086200581Srdivacky case MSP430::Shl16: 1087200581Srdivacky Opc = MSP430::SHL16r1; 1088239462Sdim RC = &MSP430::GR16RegClass; 1089200581Srdivacky break; 1090200581Srdivacky case MSP430::Sra8: 1091200581Srdivacky Opc = MSP430::SAR8r1; 1092239462Sdim RC = &MSP430::GR8RegClass; 1093200581Srdivacky break; 1094200581Srdivacky case MSP430::Sra16: 1095200581Srdivacky Opc = MSP430::SAR16r1; 1096239462Sdim RC = &MSP430::GR16RegClass; 1097200581Srdivacky break; 1098200581Srdivacky case MSP430::Srl8: 1099200581Srdivacky Opc = MSP430::SAR8r1c; 1100239462Sdim RC = &MSP430::GR8RegClass; 1101200581Srdivacky break; 1102200581Srdivacky case MSP430::Srl16: 1103200581Srdivacky Opc = MSP430::SAR16r1c; 1104239462Sdim RC = &MSP430::GR16RegClass; 1105200581Srdivacky break; 1106200581Srdivacky } 1107200581Srdivacky 1108200581Srdivacky const BasicBlock *LLVM_BB = BB->getBasicBlock(); 1109200581Srdivacky MachineFunction::iterator I = BB; 1110200581Srdivacky ++I; 1111200581Srdivacky 1112200581Srdivacky // Create loop block 1113200581Srdivacky MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB); 1114200581Srdivacky MachineBasicBlock *RemBB = F->CreateMachineBasicBlock(LLVM_BB); 1115200581Srdivacky 1116200581Srdivacky F->insert(I, LoopBB); 1117200581Srdivacky F->insert(I, RemBB); 1118200581Srdivacky 1119200581Srdivacky // Update machine-CFG edges by transferring all successors of the current 1120200581Srdivacky // block to the block containing instructions after shift. 1121210299Sed RemBB->splice(RemBB->begin(), BB, 1122210299Sed llvm::next(MachineBasicBlock::iterator(MI)), 1123210299Sed BB->end()); 1124210299Sed RemBB->transferSuccessorsAndUpdatePHIs(BB); 1125200581Srdivacky 1126200581Srdivacky // Add adges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB 1127200581Srdivacky BB->addSuccessor(LoopBB); 1128200581Srdivacky BB->addSuccessor(RemBB); 1129200581Srdivacky LoopBB->addSuccessor(RemBB); 1130200581Srdivacky LoopBB->addSuccessor(LoopBB); 1131200581Srdivacky 1132239462Sdim unsigned ShiftAmtReg = RI.createVirtualRegister(&MSP430::GR8RegClass); 1133239462Sdim unsigned ShiftAmtReg2 = RI.createVirtualRegister(&MSP430::GR8RegClass); 1134200581Srdivacky unsigned ShiftReg = RI.createVirtualRegister(RC); 1135200581Srdivacky unsigned ShiftReg2 = RI.createVirtualRegister(RC); 1136200581Srdivacky unsigned ShiftAmtSrcReg = MI->getOperand(2).getReg(); 1137200581Srdivacky unsigned SrcReg = MI->getOperand(1).getReg(); 1138200581Srdivacky unsigned DstReg = MI->getOperand(0).getReg(); 1139200581Srdivacky 1140200581Srdivacky // BB: 1141200581Srdivacky // cmp 0, N 1142200581Srdivacky // je RemBB 1143202375Srdivacky BuildMI(BB, dl, TII.get(MSP430::CMP8ri)) 1144202375Srdivacky .addReg(ShiftAmtSrcReg).addImm(0); 1145200581Srdivacky BuildMI(BB, dl, TII.get(MSP430::JCC)) 1146200581Srdivacky .addMBB(RemBB) 1147200581Srdivacky .addImm(MSP430CC::COND_E); 1148200581Srdivacky 1149200581Srdivacky // LoopBB: 1150200581Srdivacky // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB] 1151200581Srdivacky // ShiftAmt = phi [%N, BB], [%ShiftAmt2, LoopBB] 1152200581Srdivacky // ShiftReg2 = shift ShiftReg 1153200581Srdivacky // ShiftAmt2 = ShiftAmt - 1; 1154200581Srdivacky BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftReg) 1155200581Srdivacky .addReg(SrcReg).addMBB(BB) 1156200581Srdivacky .addReg(ShiftReg2).addMBB(LoopBB); 1157200581Srdivacky BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg) 1158200581Srdivacky .addReg(ShiftAmtSrcReg).addMBB(BB) 1159200581Srdivacky .addReg(ShiftAmtReg2).addMBB(LoopBB); 1160200581Srdivacky BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2) 1161200581Srdivacky .addReg(ShiftReg); 1162200581Srdivacky BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2) 1163200581Srdivacky .addReg(ShiftAmtReg).addImm(1); 1164200581Srdivacky BuildMI(LoopBB, dl, TII.get(MSP430::JCC)) 1165200581Srdivacky .addMBB(LoopBB) 1166200581Srdivacky .addImm(MSP430CC::COND_NE); 1167200581Srdivacky 1168200581Srdivacky // RemBB: 1169200581Srdivacky // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB] 1170210299Sed BuildMI(*RemBB, RemBB->begin(), dl, TII.get(MSP430::PHI), DstReg) 1171200581Srdivacky .addReg(SrcReg).addMBB(BB) 1172200581Srdivacky .addReg(ShiftReg2).addMBB(LoopBB); 1173200581Srdivacky 1174210299Sed MI->eraseFromParent(); // The pseudo instruction is gone now. 1175200581Srdivacky return RemBB; 1176200581Srdivacky} 1177200581Srdivacky 1178200581SrdivackyMachineBasicBlock* 1179193323SedMSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 1180207618Srdivacky MachineBasicBlock *BB) const { 1181200581Srdivacky unsigned Opc = MI->getOpcode(); 1182200581Srdivacky 1183200581Srdivacky if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 || 1184200581Srdivacky Opc == MSP430::Sra8 || Opc == MSP430::Sra16 || 1185200581Srdivacky Opc == MSP430::Srl8 || Opc == MSP430::Srl16) 1186207618Srdivacky return EmitShiftInstr(MI, BB); 1187200581Srdivacky 1188193323Sed const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); 1189193323Sed DebugLoc dl = MI->getDebugLoc(); 1190200581Srdivacky 1191200581Srdivacky assert((Opc == MSP430::Select16 || Opc == MSP430::Select8) && 1192193323Sed "Unexpected instr type to insert"); 1193193323Sed 1194193323Sed // To "insert" a SELECT instruction, we actually have to insert the diamond 1195193323Sed // control-flow pattern. The incoming instruction knows the destination vreg 1196193323Sed // to set, the condition code register to branch on, the true/false values to 1197193323Sed // select between, and a branch opcode to use. 1198193323Sed const BasicBlock *LLVM_BB = BB->getBasicBlock(); 1199193323Sed MachineFunction::iterator I = BB; 1200193323Sed ++I; 1201193323Sed 1202193323Sed // thisMBB: 1203193323Sed // ... 1204193323Sed // TrueVal = ... 1205193323Sed // cmpTY ccX, r1, r2 1206193323Sed // jCC copy1MBB 1207193323Sed // fallthrough --> copy0MBB 1208193323Sed MachineBasicBlock *thisMBB = BB; 1209193323Sed MachineFunction *F = BB->getParent(); 1210193323Sed MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); 1211193323Sed MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB); 1212193323Sed F->insert(I, copy0MBB); 1213193323Sed F->insert(I, copy1MBB); 1214193323Sed // Update machine-CFG edges by transferring all successors of the current 1215193323Sed // block to the new block which will contain the Phi node for the select. 1216210299Sed copy1MBB->splice(copy1MBB->begin(), BB, 1217210299Sed llvm::next(MachineBasicBlock::iterator(MI)), 1218210299Sed BB->end()); 1219210299Sed copy1MBB->transferSuccessorsAndUpdatePHIs(BB); 1220193323Sed // Next, add the true and fallthrough blocks as its successors. 1221193323Sed BB->addSuccessor(copy0MBB); 1222193323Sed BB->addSuccessor(copy1MBB); 1223193323Sed 1224210299Sed BuildMI(BB, dl, TII.get(MSP430::JCC)) 1225210299Sed .addMBB(copy1MBB) 1226210299Sed .addImm(MI->getOperand(3).getImm()); 1227210299Sed 1228193323Sed // copy0MBB: 1229193323Sed // %FalseValue = ... 1230193323Sed // # fallthrough to copy1MBB 1231193323Sed BB = copy0MBB; 1232193323Sed 1233193323Sed // Update machine-CFG edges 1234193323Sed BB->addSuccessor(copy1MBB); 1235193323Sed 1236193323Sed // copy1MBB: 1237193323Sed // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] 1238193323Sed // ... 1239193323Sed BB = copy1MBB; 1240210299Sed BuildMI(*BB, BB->begin(), dl, TII.get(MSP430::PHI), 1241193323Sed MI->getOperand(0).getReg()) 1242193323Sed .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB) 1243193323Sed .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB); 1244193323Sed 1245210299Sed MI->eraseFromParent(); // The pseudo instruction is gone now. 1246193323Sed return BB; 1247193323Sed} 1248