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