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