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