MSP430ISelLowering.cpp revision e699d0f549151a2cca993c21407aea4a6eff7d3f
1//===-- MSP430ISelLowering.cpp - MSP430 DAG Lowering Implementation ------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the MSP430TargetLowering class. 11// 12//===----------------------------------------------------------------------===// 13 14#define DEBUG_TYPE "msp430-lower" 15 16#include "MSP430ISelLowering.h" 17#include "MSP430.h" 18#include "MSP430TargetMachine.h" 19#include "MSP430Subtarget.h" 20#include "llvm/DerivedTypes.h" 21#include "llvm/Function.h" 22#include "llvm/Intrinsics.h" 23#include "llvm/CallingConv.h" 24#include "llvm/GlobalVariable.h" 25#include "llvm/GlobalAlias.h" 26#include "llvm/CodeGen/CallingConvLower.h" 27#include "llvm/CodeGen/MachineFrameInfo.h" 28#include "llvm/CodeGen/MachineFunction.h" 29#include "llvm/CodeGen/MachineInstrBuilder.h" 30#include "llvm/CodeGen/MachineRegisterInfo.h" 31#include "llvm/CodeGen/PseudoSourceValue.h" 32#include "llvm/CodeGen/SelectionDAGISel.h" 33#include "llvm/CodeGen/ValueTypes.h" 34#include "llvm/Support/Debug.h" 35#include "llvm/ADT/VectorExtras.h" 36using namespace llvm; 37 38MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) : 39 TargetLowering(tm), Subtarget(*tm.getSubtargetImpl()), TM(tm) { 40 41 // Set up the register classes. 42 addRegisterClass(MVT::i8, MSP430::GR8RegisterClass); 43 addRegisterClass(MVT::i16, MSP430::GR16RegisterClass); 44 45 // Compute derived properties from the register classes 46 computeRegisterProperties(); 47 48 // Provide all sorts of operation actions 49 50 // Division is expensive 51 setIntDivIsCheap(false); 52 53 // Even if we have only 1 bit shift here, we can perform 54 // shifts of the whole bitwidth 1 bit per step. 55 setShiftAmountType(MVT::i8); 56 57 setStackPointerRegisterToSaveRestore(MSP430::SPW); 58 setBooleanContents(ZeroOrOneBooleanContent); 59 setSchedulingPreference(SchedulingForLatency); 60 61 setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); 62 setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); 63 setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); 64 setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Expand); 65 setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Expand); 66 67 // We don't have any truncstores 68 setTruncStoreAction(MVT::i16, MVT::i8, Expand); 69 70 setOperationAction(ISD::SRA, MVT::i16, Custom); 71 setOperationAction(ISD::SHL, MVT::i16, Custom); 72 setOperationAction(ISD::SRL, MVT::i16, Custom); 73 setOperationAction(ISD::RET, MVT::Other, Custom); 74 setOperationAction(ISD::GlobalAddress, MVT::i16, Custom); 75 setOperationAction(ISD::ExternalSymbol, MVT::i16, Custom); 76 setOperationAction(ISD::BR_JT, MVT::Other, Expand); 77 setOperationAction(ISD::BRIND, MVT::Other, Expand); 78 setOperationAction(ISD::BR_CC, MVT::Other, Expand); 79 setOperationAction(ISD::BRCOND, MVT::Other, Custom); 80 setOperationAction(ISD::SETCC, MVT::i8, Custom); 81 setOperationAction(ISD::SETCC, MVT::i16, Custom); 82 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand); 83 setOperationAction(ISD::SELECT, MVT::i8, Custom); 84 setOperationAction(ISD::SELECT, MVT::i16, Custom); 85 86 // FIXME: Implement efficiently multiplication by a constant 87 setOperationAction(ISD::MUL, MVT::i16, Expand); 88 setOperationAction(ISD::MULHS, MVT::i16, Expand); 89 setOperationAction(ISD::MULHU, MVT::i16, Expand); 90 setOperationAction(ISD::SMUL_LOHI, MVT::i16, Expand); 91 setOperationAction(ISD::UMUL_LOHI, MVT::i16, Expand); 92} 93 94SDValue MSP430TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { 95 switch (Op.getOpcode()) { 96 case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG); 97 case ISD::SHL: // FALLTHROUGH 98 case ISD::SRL: 99 case ISD::SRA: return LowerShifts(Op, DAG); 100 case ISD::RET: return LowerRET(Op, DAG); 101 case ISD::CALL: return LowerCALL(Op, DAG); 102 case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); 103 case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG); 104 case ISD::SETCC: return LowerSETCC(Op, DAG); 105 case ISD::BRCOND: return LowerBRCOND(Op, DAG); 106 case ISD::SELECT: return LowerSELECT(Op, DAG); 107 default: 108 assert(0 && "unimplemented operand"); 109 return SDValue(); 110 } 111} 112 113//===----------------------------------------------------------------------===// 114// Calling Convention Implementation 115//===----------------------------------------------------------------------===// 116 117#include "MSP430GenCallingConv.inc" 118 119SDValue MSP430TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, 120 SelectionDAG &DAG) { 121 unsigned CC = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); 122 switch (CC) { 123 default: 124 assert(0 && "Unsupported calling convention"); 125 case CallingConv::C: 126 case CallingConv::Fast: 127 return LowerCCCArguments(Op, DAG); 128 } 129} 130 131SDValue MSP430TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { 132 CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); 133 unsigned CallingConv = TheCall->getCallingConv(); 134 switch (CallingConv) { 135 default: 136 assert(0 && "Unsupported calling convention"); 137 case CallingConv::Fast: 138 case CallingConv::C: 139 return LowerCCCCallTo(Op, DAG, CallingConv); 140 } 141} 142 143/// LowerCCCArguments - transform physical registers into virtual registers and 144/// generate load operations for arguments places on the stack. 145// FIXME: struct return stuff 146// FIXME: varargs 147SDValue MSP430TargetLowering::LowerCCCArguments(SDValue Op, 148 SelectionDAG &DAG) { 149 MachineFunction &MF = DAG.getMachineFunction(); 150 MachineFrameInfo *MFI = MF.getFrameInfo(); 151 MachineRegisterInfo &RegInfo = MF.getRegInfo(); 152 SDValue Root = Op.getOperand(0); 153 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0; 154 unsigned CC = MF.getFunction()->getCallingConv(); 155 DebugLoc dl = Op.getDebugLoc(); 156 157 // Assign locations to all of the incoming arguments. 158 SmallVector<CCValAssign, 16> ArgLocs; 159 CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); 160 CCInfo.AnalyzeFormalArguments(Op.getNode(), CC_MSP430); 161 162 assert(!isVarArg && "Varargs not supported yet"); 163 164 SmallVector<SDValue, 16> ArgValues; 165 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 166 CCValAssign &VA = ArgLocs[i]; 167 if (VA.isRegLoc()) { 168 // Arguments passed in registers 169 MVT RegVT = VA.getLocVT(); 170 switch (RegVT.getSimpleVT()) { 171 default: 172 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: " 173 << RegVT.getSimpleVT() 174 << "\n"; 175 abort(); 176 case MVT::i16: 177 unsigned VReg = 178 RegInfo.createVirtualRegister(MSP430::GR16RegisterClass); 179 RegInfo.addLiveIn(VA.getLocReg(), VReg); 180 SDValue ArgValue = DAG.getCopyFromReg(Root, dl, VReg, RegVT); 181 182 // If this is an 8-bit value, it is really passed promoted to 16 183 // bits. Insert an assert[sz]ext to capture this, then truncate to the 184 // right size. 185 if (VA.getLocInfo() == CCValAssign::SExt) 186 ArgValue = DAG.getNode(ISD::AssertSext, dl, RegVT, ArgValue, 187 DAG.getValueType(VA.getValVT())); 188 else if (VA.getLocInfo() == CCValAssign::ZExt) 189 ArgValue = DAG.getNode(ISD::AssertZext, dl, RegVT, ArgValue, 190 DAG.getValueType(VA.getValVT())); 191 192 if (VA.getLocInfo() != CCValAssign::Full) 193 ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); 194 195 ArgValues.push_back(ArgValue); 196 } 197 } else { 198 // Sanity check 199 assert(VA.isMemLoc()); 200 // Load the argument to a virtual register 201 unsigned ObjSize = VA.getLocVT().getSizeInBits()/8; 202 if (ObjSize > 2) { 203 cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: " 204 << VA.getLocVT().getSimpleVT() 205 << "\n"; 206 } 207 // Create the frame index object for this incoming parameter... 208 int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset()); 209 210 // Create the SelectionDAG nodes corresponding to a load 211 //from this parameter 212 SDValue FIN = DAG.getFrameIndex(FI, MVT::i16); 213 ArgValues.push_back(DAG.getLoad(VA.getLocVT(), dl, Root, FIN, 214 PseudoSourceValue::getFixedStack(FI), 0)); 215 } 216 } 217 218 ArgValues.push_back(Root); 219 220 // Return the new list of results. 221 return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(), 222 &ArgValues[0], ArgValues.size()).getValue(Op.getResNo()); 223} 224 225SDValue MSP430TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { 226 // CCValAssign - represent the assignment of the return value to a location 227 SmallVector<CCValAssign, 16> RVLocs; 228 unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv(); 229 bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg(); 230 DebugLoc dl = Op.getDebugLoc(); 231 232 // CCState - Info about the registers and stack slot. 233 CCState CCInfo(CC, isVarArg, getTargetMachine(), RVLocs); 234 235 // Analize return values of ISD::RET 236 CCInfo.AnalyzeReturn(Op.getNode(), RetCC_MSP430); 237 238 // If this is the first return lowered for this function, add the regs to the 239 // liveout set for the function. 240 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) { 241 for (unsigned i = 0; i != RVLocs.size(); ++i) 242 if (RVLocs[i].isRegLoc()) 243 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); 244 } 245 246 // The chain is always operand #0 247 SDValue Chain = Op.getOperand(0); 248 SDValue Flag; 249 250 // Copy the result values into the output registers. 251 for (unsigned i = 0; i != RVLocs.size(); ++i) { 252 CCValAssign &VA = RVLocs[i]; 253 assert(VA.isRegLoc() && "Can only return in registers!"); 254 255 // ISD::RET => ret chain, (regnum1,val1), ... 256 // So i*2+1 index only the regnums 257 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), 258 Op.getOperand(i*2+1), Flag); 259 260 // Guarantee that all emitted copies are stuck together, 261 // avoiding something bad. 262 Flag = Chain.getValue(1); 263 } 264 265 if (Flag.getNode()) 266 return DAG.getNode(MSP430ISD::RET_FLAG, dl, MVT::Other, Chain, Flag); 267 268 // Return Void 269 return DAG.getNode(MSP430ISD::RET_FLAG, dl, MVT::Other, Chain); 270} 271 272/// LowerCCCCallTo - functions arguments are copied from virtual regs to 273/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted. 274/// TODO: sret. 275SDValue MSP430TargetLowering::LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, 276 unsigned CC) { 277 CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); 278 SDValue Chain = TheCall->getChain(); 279 SDValue Callee = TheCall->getCallee(); 280 bool isVarArg = TheCall->isVarArg(); 281 DebugLoc dl = Op.getDebugLoc(); 282 283 // Analyze operands of the call, assigning locations to each operand. 284 SmallVector<CCValAssign, 16> ArgLocs; 285 CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); 286 287 CCInfo.AnalyzeCallOperands(TheCall, CC_MSP430); 288 289 // Get a count of how many bytes are to be pushed on the stack. 290 unsigned NumBytes = CCInfo.getNextStackOffset(); 291 292 Chain = DAG.getCALLSEQ_START(Chain ,DAG.getConstant(NumBytes, 293 getPointerTy(), true)); 294 295 SmallVector<std::pair<unsigned, SDValue>, 4> RegsToPass; 296 SmallVector<SDValue, 12> MemOpChains; 297 SDValue StackPtr; 298 299 // Walk the register/memloc assignments, inserting copies/loads. 300 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 301 CCValAssign &VA = ArgLocs[i]; 302 303 // Arguments start after the 5 first operands of ISD::CALL 304 SDValue Arg = TheCall->getArg(i); 305 306 // Promote the value if needed. 307 switch (VA.getLocInfo()) { 308 default: assert(0 && "Unknown loc info!"); 309 case CCValAssign::Full: break; 310 case CCValAssign::SExt: 311 Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); 312 break; 313 case CCValAssign::ZExt: 314 Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg); 315 break; 316 case CCValAssign::AExt: 317 Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg); 318 break; 319 } 320 321 // Arguments that can be passed on register must be kept at RegsToPass 322 // vector 323 if (VA.isRegLoc()) { 324 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 325 } else { 326 assert(VA.isMemLoc()); 327 328 if (StackPtr.getNode() == 0) 329 StackPtr = DAG.getCopyFromReg(Chain, dl, MSP430::SPW, getPointerTy()); 330 331 SDValue PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(), 332 StackPtr, 333 DAG.getIntPtrConstant(VA.getLocMemOffset())); 334 335 336 MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, 337 PseudoSourceValue::getStack(), 338 VA.getLocMemOffset())); 339 } 340 } 341 342 // Transform all store nodes into one single node because all store nodes are 343 // independent of each other. 344 if (!MemOpChains.empty()) 345 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 346 &MemOpChains[0], MemOpChains.size()); 347 348 // Build a sequence of copy-to-reg nodes chained together with token chain and 349 // flag operands which copy the outgoing args into registers. The InFlag in 350 // necessary since all emited instructions must be stuck together. 351 SDValue InFlag; 352 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 353 Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, 354 RegsToPass[i].second, InFlag); 355 InFlag = Chain.getValue(1); 356 } 357 358 // If the callee is a GlobalAddress node (quite common, every direct call is) 359 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 360 // Likewise ExternalSymbol -> TargetExternalSymbol. 361 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 362 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i16); 363 else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) 364 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i16); 365 366 // Returns a chain & a flag for retval copy to use. 367 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); 368 SmallVector<SDValue, 8> Ops; 369 Ops.push_back(Chain); 370 Ops.push_back(Callee); 371 372 // Add argument registers to the end of the list so that they are 373 // known live into the call. 374 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 375 Ops.push_back(DAG.getRegister(RegsToPass[i].first, 376 RegsToPass[i].second.getValueType())); 377 378 if (InFlag.getNode()) 379 Ops.push_back(InFlag); 380 381 Chain = DAG.getNode(MSP430ISD::CALL, dl, NodeTys, &Ops[0], Ops.size()); 382 InFlag = Chain.getValue(1); 383 384 // Create the CALLSEQ_END node. 385 Chain = DAG.getCALLSEQ_END(Chain, 386 DAG.getConstant(NumBytes, getPointerTy(), true), 387 DAG.getConstant(0, getPointerTy(), true), 388 InFlag); 389 InFlag = Chain.getValue(1); 390 391 // Handle result values, copying them out of physregs into vregs that we 392 // return. 393 return SDValue(LowerCallResult(Chain, InFlag, TheCall, CC, DAG), 394 Op.getResNo()); 395} 396 397/// LowerCallResult - Lower the result values of an ISD::CALL into the 398/// appropriate copies out of appropriate physical registers. This assumes that 399/// Chain/InFlag are the input chain/flag to use, and that TheCall is the call 400/// being lowered. Returns a SDNode with the same number of values as the 401/// ISD::CALL. 402SDNode* 403MSP430TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, 404 CallSDNode *TheCall, 405 unsigned CallingConv, 406 SelectionDAG &DAG) { 407 bool isVarArg = TheCall->isVarArg(); 408 DebugLoc dl = TheCall->getDebugLoc(); 409 410 // Assign locations to each value returned by this call. 411 SmallVector<CCValAssign, 16> RVLocs; 412 CCState CCInfo(CallingConv, isVarArg, getTargetMachine(), RVLocs); 413 414 CCInfo.AnalyzeCallResult(TheCall, RetCC_MSP430); 415 SmallVector<SDValue, 8> ResultVals; 416 417 // Copy all of the result registers out of their specified physreg. 418 for (unsigned i = 0; i != RVLocs.size(); ++i) { 419 Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(), 420 RVLocs[i].getValVT(), InFlag).getValue(1); 421 InFlag = Chain.getValue(2); 422 ResultVals.push_back(Chain.getValue(0)); 423 } 424 425 ResultVals.push_back(Chain); 426 427 // Merge everything together with a MERGE_VALUES node. 428 return DAG.getNode(ISD::MERGE_VALUES, dl, TheCall->getVTList(), 429 &ResultVals[0], ResultVals.size()).getNode(); 430} 431 432SDValue MSP430TargetLowering::LowerShifts(SDValue Op, 433 SelectionDAG &DAG) { 434 unsigned Opc = Op.getOpcode(); 435 SDNode* N = Op.getNode(); 436 MVT VT = Op.getValueType(); 437 DebugLoc dl = N->getDebugLoc(); 438 439 // We currently only lower shifts of constant argument. 440 if (!isa<ConstantSDNode>(N->getOperand(1))) 441 return SDValue(); 442 443 uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue(); 444 445 // Expand the stuff into sequence of shifts. 446 // FIXME: for some shift amounts this might be done better! 447 // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N 448 SDValue Victim = N->getOperand(0); 449 450 if (Opc == ISD::SRL && ShiftAmount) { 451 // Emit a special goodness here: 452 // srl A, 1 => clrc; rrc A 453 SDValue clrc = DAG.getNode(MSP430ISD::CLRC, dl, MVT::Other); 454 Victim = DAG.getNode(MSP430ISD::RRC, dl, VT, Victim, clrc); 455 ShiftAmount -= 1; 456 } 457 458 while (ShiftAmount--) 459 Victim = DAG.getNode((Opc == ISD::SRA ? MSP430ISD::RRA : MSP430ISD::RLA), 460 dl, VT, Victim); 461 462 return Victim; 463} 464 465SDValue MSP430TargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) { 466 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); 467 int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset(); 468 469 // Create the TargetGlobalAddress node, folding in the constant offset. 470 SDValue Result = DAG.getTargetGlobalAddress(GV, getPointerTy(), Offset); 471 return DAG.getNode(MSP430ISD::Wrapper, Op.getDebugLoc(), 472 getPointerTy(), Result); 473} 474 475SDValue MSP430TargetLowering::LowerExternalSymbol(SDValue Op, 476 SelectionDAG &DAG) { 477 DebugLoc dl = Op.getDebugLoc(); 478 const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol(); 479 SDValue Result = DAG.getTargetExternalSymbol(Sym, getPointerTy()); 480 481 return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result);; 482} 483 484 485MVT MSP430TargetLowering::getSetCCResultType(MVT VT) const { 486 return MVT::i8; 487} 488 489SDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) { 490 assert(Op.getValueType() == MVT::i8 && "SetCC type must be 8-bit integer"); 491 SDValue LHS = Op.getOperand(0); 492 SDValue RHS = Op.getOperand(1); 493 DebugLoc dl = Op.getDebugLoc(); 494 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get(); 495 496 // FIXME: Handle bittests someday 497 assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet"); 498 499 // FIXME: Handle jump negative someday 500 unsigned TargetCC = 0; 501 switch (CC) { 502 default: assert(0 && "Invalid integer condition!"); 503 case ISD::SETEQ: 504 TargetCC = MSP430::COND_E; // aka COND_Z 505 break; 506 case ISD::SETNE: 507 TargetCC = MSP430::COND_NE; // aka COND_NZ 508 break; 509 case ISD::SETULE: 510 std::swap(LHS, RHS); // FALLTHROUGH 511 case ISD::SETUGE: 512 TargetCC = MSP430::COND_HS; // aka COND_C 513 break; 514 case ISD::SETUGT: 515 std::swap(LHS, RHS); // FALLTHROUGH 516 case ISD::SETULT: 517 TargetCC = MSP430::COND_LO; // aka COND_NC 518 break; 519 case ISD::SETLE: 520 std::swap(LHS, RHS); // FALLTHROUGH 521 case ISD::SETGE: 522 TargetCC = MSP430::COND_GE; 523 break; 524 case ISD::SETGT: 525 std::swap(LHS, RHS); // FALLTHROUGH 526 case ISD::SETLT: 527 TargetCC = MSP430::COND_L; 528 break; 529 } 530 531 SDValue Cond = DAG.getNode(MSP430ISD::CMP, dl, MVT::i16, LHS, RHS); 532 return DAG.getNode(MSP430ISD::SETCC, dl, MVT::i8, 533 DAG.getConstant(TargetCC, MVT::i8), Cond); 534} 535 536SDValue MSP430TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) { 537 SDValue Chain = Op.getOperand(0); 538 SDValue Cond = Op.getOperand(1); 539 SDValue Dest = Op.getOperand(2); 540 DebugLoc dl = Op.getDebugLoc(); 541 SDValue CC; 542 543 // Lower condition if not lowered yet 544 if (Cond.getOpcode() == ISD::SETCC) 545 Cond = LowerSETCC(Cond, DAG); 546 547 // If condition flag is set by a MSP430ISD::CMP, then use it as the condition 548 // setting operand in place of the MSP430ISD::SETCC. 549 if (Cond.getOpcode() == MSP430ISD::SETCC) { 550 CC = Cond.getOperand(0); 551 Cond = Cond.getOperand(1); 552 } else 553 assert(0 && "Unimplemented condition!"); 554 555 return DAG.getNode(MSP430ISD::BRCOND, dl, Op.getValueType(), 556 Chain, Dest, CC, Cond); 557} 558 559SDValue MSP430TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) { 560 SDValue Cond = Op.getOperand(0); 561 SDValue TrueV = Op.getOperand(1); 562 SDValue FalseV = Op.getOperand(2); 563 DebugLoc dl = Op.getDebugLoc(); 564 SDValue CC; 565 566 // Lower condition if not lowered yet 567 if (Cond.getOpcode() == ISD::SETCC) 568 Cond = LowerSETCC(Cond, DAG); 569 570 // If condition flag is set by a MSP430ISD::CMP, then use it as the condition 571 // setting operand in place of the MSP430ISD::SETCC. 572 if (Cond.getOpcode() == MSP430ISD::SETCC) { 573 CC = Cond.getOperand(0); 574 Cond = Cond.getOperand(1); 575 TrueV = Cond.getOperand(0); 576 FalseV = Cond.getOperand(1); 577 } else { 578 CC = DAG.getConstant(MSP430::COND_NE, MVT::i16); 579 Cond = DAG.getNode(MSP430ISD::CMP, dl, MVT::i16, 580 Cond, DAG.getConstant(0, MVT::i16)); 581 } 582 583 SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Flag); 584 SmallVector<SDValue, 4> Ops; 585 Ops.push_back(TrueV); 586 Ops.push_back(FalseV); 587 Ops.push_back(CC); 588 Ops.push_back(Cond); 589 590 return DAG.getNode(MSP430ISD::SELECT, dl, VTs, &Ops[0], Ops.size()); 591} 592 593const char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const { 594 switch (Opcode) { 595 default: return NULL; 596 case MSP430ISD::RET_FLAG: return "MSP430ISD::RET_FLAG"; 597 case MSP430ISD::RRA: return "MSP430ISD::RRA"; 598 case MSP430ISD::RLA: return "MSP430ISD::RLA"; 599 case MSP430ISD::RRC: return "MSP430ISD::RRC"; 600 case MSP430ISD::CALL: return "MSP430ISD::CALL"; 601 case MSP430ISD::Wrapper: return "MSP430ISD::Wrapper"; 602 case MSP430ISD::BRCOND: return "MSP430ISD::BRCOND"; 603 case MSP430ISD::CMP: return "MSP430ISD::CMP"; 604 case MSP430ISD::SETCC: return "MSP430ISD::SETCC"; 605 case MSP430ISD::SELECT: return "MSP430ISD::SELECT"; 606 case MSP430ISD::CLRC: return "MSP430ISD::CLRC"; 607 } 608} 609 610//===----------------------------------------------------------------------===// 611// Other Lowering Code 612//===----------------------------------------------------------------------===// 613 614MachineBasicBlock* 615MSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 616 MachineBasicBlock *BB) const { 617 const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); 618 DebugLoc dl = MI->getDebugLoc(); 619 assert((MI->getOpcode() == MSP430::Select16) && 620 "Unexpected instr type to insert"); 621 622 // To "insert" a SELECT instruction, we actually have to insert the diamond 623 // control-flow pattern. The incoming instruction knows the destination vreg 624 // to set, the condition code register to branch on, the true/false values to 625 // select between, and a branch opcode to use. 626 const BasicBlock *LLVM_BB = BB->getBasicBlock(); 627 MachineFunction::iterator I = BB; 628 ++I; 629 630 // thisMBB: 631 // ... 632 // TrueVal = ... 633 // cmpTY ccX, r1, r2 634 // jCC copy1MBB 635 // fallthrough --> copy0MBB 636 MachineBasicBlock *thisMBB = BB; 637 MachineFunction *F = BB->getParent(); 638 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB); 639 MachineBasicBlock *copy1MBB = F->CreateMachineBasicBlock(LLVM_BB); 640 BuildMI(BB, dl, TII.get(MSP430::JCC)) 641 .addMBB(copy1MBB) 642 .addImm(MI->getOperand(3).getImm()); 643 F->insert(I, copy0MBB); 644 F->insert(I, copy1MBB); 645 // Update machine-CFG edges by transferring all successors of the current 646 // block to the new block which will contain the Phi node for the select. 647 copy1MBB->transferSuccessors(BB); 648 // Next, add the true and fallthrough blocks as its successors. 649 BB->addSuccessor(copy0MBB); 650 BB->addSuccessor(copy1MBB); 651 652 // copy0MBB: 653 // %FalseValue = ... 654 // # fallthrough to copy1MBB 655 BB = copy0MBB; 656 657 // Update machine-CFG edges 658 BB->addSuccessor(copy1MBB); 659 660 // copy1MBB: 661 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] 662 // ... 663 BB = copy1MBB; 664 BuildMI(BB, dl, TII.get(MSP430::PHI), 665 MI->getOperand(0).getReg()) 666 .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB) 667 .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB); 668 669 F->DeleteMachineInstr(MI); // The pseudo instruction is gone now. 670 return BB; 671} 672