MipsSEISelLowering.cpp revision 915432ca1306d10453c9eb523cbc4b257642f62a
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 28static cl::opt<bool> NoDPLoadStore("mno-ldc1-sdc1", cl::init(false), 29 cl::desc("Expand double precision loads and " 30 "stores to their single precision " 31 "counterparts")); 32 33MipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM) 34 : MipsTargetLowering(TM) { 35 // Set up the register classes 36 37 clearRegisterClasses(); 38 39 addRegisterClass(MVT::i32, &Mips::GPR32RegClass); 40 41 if (HasMips64) 42 addRegisterClass(MVT::i64, &Mips::GPR64RegClass); 43 44 if (Subtarget->hasDSP()) { 45 MVT::SimpleValueType VecTys[2] = {MVT::v2i16, MVT::v4i8}; 46 47 for (unsigned i = 0; i < array_lengthof(VecTys); ++i) { 48 addRegisterClass(VecTys[i], &Mips::DSPRRegClass); 49 50 // Expand all builtin opcodes. 51 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc) 52 setOperationAction(Opc, VecTys[i], Expand); 53 54 setOperationAction(ISD::ADD, VecTys[i], Legal); 55 setOperationAction(ISD::SUB, VecTys[i], Legal); 56 setOperationAction(ISD::LOAD, VecTys[i], Legal); 57 setOperationAction(ISD::STORE, VecTys[i], Legal); 58 setOperationAction(ISD::BITCAST, VecTys[i], Legal); 59 } 60 61 // Expand all truncating stores and extending loads. 62 unsigned FirstVT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE; 63 unsigned LastVT = (unsigned)MVT::LAST_VECTOR_VALUETYPE; 64 65 for (unsigned VT0 = FirstVT; VT0 <= LastVT; ++VT0) { 66 for (unsigned VT1 = FirstVT; VT1 <= LastVT; ++VT1) 67 setTruncStoreAction((MVT::SimpleValueType)VT0, 68 (MVT::SimpleValueType)VT1, Expand); 69 70 setLoadExtAction(ISD::SEXTLOAD, (MVT::SimpleValueType)VT0, Expand); 71 setLoadExtAction(ISD::ZEXTLOAD, (MVT::SimpleValueType)VT0, Expand); 72 setLoadExtAction(ISD::EXTLOAD, (MVT::SimpleValueType)VT0, Expand); 73 } 74 75 setTargetDAGCombine(ISD::SHL); 76 setTargetDAGCombine(ISD::SRA); 77 setTargetDAGCombine(ISD::SRL); 78 setTargetDAGCombine(ISD::SETCC); 79 setTargetDAGCombine(ISD::VSELECT); 80 } 81 82 if (Subtarget->hasDSPR2()) 83 setOperationAction(ISD::MUL, MVT::v2i16, Legal); 84 85 if (Subtarget->hasMSA()) { 86 addMSAIntType(MVT::v16i8, &Mips::MSA128BRegClass); 87 addMSAIntType(MVT::v8i16, &Mips::MSA128HRegClass); 88 addMSAIntType(MVT::v4i32, &Mips::MSA128WRegClass); 89 addMSAIntType(MVT::v2i64, &Mips::MSA128DRegClass); 90 addMSAFloatType(MVT::v8f16, &Mips::MSA128HRegClass); 91 addMSAFloatType(MVT::v4f32, &Mips::MSA128WRegClass); 92 addMSAFloatType(MVT::v2f64, &Mips::MSA128DRegClass); 93 94 setTargetDAGCombine(ISD::XOR); 95 } 96 97 if (!Subtarget->mipsSEUsesSoftFloat()) { 98 addRegisterClass(MVT::f32, &Mips::FGR32RegClass); 99 100 // When dealing with single precision only, use libcalls 101 if (!Subtarget->isSingleFloat()) { 102 if (Subtarget->isFP64bit()) 103 addRegisterClass(MVT::f64, &Mips::FGR64RegClass); 104 else 105 addRegisterClass(MVT::f64, &Mips::AFGR64RegClass); 106 } 107 } 108 109 setOperationAction(ISD::SMUL_LOHI, MVT::i32, Custom); 110 setOperationAction(ISD::UMUL_LOHI, MVT::i32, Custom); 111 setOperationAction(ISD::MULHS, MVT::i32, Custom); 112 setOperationAction(ISD::MULHU, MVT::i32, Custom); 113 114 if (HasMips64) { 115 setOperationAction(ISD::MULHS, MVT::i64, Custom); 116 setOperationAction(ISD::MULHU, MVT::i64, Custom); 117 setOperationAction(ISD::MUL, MVT::i64, Custom); 118 } 119 120 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i64, Custom); 121 setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i64, Custom); 122 123 setOperationAction(ISD::SDIVREM, MVT::i32, Custom); 124 setOperationAction(ISD::UDIVREM, MVT::i32, Custom); 125 setOperationAction(ISD::SDIVREM, MVT::i64, Custom); 126 setOperationAction(ISD::UDIVREM, MVT::i64, Custom); 127 setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom); 128 setOperationAction(ISD::LOAD, MVT::i32, Custom); 129 setOperationAction(ISD::STORE, MVT::i32, Custom); 130 131 setTargetDAGCombine(ISD::ADDE); 132 setTargetDAGCombine(ISD::SUBE); 133 setTargetDAGCombine(ISD::MUL); 134 135 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); 136 setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom); 137 setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom); 138 139 if (NoDPLoadStore) { 140 setOperationAction(ISD::LOAD, MVT::f64, Custom); 141 setOperationAction(ISD::STORE, MVT::f64, Custom); 142 } 143 144 computeRegisterProperties(); 145} 146 147const MipsTargetLowering * 148llvm::createMipsSETargetLowering(MipsTargetMachine &TM) { 149 return new MipsSETargetLowering(TM); 150} 151 152// Enable MSA support for the given integer type and Register class. 153void MipsSETargetLowering:: 154addMSAIntType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) { 155 addRegisterClass(Ty, RC); 156 157 // Expand all builtin opcodes. 158 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc) 159 setOperationAction(Opc, Ty, Expand); 160 161 setOperationAction(ISD::BITCAST, Ty, Legal); 162 setOperationAction(ISD::LOAD, Ty, Legal); 163 setOperationAction(ISD::STORE, Ty, Legal); 164 setOperationAction(ISD::BUILD_VECTOR, Ty, Custom); 165 166 setOperationAction(ISD::ADD, Ty, Legal); 167 setOperationAction(ISD::AND, Ty, Legal); 168 setOperationAction(ISD::CTLZ, Ty, Legal); 169 setOperationAction(ISD::MUL, Ty, Legal); 170 setOperationAction(ISD::OR, Ty, Legal); 171 setOperationAction(ISD::SDIV, Ty, Legal); 172 setOperationAction(ISD::SHL, Ty, Legal); 173 setOperationAction(ISD::SRA, Ty, Legal); 174 setOperationAction(ISD::SRL, Ty, Legal); 175 setOperationAction(ISD::SUB, Ty, Legal); 176 setOperationAction(ISD::UDIV, Ty, Legal); 177 setOperationAction(ISD::XOR, Ty, Legal); 178} 179 180// Enable MSA support for the given floating-point type and Register class. 181void MipsSETargetLowering:: 182addMSAFloatType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) { 183 addRegisterClass(Ty, RC); 184 185 // Expand all builtin opcodes. 186 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc) 187 setOperationAction(Opc, Ty, Expand); 188 189 setOperationAction(ISD::LOAD, Ty, Legal); 190 setOperationAction(ISD::STORE, Ty, Legal); 191 setOperationAction(ISD::BITCAST, Ty, Legal); 192 193 if (Ty != MVT::v8f16) { 194 setOperationAction(ISD::FADD, Ty, Legal); 195 setOperationAction(ISD::FDIV, Ty, Legal); 196 setOperationAction(ISD::FLOG2, Ty, Legal); 197 setOperationAction(ISD::FMUL, Ty, Legal); 198 setOperationAction(ISD::FRINT, Ty, Legal); 199 setOperationAction(ISD::FSQRT, Ty, Legal); 200 setOperationAction(ISD::FSUB, Ty, Legal); 201 } 202} 203 204bool 205MipsSETargetLowering::allowsUnalignedMemoryAccesses(EVT VT, bool *Fast) const { 206 MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy; 207 208 switch (SVT) { 209 case MVT::i64: 210 case MVT::i32: 211 if (Fast) 212 *Fast = true; 213 return true; 214 default: 215 return false; 216 } 217} 218 219SDValue MipsSETargetLowering::LowerOperation(SDValue Op, 220 SelectionDAG &DAG) const { 221 switch(Op.getOpcode()) { 222 case ISD::LOAD: return lowerLOAD(Op, DAG); 223 case ISD::STORE: return lowerSTORE(Op, DAG); 224 case ISD::SMUL_LOHI: return lowerMulDiv(Op, MipsISD::Mult, true, true, DAG); 225 case ISD::UMUL_LOHI: return lowerMulDiv(Op, MipsISD::Multu, true, true, DAG); 226 case ISD::MULHS: return lowerMulDiv(Op, MipsISD::Mult, false, true, DAG); 227 case ISD::MULHU: return lowerMulDiv(Op, MipsISD::Multu, false, true, DAG); 228 case ISD::MUL: return lowerMulDiv(Op, MipsISD::Mult, true, false, DAG); 229 case ISD::SDIVREM: return lowerMulDiv(Op, MipsISD::DivRem, true, true, DAG); 230 case ISD::UDIVREM: return lowerMulDiv(Op, MipsISD::DivRemU, true, true, 231 DAG); 232 case ISD::INTRINSIC_WO_CHAIN: return lowerINTRINSIC_WO_CHAIN(Op, DAG); 233 case ISD::INTRINSIC_W_CHAIN: return lowerINTRINSIC_W_CHAIN(Op, DAG); 234 case ISD::INTRINSIC_VOID: return lowerINTRINSIC_VOID(Op, DAG); 235 case ISD::BUILD_VECTOR: return lowerBUILD_VECTOR(Op, DAG); 236 } 237 238 return MipsTargetLowering::LowerOperation(Op, DAG); 239} 240 241// selectMADD - 242// Transforms a subgraph in CurDAG if the following pattern is found: 243// (addc multLo, Lo0), (adde multHi, Hi0), 244// where, 245// multHi/Lo: product of multiplication 246// Lo0: initial value of Lo register 247// Hi0: initial value of Hi register 248// Return true if pattern matching was successful. 249static bool selectMADD(SDNode *ADDENode, SelectionDAG *CurDAG) { 250 // ADDENode's second operand must be a flag output of an ADDC node in order 251 // for the matching to be successful. 252 SDNode *ADDCNode = ADDENode->getOperand(2).getNode(); 253 254 if (ADDCNode->getOpcode() != ISD::ADDC) 255 return false; 256 257 SDValue MultHi = ADDENode->getOperand(0); 258 SDValue MultLo = ADDCNode->getOperand(0); 259 SDNode *MultNode = MultHi.getNode(); 260 unsigned MultOpc = MultHi.getOpcode(); 261 262 // MultHi and MultLo must be generated by the same node, 263 if (MultLo.getNode() != MultNode) 264 return false; 265 266 // and it must be a multiplication. 267 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI) 268 return false; 269 270 // MultLo amd MultHi must be the first and second output of MultNode 271 // respectively. 272 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0) 273 return false; 274 275 // Transform this to a MADD only if ADDENode and ADDCNode are the only users 276 // of the values of MultNode, in which case MultNode will be removed in later 277 // phases. 278 // If there exist users other than ADDENode or ADDCNode, this function returns 279 // here, which will result in MultNode being mapped to a single MULT 280 // instruction node rather than a pair of MULT and MADD instructions being 281 // produced. 282 if (!MultHi.hasOneUse() || !MultLo.hasOneUse()) 283 return false; 284 285 SDLoc DL(ADDENode); 286 287 // Initialize accumulator. 288 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped, 289 ADDCNode->getOperand(1), 290 ADDENode->getOperand(1)); 291 292 // create MipsMAdd(u) node 293 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MAddu : MipsISD::MAdd; 294 295 SDValue MAdd = CurDAG->getNode(MultOpc, DL, MVT::Untyped, 296 MultNode->getOperand(0),// Factor 0 297 MultNode->getOperand(1),// Factor 1 298 ACCIn); 299 300 // replace uses of adde and addc here 301 if (!SDValue(ADDCNode, 0).use_empty()) { 302 SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32); 303 SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd, 304 LoIdx); 305 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDCNode, 0), LoOut); 306 } 307 if (!SDValue(ADDENode, 0).use_empty()) { 308 SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32); 309 SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd, 310 HiIdx); 311 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDENode, 0), HiOut); 312 } 313 314 return true; 315} 316 317// selectMSUB - 318// Transforms a subgraph in CurDAG if the following pattern is found: 319// (addc Lo0, multLo), (sube Hi0, multHi), 320// where, 321// multHi/Lo: product of multiplication 322// Lo0: initial value of Lo register 323// Hi0: initial value of Hi register 324// Return true if pattern matching was successful. 325static bool selectMSUB(SDNode *SUBENode, SelectionDAG *CurDAG) { 326 // SUBENode's second operand must be a flag output of an SUBC node in order 327 // for the matching to be successful. 328 SDNode *SUBCNode = SUBENode->getOperand(2).getNode(); 329 330 if (SUBCNode->getOpcode() != ISD::SUBC) 331 return false; 332 333 SDValue MultHi = SUBENode->getOperand(1); 334 SDValue MultLo = SUBCNode->getOperand(1); 335 SDNode *MultNode = MultHi.getNode(); 336 unsigned MultOpc = MultHi.getOpcode(); 337 338 // MultHi and MultLo must be generated by the same node, 339 if (MultLo.getNode() != MultNode) 340 return false; 341 342 // and it must be a multiplication. 343 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI) 344 return false; 345 346 // MultLo amd MultHi must be the first and second output of MultNode 347 // respectively. 348 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0) 349 return false; 350 351 // Transform this to a MSUB only if SUBENode and SUBCNode are the only users 352 // of the values of MultNode, in which case MultNode will be removed in later 353 // phases. 354 // If there exist users other than SUBENode or SUBCNode, this function returns 355 // here, which will result in MultNode being mapped to a single MULT 356 // instruction node rather than a pair of MULT and MSUB instructions being 357 // produced. 358 if (!MultHi.hasOneUse() || !MultLo.hasOneUse()) 359 return false; 360 361 SDLoc DL(SUBENode); 362 363 // Initialize accumulator. 364 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped, 365 SUBCNode->getOperand(0), 366 SUBENode->getOperand(0)); 367 368 // create MipsSub(u) node 369 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MSubu : MipsISD::MSub; 370 371 SDValue MSub = CurDAG->getNode(MultOpc, DL, MVT::Glue, 372 MultNode->getOperand(0),// Factor 0 373 MultNode->getOperand(1),// Factor 1 374 ACCIn); 375 376 // replace uses of sube and subc here 377 if (!SDValue(SUBCNode, 0).use_empty()) { 378 SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32); 379 SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub, 380 LoIdx); 381 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBCNode, 0), LoOut); 382 } 383 if (!SDValue(SUBENode, 0).use_empty()) { 384 SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32); 385 SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub, 386 HiIdx); 387 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBENode, 0), HiOut); 388 } 389 390 return true; 391} 392 393static SDValue performADDECombine(SDNode *N, SelectionDAG &DAG, 394 TargetLowering::DAGCombinerInfo &DCI, 395 const MipsSubtarget *Subtarget) { 396 if (DCI.isBeforeLegalize()) 397 return SDValue(); 398 399 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 && 400 selectMADD(N, &DAG)) 401 return SDValue(N, 0); 402 403 return SDValue(); 404} 405 406static SDValue performSUBECombine(SDNode *N, SelectionDAG &DAG, 407 TargetLowering::DAGCombinerInfo &DCI, 408 const MipsSubtarget *Subtarget) { 409 if (DCI.isBeforeLegalize()) 410 return SDValue(); 411 412 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 && 413 selectMSUB(N, &DAG)) 414 return SDValue(N, 0); 415 416 return SDValue(); 417} 418 419static SDValue genConstMult(SDValue X, uint64_t C, SDLoc DL, EVT VT, 420 EVT ShiftTy, SelectionDAG &DAG) { 421 // Clear the upper (64 - VT.sizeInBits) bits. 422 C &= ((uint64_t)-1) >> (64 - VT.getSizeInBits()); 423 424 // Return 0. 425 if (C == 0) 426 return DAG.getConstant(0, VT); 427 428 // Return x. 429 if (C == 1) 430 return X; 431 432 // If c is power of 2, return (shl x, log2(c)). 433 if (isPowerOf2_64(C)) 434 return DAG.getNode(ISD::SHL, DL, VT, X, 435 DAG.getConstant(Log2_64(C), ShiftTy)); 436 437 unsigned Log2Ceil = Log2_64_Ceil(C); 438 uint64_t Floor = 1LL << Log2_64(C); 439 uint64_t Ceil = Log2Ceil == 64 ? 0LL : 1LL << Log2Ceil; 440 441 // If |c - floor_c| <= |c - ceil_c|, 442 // where floor_c = pow(2, floor(log2(c))) and ceil_c = pow(2, ceil(log2(c))), 443 // return (add constMult(x, floor_c), constMult(x, c - floor_c)). 444 if (C - Floor <= Ceil - C) { 445 SDValue Op0 = genConstMult(X, Floor, DL, VT, ShiftTy, DAG); 446 SDValue Op1 = genConstMult(X, C - Floor, DL, VT, ShiftTy, DAG); 447 return DAG.getNode(ISD::ADD, DL, VT, Op0, Op1); 448 } 449 450 // If |c - floor_c| > |c - ceil_c|, 451 // return (sub constMult(x, ceil_c), constMult(x, ceil_c - c)). 452 SDValue Op0 = genConstMult(X, Ceil, DL, VT, ShiftTy, DAG); 453 SDValue Op1 = genConstMult(X, Ceil - C, DL, VT, ShiftTy, DAG); 454 return DAG.getNode(ISD::SUB, DL, VT, Op0, Op1); 455} 456 457static SDValue performMULCombine(SDNode *N, SelectionDAG &DAG, 458 const TargetLowering::DAGCombinerInfo &DCI, 459 const MipsSETargetLowering *TL) { 460 EVT VT = N->getValueType(0); 461 462 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1))) 463 if (!VT.isVector()) 464 return genConstMult(N->getOperand(0), C->getZExtValue(), SDLoc(N), 465 VT, TL->getScalarShiftAmountTy(VT), DAG); 466 467 return SDValue(N, 0); 468} 469 470static SDValue performDSPShiftCombine(unsigned Opc, SDNode *N, EVT Ty, 471 SelectionDAG &DAG, 472 const MipsSubtarget *Subtarget) { 473 // See if this is a vector splat immediate node. 474 APInt SplatValue, SplatUndef; 475 unsigned SplatBitSize; 476 bool HasAnyUndefs; 477 unsigned EltSize = Ty.getVectorElementType().getSizeInBits(); 478 BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N->getOperand(1)); 479 480 if (!BV || 481 !BV->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs, 482 EltSize, !Subtarget->isLittle()) || 483 (SplatBitSize != EltSize) || 484 (SplatValue.getZExtValue() >= EltSize)) 485 return SDValue(); 486 487 return DAG.getNode(Opc, SDLoc(N), Ty, N->getOperand(0), 488 DAG.getConstant(SplatValue.getZExtValue(), MVT::i32)); 489} 490 491static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG, 492 TargetLowering::DAGCombinerInfo &DCI, 493 const MipsSubtarget *Subtarget) { 494 EVT Ty = N->getValueType(0); 495 496 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8)) 497 return SDValue(); 498 499 return performDSPShiftCombine(MipsISD::SHLL_DSP, N, Ty, DAG, Subtarget); 500} 501 502static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG, 503 TargetLowering::DAGCombinerInfo &DCI, 504 const MipsSubtarget *Subtarget) { 505 EVT Ty = N->getValueType(0); 506 507 if ((Ty != MVT::v2i16) && ((Ty != MVT::v4i8) || !Subtarget->hasDSPR2())) 508 return SDValue(); 509 510 return performDSPShiftCombine(MipsISD::SHRA_DSP, N, Ty, DAG, Subtarget); 511} 512 513 514static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG, 515 TargetLowering::DAGCombinerInfo &DCI, 516 const MipsSubtarget *Subtarget) { 517 EVT Ty = N->getValueType(0); 518 519 if (((Ty != MVT::v2i16) || !Subtarget->hasDSPR2()) && (Ty != MVT::v4i8)) 520 return SDValue(); 521 522 return performDSPShiftCombine(MipsISD::SHRL_DSP, N, Ty, DAG, Subtarget); 523} 524 525static bool isLegalDSPCondCode(EVT Ty, ISD::CondCode CC) { 526 bool IsV216 = (Ty == MVT::v2i16); 527 528 switch (CC) { 529 case ISD::SETEQ: 530 case ISD::SETNE: return true; 531 case ISD::SETLT: 532 case ISD::SETLE: 533 case ISD::SETGT: 534 case ISD::SETGE: return IsV216; 535 case ISD::SETULT: 536 case ISD::SETULE: 537 case ISD::SETUGT: 538 case ISD::SETUGE: return !IsV216; 539 default: return false; 540 } 541} 542 543static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG) { 544 EVT Ty = N->getValueType(0); 545 546 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8)) 547 return SDValue(); 548 549 if (!isLegalDSPCondCode(Ty, cast<CondCodeSDNode>(N->getOperand(2))->get())) 550 return SDValue(); 551 552 return DAG.getNode(MipsISD::SETCC_DSP, SDLoc(N), Ty, N->getOperand(0), 553 N->getOperand(1), N->getOperand(2)); 554} 555 556static SDValue performVSELECTCombine(SDNode *N, SelectionDAG &DAG) { 557 EVT Ty = N->getValueType(0); 558 559 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8)) 560 return SDValue(); 561 562 SDValue SetCC = N->getOperand(0); 563 564 if (SetCC.getOpcode() != MipsISD::SETCC_DSP) 565 return SDValue(); 566 567 return DAG.getNode(MipsISD::SELECT_CC_DSP, SDLoc(N), Ty, 568 SetCC.getOperand(0), SetCC.getOperand(1), N->getOperand(1), 569 N->getOperand(2), SetCC.getOperand(2)); 570} 571 572static SDValue performXORCombine(SDNode *N, SelectionDAG &DAG, 573 const MipsSubtarget *Subtarget) { 574 EVT Ty = N->getValueType(0); 575 576 if (Subtarget->hasMSA() && Ty.is128BitVector() && Ty.isInteger()) { 577 // Try the following combines: 578 // (xor (or $a, $b), (build_vector allones)) 579 // (xor (or $a, $b), (bitcast (build_vector allones))) 580 SDValue Op0 = N->getOperand(0); 581 SDValue Op1 = N->getOperand(1); 582 SDValue NotOp; 583 ConstantSDNode *Const; 584 585 if (ISD::isBuildVectorAllOnes(Op0.getNode())) 586 NotOp = Op1; 587 else if (ISD::isBuildVectorAllOnes(Op1.getNode())) 588 NotOp = Op0; 589 else if ((Op0->getOpcode() == MipsISD::VSPLAT || 590 Op0->getOpcode() == MipsISD::VSPLATD) && 591 (Const = dyn_cast<ConstantSDNode>(Op0->getOperand(0))) && 592 Const->isAllOnesValue()) 593 NotOp = Op1; 594 else if ((Op1->getOpcode() == MipsISD::VSPLAT || 595 Op1->getOpcode() == MipsISD::VSPLATD) && 596 (Const = dyn_cast<ConstantSDNode>(Op1->getOperand(0))) && 597 Const->isAllOnesValue()) 598 NotOp = Op0; 599 else 600 return SDValue(); 601 602 if (NotOp->getOpcode() == ISD::OR) 603 return DAG.getNode(MipsISD::VNOR, SDLoc(N), Ty, NotOp->getOperand(0), 604 NotOp->getOperand(1)); 605 } 606 607 return SDValue(); 608} 609 610SDValue 611MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const { 612 SelectionDAG &DAG = DCI.DAG; 613 SDValue Val; 614 615 switch (N->getOpcode()) { 616 case ISD::ADDE: 617 return performADDECombine(N, DAG, DCI, Subtarget); 618 case ISD::SUBE: 619 return performSUBECombine(N, DAG, DCI, Subtarget); 620 case ISD::MUL: 621 return performMULCombine(N, DAG, DCI, this); 622 case ISD::SHL: 623 return performSHLCombine(N, DAG, DCI, Subtarget); 624 case ISD::SRA: 625 return performSRACombine(N, DAG, DCI, Subtarget); 626 case ISD::SRL: 627 return performSRLCombine(N, DAG, DCI, Subtarget); 628 case ISD::VSELECT: 629 return performVSELECTCombine(N, DAG); 630 case ISD::XOR: 631 Val = performXORCombine(N, DAG, Subtarget); 632 break; 633 case ISD::SETCC: 634 Val = performSETCCCombine(N, DAG); 635 break; 636 } 637 638 if (Val.getNode()) 639 return Val; 640 641 return MipsTargetLowering::PerformDAGCombine(N, DCI); 642} 643 644MachineBasicBlock * 645MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 646 MachineBasicBlock *BB) const { 647 switch (MI->getOpcode()) { 648 default: 649 return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB); 650 case Mips::BPOSGE32_PSEUDO: 651 return emitBPOSGE32(MI, BB); 652 case Mips::SNZ_B_PSEUDO: 653 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_B); 654 case Mips::SNZ_H_PSEUDO: 655 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_H); 656 case Mips::SNZ_W_PSEUDO: 657 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_W); 658 case Mips::SNZ_D_PSEUDO: 659 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_D); 660 case Mips::SNZ_V_PSEUDO: 661 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_V); 662 case Mips::SZ_B_PSEUDO: 663 return emitMSACBranchPseudo(MI, BB, Mips::BZ_B); 664 case Mips::SZ_H_PSEUDO: 665 return emitMSACBranchPseudo(MI, BB, Mips::BZ_H); 666 case Mips::SZ_W_PSEUDO: 667 return emitMSACBranchPseudo(MI, BB, Mips::BZ_W); 668 case Mips::SZ_D_PSEUDO: 669 return emitMSACBranchPseudo(MI, BB, Mips::BZ_D); 670 case Mips::SZ_V_PSEUDO: 671 return emitMSACBranchPseudo(MI, BB, Mips::BZ_V); 672 } 673} 674 675bool MipsSETargetLowering:: 676isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo, 677 unsigned NextStackOffset, 678 const MipsFunctionInfo& FI) const { 679 if (!EnableMipsTailCalls) 680 return false; 681 682 // Return false if either the callee or caller has a byval argument. 683 if (MipsCCInfo.hasByValArg() || FI.hasByvalArg()) 684 return false; 685 686 // Return true if the callee's argument area is no larger than the 687 // caller's. 688 return NextStackOffset <= FI.getIncomingArgSize(); 689} 690 691void MipsSETargetLowering:: 692getOpndList(SmallVectorImpl<SDValue> &Ops, 693 std::deque< std::pair<unsigned, SDValue> > &RegsToPass, 694 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage, 695 CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const { 696 // T9 should contain the address of the callee function if 697 // -reloction-model=pic or it is an indirect call. 698 if (IsPICCall || !GlobalOrExternal) { 699 unsigned T9Reg = IsN64 ? Mips::T9_64 : Mips::T9; 700 RegsToPass.push_front(std::make_pair(T9Reg, Callee)); 701 } else 702 Ops.push_back(Callee); 703 704 MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal, 705 InternalLinkage, CLI, Callee, Chain); 706} 707 708SDValue MipsSETargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const { 709 LoadSDNode &Nd = *cast<LoadSDNode>(Op); 710 711 if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore) 712 return MipsTargetLowering::lowerLOAD(Op, DAG); 713 714 // Replace a double precision load with two i32 loads and a buildpair64. 715 SDLoc DL(Op); 716 SDValue Ptr = Nd.getBasePtr(), Chain = Nd.getChain(); 717 EVT PtrVT = Ptr.getValueType(); 718 719 // i32 load from lower address. 720 SDValue Lo = DAG.getLoad(MVT::i32, DL, Chain, Ptr, 721 MachinePointerInfo(), Nd.isVolatile(), 722 Nd.isNonTemporal(), Nd.isInvariant(), 723 Nd.getAlignment()); 724 725 // i32 load from higher address. 726 Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Ptr, DAG.getConstant(4, PtrVT)); 727 SDValue Hi = DAG.getLoad(MVT::i32, DL, Lo.getValue(1), Ptr, 728 MachinePointerInfo(), Nd.isVolatile(), 729 Nd.isNonTemporal(), Nd.isInvariant(), 730 std::min(Nd.getAlignment(), 4U)); 731 732 if (!Subtarget->isLittle()) 733 std::swap(Lo, Hi); 734 735 SDValue BP = DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, Lo, Hi); 736 SDValue Ops[2] = {BP, Hi.getValue(1)}; 737 return DAG.getMergeValues(Ops, 2, DL); 738} 739 740SDValue MipsSETargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const { 741 StoreSDNode &Nd = *cast<StoreSDNode>(Op); 742 743 if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore) 744 return MipsTargetLowering::lowerSTORE(Op, DAG); 745 746 // Replace a double precision store with two extractelement64s and i32 stores. 747 SDLoc DL(Op); 748 SDValue Val = Nd.getValue(), Ptr = Nd.getBasePtr(), Chain = Nd.getChain(); 749 EVT PtrVT = Ptr.getValueType(); 750 SDValue Lo = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, 751 Val, DAG.getConstant(0, MVT::i32)); 752 SDValue Hi = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, 753 Val, DAG.getConstant(1, MVT::i32)); 754 755 if (!Subtarget->isLittle()) 756 std::swap(Lo, Hi); 757 758 // i32 store to lower address. 759 Chain = DAG.getStore(Chain, DL, Lo, Ptr, MachinePointerInfo(), 760 Nd.isVolatile(), Nd.isNonTemporal(), Nd.getAlignment(), 761 Nd.getTBAAInfo()); 762 763 // i32 store to higher address. 764 Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Ptr, DAG.getConstant(4, PtrVT)); 765 return DAG.getStore(Chain, DL, Hi, Ptr, MachinePointerInfo(), 766 Nd.isVolatile(), Nd.isNonTemporal(), 767 std::min(Nd.getAlignment(), 4U), Nd.getTBAAInfo()); 768} 769 770SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc, 771 bool HasLo, bool HasHi, 772 SelectionDAG &DAG) const { 773 EVT Ty = Op.getOperand(0).getValueType(); 774 SDLoc DL(Op); 775 SDValue Mult = DAG.getNode(NewOpc, DL, MVT::Untyped, 776 Op.getOperand(0), Op.getOperand(1)); 777 SDValue Lo, Hi; 778 779 if (HasLo) 780 Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult, 781 DAG.getConstant(Mips::sub_lo, MVT::i32)); 782 if (HasHi) 783 Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult, 784 DAG.getConstant(Mips::sub_hi, MVT::i32)); 785 786 if (!HasLo || !HasHi) 787 return HasLo ? Lo : Hi; 788 789 SDValue Vals[] = { Lo, Hi }; 790 return DAG.getMergeValues(Vals, 2, DL); 791} 792 793 794static SDValue initAccumulator(SDValue In, SDLoc DL, SelectionDAG &DAG) { 795 SDValue InLo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In, 796 DAG.getConstant(0, MVT::i32)); 797 SDValue InHi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In, 798 DAG.getConstant(1, MVT::i32)); 799 return DAG.getNode(MipsISD::InsertLOHI, DL, MVT::Untyped, InLo, InHi); 800} 801 802static SDValue extractLOHI(SDValue Op, SDLoc DL, SelectionDAG &DAG) { 803 SDValue Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op, 804 DAG.getConstant(Mips::sub_lo, MVT::i32)); 805 SDValue Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op, 806 DAG.getConstant(Mips::sub_hi, MVT::i32)); 807 return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi); 808} 809 810// This function expands mips intrinsic nodes which have 64-bit input operands 811// or output values. 812// 813// out64 = intrinsic-node in64 814// => 815// lo = copy (extract-element (in64, 0)) 816// hi = copy (extract-element (in64, 1)) 817// mips-specific-node 818// v0 = copy lo 819// v1 = copy hi 820// out64 = merge-values (v0, v1) 821// 822static SDValue lowerDSPIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) { 823 SDLoc DL(Op); 824 bool HasChainIn = Op->getOperand(0).getValueType() == MVT::Other; 825 SmallVector<SDValue, 3> Ops; 826 unsigned OpNo = 0; 827 828 // See if Op has a chain input. 829 if (HasChainIn) 830 Ops.push_back(Op->getOperand(OpNo++)); 831 832 // The next operand is the intrinsic opcode. 833 assert(Op->getOperand(OpNo).getOpcode() == ISD::TargetConstant); 834 835 // See if the next operand has type i64. 836 SDValue Opnd = Op->getOperand(++OpNo), In64; 837 838 if (Opnd.getValueType() == MVT::i64) 839 In64 = initAccumulator(Opnd, DL, DAG); 840 else 841 Ops.push_back(Opnd); 842 843 // Push the remaining operands. 844 for (++OpNo ; OpNo < Op->getNumOperands(); ++OpNo) 845 Ops.push_back(Op->getOperand(OpNo)); 846 847 // Add In64 to the end of the list. 848 if (In64.getNode()) 849 Ops.push_back(In64); 850 851 // Scan output. 852 SmallVector<EVT, 2> ResTys; 853 854 for (SDNode::value_iterator I = Op->value_begin(), E = Op->value_end(); 855 I != E; ++I) 856 ResTys.push_back((*I == MVT::i64) ? MVT::Untyped : *I); 857 858 // Create node. 859 SDValue Val = DAG.getNode(Opc, DL, ResTys, &Ops[0], Ops.size()); 860 SDValue Out = (ResTys[0] == MVT::Untyped) ? extractLOHI(Val, DL, DAG) : Val; 861 862 if (!HasChainIn) 863 return Out; 864 865 assert(Val->getValueType(1) == MVT::Other); 866 SDValue Vals[] = { Out, SDValue(Val.getNode(), 1) }; 867 return DAG.getMergeValues(Vals, 2, DL); 868} 869 870static SDValue lowerMSABinaryIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) { 871 SDLoc DL(Op); 872 SDValue LHS = Op->getOperand(1); 873 SDValue RHS = Op->getOperand(2); 874 EVT ResTy = Op->getValueType(0); 875 876 SDValue Result = DAG.getNode(Opc, DL, ResTy, LHS, RHS); 877 878 return Result; 879} 880 881static SDValue lowerMSABranchIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) { 882 SDLoc DL(Op); 883 SDValue Value = Op->getOperand(1); 884 EVT ResTy = Op->getValueType(0); 885 886 SDValue Result = DAG.getNode(Opc, DL, ResTy, Value); 887 888 return Result; 889} 890 891static SDValue lowerMSAUnaryIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) { 892 SDLoc DL(Op); 893 SDValue Value = Op->getOperand(1); 894 EVT ResTy = Op->getValueType(0); 895 896 SDValue Result = DAG.getNode(Opc, DL, ResTy, Value); 897 898 return Result; 899} 900 901SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op, 902 SelectionDAG &DAG) const { 903 switch (cast<ConstantSDNode>(Op->getOperand(0))->getZExtValue()) { 904 default: 905 return SDValue(); 906 case Intrinsic::mips_shilo: 907 return lowerDSPIntr(Op, DAG, MipsISD::SHILO); 908 case Intrinsic::mips_dpau_h_qbl: 909 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBL); 910 case Intrinsic::mips_dpau_h_qbr: 911 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBR); 912 case Intrinsic::mips_dpsu_h_qbl: 913 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBL); 914 case Intrinsic::mips_dpsu_h_qbr: 915 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBR); 916 case Intrinsic::mips_dpa_w_ph: 917 return lowerDSPIntr(Op, DAG, MipsISD::DPA_W_PH); 918 case Intrinsic::mips_dps_w_ph: 919 return lowerDSPIntr(Op, DAG, MipsISD::DPS_W_PH); 920 case Intrinsic::mips_dpax_w_ph: 921 return lowerDSPIntr(Op, DAG, MipsISD::DPAX_W_PH); 922 case Intrinsic::mips_dpsx_w_ph: 923 return lowerDSPIntr(Op, DAG, MipsISD::DPSX_W_PH); 924 case Intrinsic::mips_mulsa_w_ph: 925 return lowerDSPIntr(Op, DAG, MipsISD::MULSA_W_PH); 926 case Intrinsic::mips_mult: 927 return lowerDSPIntr(Op, DAG, MipsISD::Mult); 928 case Intrinsic::mips_multu: 929 return lowerDSPIntr(Op, DAG, MipsISD::Multu); 930 case Intrinsic::mips_madd: 931 return lowerDSPIntr(Op, DAG, MipsISD::MAdd); 932 case Intrinsic::mips_maddu: 933 return lowerDSPIntr(Op, DAG, MipsISD::MAddu); 934 case Intrinsic::mips_msub: 935 return lowerDSPIntr(Op, DAG, MipsISD::MSub); 936 case Intrinsic::mips_msubu: 937 return lowerDSPIntr(Op, DAG, MipsISD::MSubu); 938 case Intrinsic::mips_addv_b: 939 case Intrinsic::mips_addv_h: 940 case Intrinsic::mips_addv_w: 941 case Intrinsic::mips_addv_d: 942 return lowerMSABinaryIntr(Op, DAG, ISD::ADD); 943 case Intrinsic::mips_and_v: 944 return lowerMSABinaryIntr(Op, DAG, ISD::AND); 945 case Intrinsic::mips_bnz_b: 946 case Intrinsic::mips_bnz_h: 947 case Intrinsic::mips_bnz_w: 948 case Intrinsic::mips_bnz_d: 949 return lowerMSABranchIntr(Op, DAG, MipsISD::VALL_NONZERO); 950 case Intrinsic::mips_bnz_v: 951 return lowerMSABranchIntr(Op, DAG, MipsISD::VANY_NONZERO); 952 case Intrinsic::mips_bz_b: 953 case Intrinsic::mips_bz_h: 954 case Intrinsic::mips_bz_w: 955 case Intrinsic::mips_bz_d: 956 return lowerMSABranchIntr(Op, DAG, MipsISD::VALL_ZERO); 957 case Intrinsic::mips_bz_v: 958 return lowerMSABranchIntr(Op, DAG, MipsISD::VANY_ZERO); 959 case Intrinsic::mips_div_s_b: 960 case Intrinsic::mips_div_s_h: 961 case Intrinsic::mips_div_s_w: 962 case Intrinsic::mips_div_s_d: 963 return lowerMSABinaryIntr(Op, DAG, ISD::SDIV); 964 case Intrinsic::mips_div_u_b: 965 case Intrinsic::mips_div_u_h: 966 case Intrinsic::mips_div_u_w: 967 case Intrinsic::mips_div_u_d: 968 return lowerMSABinaryIntr(Op, DAG, ISD::UDIV); 969 case Intrinsic::mips_fadd_w: 970 case Intrinsic::mips_fadd_d: 971 return lowerMSABinaryIntr(Op, DAG, ISD::FADD); 972 case Intrinsic::mips_fdiv_w: 973 case Intrinsic::mips_fdiv_d: 974 return lowerMSABinaryIntr(Op, DAG, ISD::FDIV); 975 case Intrinsic::mips_fill_b: 976 case Intrinsic::mips_fill_h: 977 case Intrinsic::mips_fill_w: 978 return lowerMSAUnaryIntr(Op, DAG, MipsISD::VSPLAT); 979 case Intrinsic::mips_flog2_w: 980 case Intrinsic::mips_flog2_d: 981 return lowerMSAUnaryIntr(Op, DAG, ISD::FLOG2); 982 case Intrinsic::mips_fmul_w: 983 case Intrinsic::mips_fmul_d: 984 return lowerMSABinaryIntr(Op, DAG, ISD::FMUL); 985 case Intrinsic::mips_frint_w: 986 case Intrinsic::mips_frint_d: 987 return lowerMSAUnaryIntr(Op, DAG, ISD::FRINT); 988 case Intrinsic::mips_fsqrt_w: 989 case Intrinsic::mips_fsqrt_d: 990 return lowerMSAUnaryIntr(Op, DAG, ISD::FSQRT); 991 case Intrinsic::mips_fsub_w: 992 case Intrinsic::mips_fsub_d: 993 return lowerMSABinaryIntr(Op, DAG, ISD::FSUB); 994 case Intrinsic::mips_ldi_b: 995 case Intrinsic::mips_ldi_h: 996 case Intrinsic::mips_ldi_w: 997 case Intrinsic::mips_ldi_d: 998 return lowerMSAUnaryIntr(Op, DAG, MipsISD::VSPLAT); 999 case Intrinsic::mips_mulv_b: 1000 case Intrinsic::mips_mulv_h: 1001 case Intrinsic::mips_mulv_w: 1002 case Intrinsic::mips_mulv_d: 1003 return lowerMSABinaryIntr(Op, DAG, ISD::MUL); 1004 case Intrinsic::mips_nlzc_b: 1005 case Intrinsic::mips_nlzc_h: 1006 case Intrinsic::mips_nlzc_w: 1007 case Intrinsic::mips_nlzc_d: 1008 return lowerMSAUnaryIntr(Op, DAG, ISD::CTLZ); 1009 case Intrinsic::mips_nor_v: { 1010 SDValue Res = lowerMSABinaryIntr(Op, DAG, ISD::OR); 1011 return DAG.getNOT(SDLoc(Op), Res, Res->getValueType(0)); 1012 } 1013 case Intrinsic::mips_or_v: 1014 return lowerMSABinaryIntr(Op, DAG, ISD::OR); 1015 case Intrinsic::mips_sll_b: 1016 case Intrinsic::mips_sll_h: 1017 case Intrinsic::mips_sll_w: 1018 case Intrinsic::mips_sll_d: 1019 return lowerMSABinaryIntr(Op, DAG, ISD::SHL); 1020 case Intrinsic::mips_sra_b: 1021 case Intrinsic::mips_sra_h: 1022 case Intrinsic::mips_sra_w: 1023 case Intrinsic::mips_sra_d: 1024 return lowerMSABinaryIntr(Op, DAG, ISD::SRA); 1025 case Intrinsic::mips_srl_b: 1026 case Intrinsic::mips_srl_h: 1027 case Intrinsic::mips_srl_w: 1028 case Intrinsic::mips_srl_d: 1029 return lowerMSABinaryIntr(Op, DAG, ISD::SRL); 1030 case Intrinsic::mips_subv_b: 1031 case Intrinsic::mips_subv_h: 1032 case Intrinsic::mips_subv_w: 1033 case Intrinsic::mips_subv_d: 1034 return lowerMSABinaryIntr(Op, DAG, ISD::SUB); 1035 case Intrinsic::mips_xor_v: 1036 return lowerMSABinaryIntr(Op, DAG, ISD::XOR); 1037 } 1038} 1039 1040static SDValue lowerMSALoadIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr) { 1041 SDLoc DL(Op); 1042 SDValue ChainIn = Op->getOperand(0); 1043 SDValue Address = Op->getOperand(2); 1044 SDValue Offset = Op->getOperand(3); 1045 EVT ResTy = Op->getValueType(0); 1046 EVT PtrTy = Address->getValueType(0); 1047 1048 Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset); 1049 1050 return DAG.getLoad(ResTy, DL, ChainIn, Address, MachinePointerInfo(), false, 1051 false, false, 16); 1052} 1053 1054SDValue MipsSETargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op, 1055 SelectionDAG &DAG) const { 1056 unsigned Intr = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue(); 1057 switch (Intr) { 1058 default: 1059 return SDValue(); 1060 case Intrinsic::mips_extp: 1061 return lowerDSPIntr(Op, DAG, MipsISD::EXTP); 1062 case Intrinsic::mips_extpdp: 1063 return lowerDSPIntr(Op, DAG, MipsISD::EXTPDP); 1064 case Intrinsic::mips_extr_w: 1065 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_W); 1066 case Intrinsic::mips_extr_r_w: 1067 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_R_W); 1068 case Intrinsic::mips_extr_rs_w: 1069 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_RS_W); 1070 case Intrinsic::mips_extr_s_h: 1071 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_S_H); 1072 case Intrinsic::mips_mthlip: 1073 return lowerDSPIntr(Op, DAG, MipsISD::MTHLIP); 1074 case Intrinsic::mips_mulsaq_s_w_ph: 1075 return lowerDSPIntr(Op, DAG, MipsISD::MULSAQ_S_W_PH); 1076 case Intrinsic::mips_maq_s_w_phl: 1077 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHL); 1078 case Intrinsic::mips_maq_s_w_phr: 1079 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHR); 1080 case Intrinsic::mips_maq_sa_w_phl: 1081 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHL); 1082 case Intrinsic::mips_maq_sa_w_phr: 1083 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHR); 1084 case Intrinsic::mips_dpaq_s_w_ph: 1085 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_S_W_PH); 1086 case Intrinsic::mips_dpsq_s_w_ph: 1087 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_S_W_PH); 1088 case Intrinsic::mips_dpaq_sa_l_w: 1089 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_SA_L_W); 1090 case Intrinsic::mips_dpsq_sa_l_w: 1091 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_SA_L_W); 1092 case Intrinsic::mips_dpaqx_s_w_ph: 1093 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_S_W_PH); 1094 case Intrinsic::mips_dpaqx_sa_w_ph: 1095 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_SA_W_PH); 1096 case Intrinsic::mips_dpsqx_s_w_ph: 1097 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_S_W_PH); 1098 case Intrinsic::mips_dpsqx_sa_w_ph: 1099 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_SA_W_PH); 1100 case Intrinsic::mips_ld_b: 1101 case Intrinsic::mips_ld_h: 1102 case Intrinsic::mips_ld_w: 1103 case Intrinsic::mips_ld_d: 1104 case Intrinsic::mips_ldx_b: 1105 case Intrinsic::mips_ldx_h: 1106 case Intrinsic::mips_ldx_w: 1107 case Intrinsic::mips_ldx_d: 1108 return lowerMSALoadIntr(Op, DAG, Intr); 1109 } 1110} 1111 1112static SDValue lowerMSAStoreIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr) { 1113 SDLoc DL(Op); 1114 SDValue ChainIn = Op->getOperand(0); 1115 SDValue Value = Op->getOperand(2); 1116 SDValue Address = Op->getOperand(3); 1117 SDValue Offset = Op->getOperand(4); 1118 EVT PtrTy = Address->getValueType(0); 1119 1120 Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset); 1121 1122 return DAG.getStore(ChainIn, DL, Value, Address, MachinePointerInfo(), false, 1123 false, 16); 1124} 1125 1126SDValue MipsSETargetLowering::lowerINTRINSIC_VOID(SDValue Op, 1127 SelectionDAG &DAG) const { 1128 unsigned Intr = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue(); 1129 switch (Intr) { 1130 default: 1131 return SDValue(); 1132 case Intrinsic::mips_st_b: 1133 case Intrinsic::mips_st_h: 1134 case Intrinsic::mips_st_w: 1135 case Intrinsic::mips_st_d: 1136 case Intrinsic::mips_stx_b: 1137 case Intrinsic::mips_stx_h: 1138 case Intrinsic::mips_stx_w: 1139 case Intrinsic::mips_stx_d: 1140 return lowerMSAStoreIntr(Op, DAG, Intr); 1141 } 1142} 1143 1144/// \brief Check if the given BuildVectorSDNode is a splat. 1145/// This method currently relies on DAG nodes being reused when equivalent, 1146/// so it's possible for this to return false even when isConstantSplat returns 1147/// true. 1148static bool isSplatVector(const BuildVectorSDNode *N) { 1149 unsigned int nOps = N->getNumOperands(); 1150 assert(nOps > 1 && "isSplat has 0 or 1 sized build vector"); 1151 1152 SDValue Operand0 = N->getOperand(0); 1153 1154 for (unsigned int i = 1; i < nOps; ++i) { 1155 if (N->getOperand(i) != Operand0) 1156 return false; 1157 } 1158 1159 return true; 1160} 1161 1162// Lowers ISD::BUILD_VECTOR into appropriate SelectionDAG nodes for the 1163// backend. 1164// 1165// Lowers according to the following rules: 1166// - Vectors of 128-bits may be legal subject to the other rules. Other sizes 1167// are not legal. 1168// - Non-constant splats are legal and are lowered to MipsISD::VSPLAT. 1169// - Constant splats with an element size of 32-bits or less are legal and are 1170// lowered to MipsISD::VSPLAT. 1171// - Constant splats with an element size of 64-bits but whose value would fit 1172// within a 10 bit immediate are legal and are lowered to MipsISD::VSPLATD. 1173// - All other ISD::BUILD_VECTORS are not legal 1174SDValue MipsSETargetLowering::lowerBUILD_VECTOR(SDValue Op, 1175 SelectionDAG &DAG) const { 1176 BuildVectorSDNode *Node = cast<BuildVectorSDNode>(Op); 1177 EVT ResTy = Op->getValueType(0); 1178 SDLoc DL(Op); 1179 APInt SplatValue, SplatUndef; 1180 unsigned SplatBitSize; 1181 bool HasAnyUndefs; 1182 1183 if (!Subtarget->hasMSA() || !ResTy.is128BitVector()) 1184 return SDValue(); 1185 1186 if (Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, 1187 HasAnyUndefs, 8, 1188 !Subtarget->isLittle())) { 1189 SDValue Result; 1190 EVT TmpVecTy; 1191 EVT ConstTy = MVT::i32; 1192 unsigned SplatOp = MipsISD::VSPLAT; 1193 1194 switch (SplatBitSize) { 1195 default: 1196 return SDValue(); 1197 case 64: 1198 TmpVecTy = MVT::v2i64; 1199 1200 // i64 is an illegal type on Mips32, but if it the constant fits into a 1201 // signed 10-bit value then we can still handle it using VSPLATD and an 1202 // i32 constant 1203 if (HasMips64) 1204 ConstTy = MVT::i64; 1205 else if (isInt<10>(SplatValue.getSExtValue())) { 1206 SplatValue = SplatValue.trunc(32); 1207 SplatOp = MipsISD::VSPLATD; 1208 } else 1209 return SDValue(); 1210 break; 1211 case 32: 1212 TmpVecTy = MVT::v4i32; 1213 break; 1214 case 16: 1215 TmpVecTy = MVT::v8i16; 1216 SplatValue = SplatValue.sext(32); 1217 break; 1218 case 8: 1219 TmpVecTy = MVT::v16i8; 1220 SplatValue = SplatValue.sext(32); 1221 break; 1222 } 1223 1224 Result = DAG.getNode(SplatOp, DL, TmpVecTy, 1225 DAG.getConstant(SplatValue, ConstTy)); 1226 if (ResTy != Result.getValueType()) 1227 Result = DAG.getNode(ISD::BITCAST, DL, ResTy, Result); 1228 1229 return Result; 1230 } 1231 else if (isSplatVector(Node)) 1232 return DAG.getNode(MipsISD::VSPLAT, DL, ResTy, Op->getOperand(0)); 1233 1234 return SDValue(); 1235} 1236 1237MachineBasicBlock * MipsSETargetLowering:: 1238emitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{ 1239 // $bb: 1240 // bposge32_pseudo $vr0 1241 // => 1242 // $bb: 1243 // bposge32 $tbb 1244 // $fbb: 1245 // li $vr2, 0 1246 // b $sink 1247 // $tbb: 1248 // li $vr1, 1 1249 // $sink: 1250 // $vr0 = phi($vr2, $fbb, $vr1, $tbb) 1251 1252 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); 1253 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); 1254 const TargetRegisterClass *RC = &Mips::GPR32RegClass; 1255 DebugLoc DL = MI->getDebugLoc(); 1256 const BasicBlock *LLVM_BB = BB->getBasicBlock(); 1257 MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB)); 1258 MachineFunction *F = BB->getParent(); 1259 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB); 1260 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB); 1261 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB); 1262 F->insert(It, FBB); 1263 F->insert(It, TBB); 1264 F->insert(It, Sink); 1265 1266 // Transfer the remainder of BB and its successor edges to Sink. 1267 Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)), 1268 BB->end()); 1269 Sink->transferSuccessorsAndUpdatePHIs(BB); 1270 1271 // Add successors. 1272 BB->addSuccessor(FBB); 1273 BB->addSuccessor(TBB); 1274 FBB->addSuccessor(Sink); 1275 TBB->addSuccessor(Sink); 1276 1277 // Insert the real bposge32 instruction to $BB. 1278 BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB); 1279 1280 // Fill $FBB. 1281 unsigned VR2 = RegInfo.createVirtualRegister(RC); 1282 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), VR2) 1283 .addReg(Mips::ZERO).addImm(0); 1284 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink); 1285 1286 // Fill $TBB. 1287 unsigned VR1 = RegInfo.createVirtualRegister(RC); 1288 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1) 1289 .addReg(Mips::ZERO).addImm(1); 1290 1291 // Insert phi function to $Sink. 1292 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI), 1293 MI->getOperand(0).getReg()) 1294 .addReg(VR2).addMBB(FBB).addReg(VR1).addMBB(TBB); 1295 1296 MI->eraseFromParent(); // The pseudo instruction is gone now. 1297 return Sink; 1298} 1299 1300MachineBasicBlock * MipsSETargetLowering:: 1301emitMSACBranchPseudo(MachineInstr *MI, MachineBasicBlock *BB, 1302 unsigned BranchOp) const{ 1303 // $bb: 1304 // vany_nonzero $rd, $ws 1305 // => 1306 // $bb: 1307 // bnz.b $ws, $tbb 1308 // b $fbb 1309 // $fbb: 1310 // li $rd1, 0 1311 // b $sink 1312 // $tbb: 1313 // li $rd2, 1 1314 // $sink: 1315 // $rd = phi($rd1, $fbb, $rd2, $tbb) 1316 1317 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); 1318 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); 1319 const TargetRegisterClass *RC = &Mips::GPR32RegClass; 1320 DebugLoc DL = MI->getDebugLoc(); 1321 const BasicBlock *LLVM_BB = BB->getBasicBlock(); 1322 MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB)); 1323 MachineFunction *F = BB->getParent(); 1324 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB); 1325 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB); 1326 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB); 1327 F->insert(It, FBB); 1328 F->insert(It, TBB); 1329 F->insert(It, Sink); 1330 1331 // Transfer the remainder of BB and its successor edges to Sink. 1332 Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)), 1333 BB->end()); 1334 Sink->transferSuccessorsAndUpdatePHIs(BB); 1335 1336 // Add successors. 1337 BB->addSuccessor(FBB); 1338 BB->addSuccessor(TBB); 1339 FBB->addSuccessor(Sink); 1340 TBB->addSuccessor(Sink); 1341 1342 // Insert the real bnz.b instruction to $BB. 1343 BuildMI(BB, DL, TII->get(BranchOp)) 1344 .addReg(MI->getOperand(1).getReg()) 1345 .addMBB(TBB); 1346 1347 // Fill $FBB. 1348 unsigned RD1 = RegInfo.createVirtualRegister(RC); 1349 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), RD1) 1350 .addReg(Mips::ZERO).addImm(0); 1351 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink); 1352 1353 // Fill $TBB. 1354 unsigned RD2 = RegInfo.createVirtualRegister(RC); 1355 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), RD2) 1356 .addReg(Mips::ZERO).addImm(1); 1357 1358 // Insert phi function to $Sink. 1359 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI), 1360 MI->getOperand(0).getReg()) 1361 .addReg(RD1).addMBB(FBB).addReg(RD2).addMBB(TBB); 1362 1363 MI->eraseFromParent(); // The pseudo instruction is gone now. 1364 return Sink; 1365} 1366