MipsSEISelLowering.cpp revision d597263b9442923bacc24f26a8510fb69f992864
1//===-- MipsSEISelLowering.cpp - MipsSE DAG Lowering Interface --*- C++ -*-===// 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// Subclass of MipsTargetLowering specialized for mips32/64. 11// 12//===----------------------------------------------------------------------===// 13#include "MipsSEISelLowering.h" 14#include "MipsRegisterInfo.h" 15#include "MipsTargetMachine.h" 16#include "llvm/CodeGen/MachineInstrBuilder.h" 17#include "llvm/CodeGen/MachineRegisterInfo.h" 18#include "llvm/IR/Intrinsics.h" 19#include "llvm/Support/CommandLine.h" 20#include "llvm/Target/TargetInstrInfo.h" 21 22using namespace llvm; 23 24static cl::opt<bool> 25EnableMipsTailCalls("enable-mips-tail-calls", cl::Hidden, 26 cl::desc("MIPS: Enable tail calls."), cl::init(false)); 27 28MipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM) 29 : MipsTargetLowering(TM) { 30 // Set up the register classes 31 32 clearRegisterClasses(); 33 34 addRegisterClass(MVT::i32, &Mips::CPURegsRegClass); 35 36 if (HasMips64) 37 addRegisterClass(MVT::i64, &Mips::CPU64RegsRegClass); 38 39 if (Subtarget->hasDSP()) { 40 MVT::SimpleValueType VecTys[2] = {MVT::v2i16, MVT::v4i8}; 41 42 for (unsigned i = 0; i < array_lengthof(VecTys); ++i) { 43 addRegisterClass(VecTys[i], &Mips::DSPRegsRegClass); 44 45 // Expand all builtin opcodes. 46 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc) 47 setOperationAction(Opc, VecTys[i], Expand); 48 49 setOperationAction(ISD::ADD, VecTys[i], Legal); 50 setOperationAction(ISD::SUB, VecTys[i], Legal); 51 setOperationAction(ISD::LOAD, VecTys[i], Legal); 52 setOperationAction(ISD::STORE, VecTys[i], Legal); 53 setOperationAction(ISD::BITCAST, VecTys[i], Legal); 54 } 55 56 setTargetDAGCombine(ISD::SHL); 57 setTargetDAGCombine(ISD::SRA); 58 setTargetDAGCombine(ISD::SRL); 59 } 60 61 if (Subtarget->hasDSPR2()) 62 setOperationAction(ISD::MUL, MVT::v2i16, Legal); 63 64 if (!TM.Options.UseSoftFloat) { 65 addRegisterClass(MVT::f32, &Mips::FGR32RegClass); 66 67 // When dealing with single precision only, use libcalls 68 if (!Subtarget->isSingleFloat()) { 69 if (HasMips64) 70 addRegisterClass(MVT::f64, &Mips::FGR64RegClass); 71 else 72 addRegisterClass(MVT::f64, &Mips::AFGR64RegClass); 73 } 74 } 75 76 setOperationAction(ISD::SMUL_LOHI, MVT::i32, Custom); 77 setOperationAction(ISD::UMUL_LOHI, MVT::i32, Custom); 78 setOperationAction(ISD::MULHS, MVT::i32, Custom); 79 setOperationAction(ISD::MULHU, MVT::i32, Custom); 80 81 if (HasMips64) { 82 setOperationAction(ISD::MULHS, MVT::i64, Custom); 83 setOperationAction(ISD::MULHU, MVT::i64, Custom); 84 setOperationAction(ISD::MUL, MVT::i64, Custom); 85 } 86 87 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i64, Custom); 88 setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i64, Custom); 89 90 setOperationAction(ISD::SDIVREM, MVT::i32, Custom); 91 setOperationAction(ISD::UDIVREM, MVT::i32, Custom); 92 setOperationAction(ISD::SDIVREM, MVT::i64, Custom); 93 setOperationAction(ISD::UDIVREM, MVT::i64, Custom); 94 setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom); 95 setOperationAction(ISD::LOAD, MVT::i32, Custom); 96 setOperationAction(ISD::STORE, MVT::i32, Custom); 97 98 setTargetDAGCombine(ISD::ADDE); 99 setTargetDAGCombine(ISD::SUBE); 100 101 computeRegisterProperties(); 102} 103 104const MipsTargetLowering * 105llvm::createMipsSETargetLowering(MipsTargetMachine &TM) { 106 return new MipsSETargetLowering(TM); 107} 108 109 110bool 111MipsSETargetLowering::allowsUnalignedMemoryAccesses(EVT VT, bool *Fast) const { 112 MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy; 113 114 switch (SVT) { 115 case MVT::i64: 116 case MVT::i32: 117 if (Fast) 118 *Fast = true; 119 return true; 120 default: 121 return false; 122 } 123} 124 125SDValue MipsSETargetLowering::LowerOperation(SDValue Op, 126 SelectionDAG &DAG) const { 127 switch(Op.getOpcode()) { 128 case ISD::SMUL_LOHI: return lowerMulDiv(Op, MipsISD::Mult, true, true, DAG); 129 case ISD::UMUL_LOHI: return lowerMulDiv(Op, MipsISD::Multu, true, true, DAG); 130 case ISD::MULHS: return lowerMulDiv(Op, MipsISD::Mult, false, true, DAG); 131 case ISD::MULHU: return lowerMulDiv(Op, MipsISD::Multu, false, true, DAG); 132 case ISD::MUL: return lowerMulDiv(Op, MipsISD::Mult, true, false, DAG); 133 case ISD::SDIVREM: return lowerMulDiv(Op, MipsISD::DivRem, true, true, DAG); 134 case ISD::UDIVREM: return lowerMulDiv(Op, MipsISD::DivRemU, true, true, DAG); 135 case ISD::INTRINSIC_WO_CHAIN: return lowerINTRINSIC_WO_CHAIN(Op, DAG); 136 case ISD::INTRINSIC_W_CHAIN: return lowerINTRINSIC_W_CHAIN(Op, DAG); 137 } 138 139 return MipsTargetLowering::LowerOperation(Op, DAG); 140} 141 142// selectMADD - 143// Transforms a subgraph in CurDAG if the following pattern is found: 144// (addc multLo, Lo0), (adde multHi, Hi0), 145// where, 146// multHi/Lo: product of multiplication 147// Lo0: initial value of Lo register 148// Hi0: initial value of Hi register 149// Return true if pattern matching was successful. 150static bool selectMADD(SDNode *ADDENode, SelectionDAG *CurDAG) { 151 // ADDENode's second operand must be a flag output of an ADDC node in order 152 // for the matching to be successful. 153 SDNode *ADDCNode = ADDENode->getOperand(2).getNode(); 154 155 if (ADDCNode->getOpcode() != ISD::ADDC) 156 return false; 157 158 SDValue MultHi = ADDENode->getOperand(0); 159 SDValue MultLo = ADDCNode->getOperand(0); 160 SDNode *MultNode = MultHi.getNode(); 161 unsigned MultOpc = MultHi.getOpcode(); 162 163 // MultHi and MultLo must be generated by the same node, 164 if (MultLo.getNode() != MultNode) 165 return false; 166 167 // and it must be a multiplication. 168 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI) 169 return false; 170 171 // MultLo amd MultHi must be the first and second output of MultNode 172 // respectively. 173 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0) 174 return false; 175 176 // Transform this to a MADD only if ADDENode and ADDCNode are the only users 177 // of the values of MultNode, in which case MultNode will be removed in later 178 // phases. 179 // If there exist users other than ADDENode or ADDCNode, this function returns 180 // here, which will result in MultNode being mapped to a single MULT 181 // instruction node rather than a pair of MULT and MADD instructions being 182 // produced. 183 if (!MultHi.hasOneUse() || !MultLo.hasOneUse()) 184 return false; 185 186 DebugLoc DL = ADDENode->getDebugLoc(); 187 188 // Initialize accumulator. 189 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped, 190 ADDCNode->getOperand(1), 191 ADDENode->getOperand(1)); 192 193 // create MipsMAdd(u) node 194 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MAddu : MipsISD::MAdd; 195 196 SDValue MAdd = CurDAG->getNode(MultOpc, DL, MVT::Untyped, 197 MultNode->getOperand(0),// Factor 0 198 MultNode->getOperand(1),// Factor 1 199 ACCIn); 200 201 // replace uses of adde and addc here 202 if (!SDValue(ADDCNode, 0).use_empty()) { 203 SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32); 204 SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd, 205 LoIdx); 206 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDCNode, 0), LoOut); 207 } 208 if (!SDValue(ADDENode, 0).use_empty()) { 209 SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32); 210 SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd, 211 HiIdx); 212 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDENode, 0), HiOut); 213 } 214 215 return true; 216} 217 218// selectMSUB - 219// Transforms a subgraph in CurDAG if the following pattern is found: 220// (addc Lo0, multLo), (sube Hi0, multHi), 221// where, 222// multHi/Lo: product of multiplication 223// Lo0: initial value of Lo register 224// Hi0: initial value of Hi register 225// Return true if pattern matching was successful. 226static bool selectMSUB(SDNode *SUBENode, SelectionDAG *CurDAG) { 227 // SUBENode's second operand must be a flag output of an SUBC node in order 228 // for the matching to be successful. 229 SDNode *SUBCNode = SUBENode->getOperand(2).getNode(); 230 231 if (SUBCNode->getOpcode() != ISD::SUBC) 232 return false; 233 234 SDValue MultHi = SUBENode->getOperand(1); 235 SDValue MultLo = SUBCNode->getOperand(1); 236 SDNode *MultNode = MultHi.getNode(); 237 unsigned MultOpc = MultHi.getOpcode(); 238 239 // MultHi and MultLo must be generated by the same node, 240 if (MultLo.getNode() != MultNode) 241 return false; 242 243 // and it must be a multiplication. 244 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI) 245 return false; 246 247 // MultLo amd MultHi must be the first and second output of MultNode 248 // respectively. 249 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0) 250 return false; 251 252 // Transform this to a MSUB only if SUBENode and SUBCNode are the only users 253 // of the values of MultNode, in which case MultNode will be removed in later 254 // phases. 255 // If there exist users other than SUBENode or SUBCNode, this function returns 256 // here, which will result in MultNode being mapped to a single MULT 257 // instruction node rather than a pair of MULT and MSUB instructions being 258 // produced. 259 if (!MultHi.hasOneUse() || !MultLo.hasOneUse()) 260 return false; 261 262 DebugLoc DL = SUBENode->getDebugLoc(); 263 264 // Initialize accumulator. 265 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped, 266 SUBCNode->getOperand(0), 267 SUBENode->getOperand(0)); 268 269 // create MipsSub(u) node 270 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MSubu : MipsISD::MSub; 271 272 SDValue MSub = CurDAG->getNode(MultOpc, DL, MVT::Glue, 273 MultNode->getOperand(0),// Factor 0 274 MultNode->getOperand(1),// Factor 1 275 ACCIn); 276 277 // replace uses of sube and subc here 278 if (!SDValue(SUBCNode, 0).use_empty()) { 279 SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32); 280 SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub, 281 LoIdx); 282 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBCNode, 0), LoOut); 283 } 284 if (!SDValue(SUBENode, 0).use_empty()) { 285 SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32); 286 SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub, 287 HiIdx); 288 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBENode, 0), HiOut); 289 } 290 291 return true; 292} 293 294static SDValue performADDECombine(SDNode *N, SelectionDAG &DAG, 295 TargetLowering::DAGCombinerInfo &DCI, 296 const MipsSubtarget *Subtarget) { 297 if (DCI.isBeforeLegalize()) 298 return SDValue(); 299 300 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 && 301 selectMADD(N, &DAG)) 302 return SDValue(N, 0); 303 304 return SDValue(); 305} 306 307static SDValue performSUBECombine(SDNode *N, SelectionDAG &DAG, 308 TargetLowering::DAGCombinerInfo &DCI, 309 const MipsSubtarget *Subtarget) { 310 if (DCI.isBeforeLegalize()) 311 return SDValue(); 312 313 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 && 314 selectMSUB(N, &DAG)) 315 return SDValue(N, 0); 316 317 return SDValue(); 318} 319 320static SDValue performDSPShiftCombine(unsigned Opc, SDNode *N, EVT Ty, 321 SelectionDAG &DAG, 322 const MipsSubtarget *Subtarget) { 323 // See if this is a vector splat immediate node. 324 APInt SplatValue, SplatUndef; 325 unsigned SplatBitSize; 326 bool HasAnyUndefs; 327 unsigned EltSize = Ty.getVectorElementType().getSizeInBits(); 328 BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N->getOperand(1)); 329 330 if (!BV || 331 !BV->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs, EltSize, 332 !Subtarget->isLittle()) || 333 (SplatBitSize != EltSize) || 334 !isUIntN(Log2_32(EltSize), SplatValue.getZExtValue())) 335 return SDValue(); 336 337 return DAG.getNode(Opc, N->getDebugLoc(), Ty, N->getOperand(0), 338 DAG.getConstant(SplatValue.getZExtValue(), MVT::i32)); 339} 340 341static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG, 342 TargetLowering::DAGCombinerInfo &DCI, 343 const MipsSubtarget *Subtarget) { 344 EVT Ty = N->getValueType(0); 345 346 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8)) 347 return SDValue(); 348 349 return performDSPShiftCombine(MipsISD::SHLL_DSP, N, Ty, DAG, Subtarget); 350} 351 352static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG, 353 TargetLowering::DAGCombinerInfo &DCI, 354 const MipsSubtarget *Subtarget) { 355 EVT Ty = N->getValueType(0); 356 357 if ((Ty != MVT::v2i16) && ((Ty != MVT::v4i8) || !Subtarget->hasDSPR2())) 358 return SDValue(); 359 360 return performDSPShiftCombine(MipsISD::SHRA_DSP, N, Ty, DAG, Subtarget); 361} 362 363 364static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG, 365 TargetLowering::DAGCombinerInfo &DCI, 366 const MipsSubtarget *Subtarget) { 367 EVT Ty = N->getValueType(0); 368 369 if (((Ty != MVT::v2i16) || !Subtarget->hasDSPR2()) && (Ty != MVT::v4i8)) 370 return SDValue(); 371 372 return performDSPShiftCombine(MipsISD::SHRL_DSP, N, Ty, DAG, Subtarget); 373} 374 375SDValue 376MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const { 377 SelectionDAG &DAG = DCI.DAG; 378 379 switch (N->getOpcode()) { 380 case ISD::ADDE: 381 return performADDECombine(N, DAG, DCI, Subtarget); 382 case ISD::SUBE: 383 return performSUBECombine(N, DAG, DCI, Subtarget); 384 case ISD::SHL: 385 return performSHLCombine(N, DAG, DCI, Subtarget); 386 case ISD::SRA: 387 return performSRACombine(N, DAG, DCI, Subtarget); 388 case ISD::SRL: 389 return performSRLCombine(N, DAG, DCI, Subtarget); 390 default: 391 return MipsTargetLowering::PerformDAGCombine(N, DCI); 392 } 393} 394 395MachineBasicBlock * 396MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 397 MachineBasicBlock *BB) const { 398 switch (MI->getOpcode()) { 399 default: 400 return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB); 401 case Mips::BPOSGE32_PSEUDO: 402 return emitBPOSGE32(MI, BB); 403 } 404} 405 406bool MipsSETargetLowering:: 407isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo, 408 unsigned NextStackOffset, 409 const MipsFunctionInfo& FI) const { 410 if (!EnableMipsTailCalls) 411 return false; 412 413 // Return false if either the callee or caller has a byval argument. 414 if (MipsCCInfo.hasByValArg() || FI.hasByvalArg()) 415 return false; 416 417 // Return true if the callee's argument area is no larger than the 418 // caller's. 419 return NextStackOffset <= FI.getIncomingArgSize(); 420} 421 422void MipsSETargetLowering:: 423getOpndList(SmallVectorImpl<SDValue> &Ops, 424 std::deque< std::pair<unsigned, SDValue> > &RegsToPass, 425 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage, 426 CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const { 427 // T9 should contain the address of the callee function if 428 // -reloction-model=pic or it is an indirect call. 429 if (IsPICCall || !GlobalOrExternal) { 430 unsigned T9Reg = IsN64 ? Mips::T9_64 : Mips::T9; 431 RegsToPass.push_front(std::make_pair(T9Reg, Callee)); 432 } else 433 Ops.push_back(Callee); 434 435 MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal, 436 InternalLinkage, CLI, Callee, Chain); 437} 438 439SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc, 440 bool HasLo, bool HasHi, 441 SelectionDAG &DAG) const { 442 EVT Ty = Op.getOperand(0).getValueType(); 443 DebugLoc DL = Op.getDebugLoc(); 444 SDValue Mult = DAG.getNode(NewOpc, DL, MVT::Untyped, 445 Op.getOperand(0), Op.getOperand(1)); 446 SDValue Lo, Hi; 447 448 if (HasLo) 449 Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult, 450 DAG.getConstant(Mips::sub_lo, MVT::i32)); 451 if (HasHi) 452 Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult, 453 DAG.getConstant(Mips::sub_hi, MVT::i32)); 454 455 if (!HasLo || !HasHi) 456 return HasLo ? Lo : Hi; 457 458 SDValue Vals[] = { Lo, Hi }; 459 return DAG.getMergeValues(Vals, 2, DL); 460} 461 462 463static SDValue initAccumulator(SDValue In, DebugLoc DL, SelectionDAG &DAG) { 464 SDValue InLo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In, 465 DAG.getConstant(0, MVT::i32)); 466 SDValue InHi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In, 467 DAG.getConstant(1, MVT::i32)); 468 return DAG.getNode(MipsISD::InsertLOHI, DL, MVT::Untyped, InLo, InHi); 469} 470 471static SDValue extractLOHI(SDValue Op, DebugLoc DL, SelectionDAG &DAG) { 472 SDValue Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op, 473 DAG.getConstant(Mips::sub_lo, MVT::i32)); 474 SDValue Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op, 475 DAG.getConstant(Mips::sub_hi, MVT::i32)); 476 return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi); 477} 478 479// This function expands mips intrinsic nodes which have 64-bit input operands 480// or output values. 481// 482// out64 = intrinsic-node in64 483// => 484// lo = copy (extract-element (in64, 0)) 485// hi = copy (extract-element (in64, 1)) 486// mips-specific-node 487// v0 = copy lo 488// v1 = copy hi 489// out64 = merge-values (v0, v1) 490// 491static SDValue lowerDSPIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) { 492 DebugLoc DL = Op.getDebugLoc(); 493 bool HasChainIn = Op->getOperand(0).getValueType() == MVT::Other; 494 SmallVector<SDValue, 3> Ops; 495 unsigned OpNo = 0; 496 497 // See if Op has a chain input. 498 if (HasChainIn) 499 Ops.push_back(Op->getOperand(OpNo++)); 500 501 // The next operand is the intrinsic opcode. 502 assert(Op->getOperand(OpNo).getOpcode() == ISD::TargetConstant); 503 504 // See if the next operand has type i64. 505 SDValue Opnd = Op->getOperand(++OpNo), In64; 506 507 if (Opnd.getValueType() == MVT::i64) 508 In64 = initAccumulator(Opnd, DL, DAG); 509 else 510 Ops.push_back(Opnd); 511 512 // Push the remaining operands. 513 for (++OpNo ; OpNo < Op->getNumOperands(); ++OpNo) 514 Ops.push_back(Op->getOperand(OpNo)); 515 516 // Add In64 to the end of the list. 517 if (In64.getNode()) 518 Ops.push_back(In64); 519 520 // Scan output. 521 SmallVector<EVT, 2> ResTys; 522 523 for (SDNode::value_iterator I = Op->value_begin(), E = Op->value_end(); 524 I != E; ++I) 525 ResTys.push_back((*I == MVT::i64) ? MVT::Untyped : *I); 526 527 // Create node. 528 SDValue Val = DAG.getNode(Opc, DL, ResTys, &Ops[0], Ops.size()); 529 SDValue Out = (ResTys[0] == MVT::Untyped) ? extractLOHI(Val, DL, DAG) : Val; 530 531 if (!HasChainIn) 532 return Out; 533 534 assert(Val->getValueType(1) == MVT::Other); 535 SDValue Vals[] = { Out, SDValue(Val.getNode(), 1) }; 536 return DAG.getMergeValues(Vals, 2, DL); 537} 538 539SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op, 540 SelectionDAG &DAG) const { 541 switch (cast<ConstantSDNode>(Op->getOperand(0))->getZExtValue()) { 542 default: 543 return SDValue(); 544 case Intrinsic::mips_shilo: 545 return lowerDSPIntr(Op, DAG, MipsISD::SHILO); 546 case Intrinsic::mips_dpau_h_qbl: 547 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBL); 548 case Intrinsic::mips_dpau_h_qbr: 549 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBR); 550 case Intrinsic::mips_dpsu_h_qbl: 551 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBL); 552 case Intrinsic::mips_dpsu_h_qbr: 553 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBR); 554 case Intrinsic::mips_dpa_w_ph: 555 return lowerDSPIntr(Op, DAG, MipsISD::DPA_W_PH); 556 case Intrinsic::mips_dps_w_ph: 557 return lowerDSPIntr(Op, DAG, MipsISD::DPS_W_PH); 558 case Intrinsic::mips_dpax_w_ph: 559 return lowerDSPIntr(Op, DAG, MipsISD::DPAX_W_PH); 560 case Intrinsic::mips_dpsx_w_ph: 561 return lowerDSPIntr(Op, DAG, MipsISD::DPSX_W_PH); 562 case Intrinsic::mips_mulsa_w_ph: 563 return lowerDSPIntr(Op, DAG, MipsISD::MULSA_W_PH); 564 case Intrinsic::mips_mult: 565 return lowerDSPIntr(Op, DAG, MipsISD::Mult); 566 case Intrinsic::mips_multu: 567 return lowerDSPIntr(Op, DAG, MipsISD::Multu); 568 case Intrinsic::mips_madd: 569 return lowerDSPIntr(Op, DAG, MipsISD::MAdd); 570 case Intrinsic::mips_maddu: 571 return lowerDSPIntr(Op, DAG, MipsISD::MAddu); 572 case Intrinsic::mips_msub: 573 return lowerDSPIntr(Op, DAG, MipsISD::MSub); 574 case Intrinsic::mips_msubu: 575 return lowerDSPIntr(Op, DAG, MipsISD::MSubu); 576 } 577} 578 579SDValue MipsSETargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op, 580 SelectionDAG &DAG) const { 581 switch (cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue()) { 582 default: 583 return SDValue(); 584 case Intrinsic::mips_extp: 585 return lowerDSPIntr(Op, DAG, MipsISD::EXTP); 586 case Intrinsic::mips_extpdp: 587 return lowerDSPIntr(Op, DAG, MipsISD::EXTPDP); 588 case Intrinsic::mips_extr_w: 589 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_W); 590 case Intrinsic::mips_extr_r_w: 591 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_R_W); 592 case Intrinsic::mips_extr_rs_w: 593 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_RS_W); 594 case Intrinsic::mips_extr_s_h: 595 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_S_H); 596 case Intrinsic::mips_mthlip: 597 return lowerDSPIntr(Op, DAG, MipsISD::MTHLIP); 598 case Intrinsic::mips_mulsaq_s_w_ph: 599 return lowerDSPIntr(Op, DAG, MipsISD::MULSAQ_S_W_PH); 600 case Intrinsic::mips_maq_s_w_phl: 601 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHL); 602 case Intrinsic::mips_maq_s_w_phr: 603 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHR); 604 case Intrinsic::mips_maq_sa_w_phl: 605 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHL); 606 case Intrinsic::mips_maq_sa_w_phr: 607 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHR); 608 case Intrinsic::mips_dpaq_s_w_ph: 609 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_S_W_PH); 610 case Intrinsic::mips_dpsq_s_w_ph: 611 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_S_W_PH); 612 case Intrinsic::mips_dpaq_sa_l_w: 613 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_SA_L_W); 614 case Intrinsic::mips_dpsq_sa_l_w: 615 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_SA_L_W); 616 case Intrinsic::mips_dpaqx_s_w_ph: 617 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_S_W_PH); 618 case Intrinsic::mips_dpaqx_sa_w_ph: 619 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_SA_W_PH); 620 case Intrinsic::mips_dpsqx_s_w_ph: 621 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_S_W_PH); 622 case Intrinsic::mips_dpsqx_sa_w_ph: 623 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_SA_W_PH); 624 } 625} 626 627MachineBasicBlock * MipsSETargetLowering:: 628emitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{ 629 // $bb: 630 // bposge32_pseudo $vr0 631 // => 632 // $bb: 633 // bposge32 $tbb 634 // $fbb: 635 // li $vr2, 0 636 // b $sink 637 // $tbb: 638 // li $vr1, 1 639 // $sink: 640 // $vr0 = phi($vr2, $fbb, $vr1, $tbb) 641 642 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); 643 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); 644 const TargetRegisterClass *RC = &Mips::CPURegsRegClass; 645 DebugLoc DL = MI->getDebugLoc(); 646 const BasicBlock *LLVM_BB = BB->getBasicBlock(); 647 MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB)); 648 MachineFunction *F = BB->getParent(); 649 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB); 650 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB); 651 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB); 652 F->insert(It, FBB); 653 F->insert(It, TBB); 654 F->insert(It, Sink); 655 656 // Transfer the remainder of BB and its successor edges to Sink. 657 Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)), 658 BB->end()); 659 Sink->transferSuccessorsAndUpdatePHIs(BB); 660 661 // Add successors. 662 BB->addSuccessor(FBB); 663 BB->addSuccessor(TBB); 664 FBB->addSuccessor(Sink); 665 TBB->addSuccessor(Sink); 666 667 // Insert the real bposge32 instruction to $BB. 668 BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB); 669 670 // Fill $FBB. 671 unsigned VR2 = RegInfo.createVirtualRegister(RC); 672 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), VR2) 673 .addReg(Mips::ZERO).addImm(0); 674 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink); 675 676 // Fill $TBB. 677 unsigned VR1 = RegInfo.createVirtualRegister(RC); 678 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1) 679 .addReg(Mips::ZERO).addImm(1); 680 681 // Insert phi function to $Sink. 682 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI), 683 MI->getOperand(0).getReg()) 684 .addReg(VR2).addMBB(FBB).addReg(VR1).addMBB(TBB); 685 686 MI->eraseFromParent(); // The pseudo instruction is gone now. 687 return Sink; 688} 689