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