MipsSEISelLowering.cpp revision ad16ddeb8e07a259d17ef203c9f443f816f6ae7b
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::AND); 95 setTargetDAGCombine(ISD::SRA); 96 setTargetDAGCombine(ISD::VSELECT); 97 setTargetDAGCombine(ISD::XOR); 98 } 99 100 if (!Subtarget->mipsSEUsesSoftFloat()) { 101 addRegisterClass(MVT::f32, &Mips::FGR32RegClass); 102 103 // When dealing with single precision only, use libcalls 104 if (!Subtarget->isSingleFloat()) { 105 if (Subtarget->isFP64bit()) 106 addRegisterClass(MVT::f64, &Mips::FGR64RegClass); 107 else 108 addRegisterClass(MVT::f64, &Mips::AFGR64RegClass); 109 } 110 } 111 112 setOperationAction(ISD::SMUL_LOHI, MVT::i32, Custom); 113 setOperationAction(ISD::UMUL_LOHI, MVT::i32, Custom); 114 setOperationAction(ISD::MULHS, MVT::i32, Custom); 115 setOperationAction(ISD::MULHU, MVT::i32, Custom); 116 117 if (HasMips64) { 118 setOperationAction(ISD::MULHS, MVT::i64, Custom); 119 setOperationAction(ISD::MULHU, MVT::i64, Custom); 120 setOperationAction(ISD::MUL, MVT::i64, Custom); 121 } 122 123 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i64, Custom); 124 setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i64, Custom); 125 126 setOperationAction(ISD::SDIVREM, MVT::i32, Custom); 127 setOperationAction(ISD::UDIVREM, MVT::i32, Custom); 128 setOperationAction(ISD::SDIVREM, MVT::i64, Custom); 129 setOperationAction(ISD::UDIVREM, MVT::i64, Custom); 130 setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom); 131 setOperationAction(ISD::LOAD, MVT::i32, Custom); 132 setOperationAction(ISD::STORE, MVT::i32, Custom); 133 134 setTargetDAGCombine(ISD::ADDE); 135 setTargetDAGCombine(ISD::SUBE); 136 setTargetDAGCombine(ISD::MUL); 137 138 setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); 139 setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom); 140 setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom); 141 142 if (NoDPLoadStore) { 143 setOperationAction(ISD::LOAD, MVT::f64, Custom); 144 setOperationAction(ISD::STORE, MVT::f64, Custom); 145 } 146 147 computeRegisterProperties(); 148} 149 150const MipsTargetLowering * 151llvm::createMipsSETargetLowering(MipsTargetMachine &TM) { 152 return new MipsSETargetLowering(TM); 153} 154 155// Enable MSA support for the given integer type and Register class. 156void MipsSETargetLowering:: 157addMSAIntType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) { 158 addRegisterClass(Ty, RC); 159 160 // Expand all builtin opcodes. 161 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc) 162 setOperationAction(Opc, Ty, Expand); 163 164 setOperationAction(ISD::BITCAST, Ty, Legal); 165 setOperationAction(ISD::LOAD, Ty, Legal); 166 setOperationAction(ISD::STORE, Ty, Legal); 167 setOperationAction(ISD::EXTRACT_VECTOR_ELT, Ty, Custom); 168 setOperationAction(ISD::INSERT_VECTOR_ELT, Ty, Legal); 169 setOperationAction(ISD::BUILD_VECTOR, Ty, Custom); 170 171 setOperationAction(ISD::ADD, Ty, Legal); 172 setOperationAction(ISD::AND, Ty, Legal); 173 setOperationAction(ISD::CTLZ, Ty, Legal); 174 setOperationAction(ISD::CTPOP, Ty, Legal); 175 setOperationAction(ISD::MUL, Ty, Legal); 176 setOperationAction(ISD::OR, Ty, Legal); 177 setOperationAction(ISD::SDIV, Ty, Legal); 178 setOperationAction(ISD::SHL, Ty, Legal); 179 setOperationAction(ISD::SRA, Ty, Legal); 180 setOperationAction(ISD::SRL, Ty, Legal); 181 setOperationAction(ISD::SUB, Ty, Legal); 182 setOperationAction(ISD::UDIV, Ty, Legal); 183 setOperationAction(ISD::VSELECT, Ty, Legal); 184 setOperationAction(ISD::XOR, Ty, Legal); 185 186 setOperationAction(ISD::SETCC, Ty, Legal); 187 setCondCodeAction(ISD::SETNE, Ty, Expand); 188 setCondCodeAction(ISD::SETGE, Ty, Expand); 189 setCondCodeAction(ISD::SETGT, Ty, Expand); 190 setCondCodeAction(ISD::SETUGE, Ty, Expand); 191 setCondCodeAction(ISD::SETUGT, Ty, Expand); 192} 193 194// Enable MSA support for the given floating-point type and Register class. 195void MipsSETargetLowering:: 196addMSAFloatType(MVT::SimpleValueType Ty, const TargetRegisterClass *RC) { 197 addRegisterClass(Ty, RC); 198 199 // Expand all builtin opcodes. 200 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc) 201 setOperationAction(Opc, Ty, Expand); 202 203 setOperationAction(ISD::LOAD, Ty, Legal); 204 setOperationAction(ISD::STORE, Ty, Legal); 205 setOperationAction(ISD::BITCAST, Ty, Legal); 206 setOperationAction(ISD::EXTRACT_VECTOR_ELT, Ty, Legal); 207 208 if (Ty != MVT::v8f16) { 209 setOperationAction(ISD::FABS, Ty, Legal); 210 setOperationAction(ISD::FADD, Ty, Legal); 211 setOperationAction(ISD::FDIV, Ty, Legal); 212 setOperationAction(ISD::FLOG2, Ty, Legal); 213 setOperationAction(ISD::FMUL, Ty, Legal); 214 setOperationAction(ISD::FRINT, Ty, Legal); 215 setOperationAction(ISD::FSQRT, Ty, Legal); 216 setOperationAction(ISD::FSUB, Ty, Legal); 217 setOperationAction(ISD::VSELECT, Ty, Legal); 218 219 setOperationAction(ISD::SETCC, Ty, Legal); 220 setCondCodeAction(ISD::SETOGE, Ty, Expand); 221 setCondCodeAction(ISD::SETOGT, Ty, Expand); 222 setCondCodeAction(ISD::SETUGE, Ty, Expand); 223 setCondCodeAction(ISD::SETUGT, Ty, Expand); 224 setCondCodeAction(ISD::SETGE, Ty, Expand); 225 setCondCodeAction(ISD::SETGT, Ty, Expand); 226 } 227} 228 229bool 230MipsSETargetLowering::allowsUnalignedMemoryAccesses(EVT VT, bool *Fast) const { 231 MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy; 232 233 switch (SVT) { 234 case MVT::i64: 235 case MVT::i32: 236 if (Fast) 237 *Fast = true; 238 return true; 239 default: 240 return false; 241 } 242} 243 244SDValue MipsSETargetLowering::LowerOperation(SDValue Op, 245 SelectionDAG &DAG) const { 246 switch(Op.getOpcode()) { 247 case ISD::LOAD: return lowerLOAD(Op, DAG); 248 case ISD::STORE: return lowerSTORE(Op, DAG); 249 case ISD::SMUL_LOHI: return lowerMulDiv(Op, MipsISD::Mult, true, true, DAG); 250 case ISD::UMUL_LOHI: return lowerMulDiv(Op, MipsISD::Multu, true, true, DAG); 251 case ISD::MULHS: return lowerMulDiv(Op, MipsISD::Mult, false, true, DAG); 252 case ISD::MULHU: return lowerMulDiv(Op, MipsISD::Multu, false, true, DAG); 253 case ISD::MUL: return lowerMulDiv(Op, MipsISD::Mult, true, false, DAG); 254 case ISD::SDIVREM: return lowerMulDiv(Op, MipsISD::DivRem, true, true, DAG); 255 case ISD::UDIVREM: return lowerMulDiv(Op, MipsISD::DivRemU, true, true, 256 DAG); 257 case ISD::INTRINSIC_WO_CHAIN: return lowerINTRINSIC_WO_CHAIN(Op, DAG); 258 case ISD::INTRINSIC_W_CHAIN: return lowerINTRINSIC_W_CHAIN(Op, DAG); 259 case ISD::INTRINSIC_VOID: return lowerINTRINSIC_VOID(Op, DAG); 260 case ISD::EXTRACT_VECTOR_ELT: return lowerEXTRACT_VECTOR_ELT(Op, DAG); 261 case ISD::BUILD_VECTOR: return lowerBUILD_VECTOR(Op, DAG); 262 } 263 264 return MipsTargetLowering::LowerOperation(Op, DAG); 265} 266 267// selectMADD - 268// Transforms a subgraph in CurDAG if the following pattern is found: 269// (addc multLo, Lo0), (adde multHi, Hi0), 270// where, 271// multHi/Lo: product of multiplication 272// Lo0: initial value of Lo register 273// Hi0: initial value of Hi register 274// Return true if pattern matching was successful. 275static bool selectMADD(SDNode *ADDENode, SelectionDAG *CurDAG) { 276 // ADDENode's second operand must be a flag output of an ADDC node in order 277 // for the matching to be successful. 278 SDNode *ADDCNode = ADDENode->getOperand(2).getNode(); 279 280 if (ADDCNode->getOpcode() != ISD::ADDC) 281 return false; 282 283 SDValue MultHi = ADDENode->getOperand(0); 284 SDValue MultLo = ADDCNode->getOperand(0); 285 SDNode *MultNode = MultHi.getNode(); 286 unsigned MultOpc = MultHi.getOpcode(); 287 288 // MultHi and MultLo must be generated by the same node, 289 if (MultLo.getNode() != MultNode) 290 return false; 291 292 // and it must be a multiplication. 293 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI) 294 return false; 295 296 // MultLo amd MultHi must be the first and second output of MultNode 297 // respectively. 298 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0) 299 return false; 300 301 // Transform this to a MADD only if ADDENode and ADDCNode are the only users 302 // of the values of MultNode, in which case MultNode will be removed in later 303 // phases. 304 // If there exist users other than ADDENode or ADDCNode, this function returns 305 // here, which will result in MultNode being mapped to a single MULT 306 // instruction node rather than a pair of MULT and MADD instructions being 307 // produced. 308 if (!MultHi.hasOneUse() || !MultLo.hasOneUse()) 309 return false; 310 311 SDLoc DL(ADDENode); 312 313 // Initialize accumulator. 314 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped, 315 ADDCNode->getOperand(1), 316 ADDENode->getOperand(1)); 317 318 // create MipsMAdd(u) node 319 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MAddu : MipsISD::MAdd; 320 321 SDValue MAdd = CurDAG->getNode(MultOpc, DL, MVT::Untyped, 322 MultNode->getOperand(0),// Factor 0 323 MultNode->getOperand(1),// Factor 1 324 ACCIn); 325 326 // replace uses of adde and addc here 327 if (!SDValue(ADDCNode, 0).use_empty()) { 328 SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32); 329 SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd, 330 LoIdx); 331 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDCNode, 0), LoOut); 332 } 333 if (!SDValue(ADDENode, 0).use_empty()) { 334 SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32); 335 SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd, 336 HiIdx); 337 CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDENode, 0), HiOut); 338 } 339 340 return true; 341} 342 343// selectMSUB - 344// Transforms a subgraph in CurDAG if the following pattern is found: 345// (addc Lo0, multLo), (sube Hi0, multHi), 346// where, 347// multHi/Lo: product of multiplication 348// Lo0: initial value of Lo register 349// Hi0: initial value of Hi register 350// Return true if pattern matching was successful. 351static bool selectMSUB(SDNode *SUBENode, SelectionDAG *CurDAG) { 352 // SUBENode's second operand must be a flag output of an SUBC node in order 353 // for the matching to be successful. 354 SDNode *SUBCNode = SUBENode->getOperand(2).getNode(); 355 356 if (SUBCNode->getOpcode() != ISD::SUBC) 357 return false; 358 359 SDValue MultHi = SUBENode->getOperand(1); 360 SDValue MultLo = SUBCNode->getOperand(1); 361 SDNode *MultNode = MultHi.getNode(); 362 unsigned MultOpc = MultHi.getOpcode(); 363 364 // MultHi and MultLo must be generated by the same node, 365 if (MultLo.getNode() != MultNode) 366 return false; 367 368 // and it must be a multiplication. 369 if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI) 370 return false; 371 372 // MultLo amd MultHi must be the first and second output of MultNode 373 // respectively. 374 if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0) 375 return false; 376 377 // Transform this to a MSUB only if SUBENode and SUBCNode are the only users 378 // of the values of MultNode, in which case MultNode will be removed in later 379 // phases. 380 // If there exist users other than SUBENode or SUBCNode, this function returns 381 // here, which will result in MultNode being mapped to a single MULT 382 // instruction node rather than a pair of MULT and MSUB instructions being 383 // produced. 384 if (!MultHi.hasOneUse() || !MultLo.hasOneUse()) 385 return false; 386 387 SDLoc DL(SUBENode); 388 389 // Initialize accumulator. 390 SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped, 391 SUBCNode->getOperand(0), 392 SUBENode->getOperand(0)); 393 394 // create MipsSub(u) node 395 MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MSubu : MipsISD::MSub; 396 397 SDValue MSub = CurDAG->getNode(MultOpc, DL, MVT::Glue, 398 MultNode->getOperand(0),// Factor 0 399 MultNode->getOperand(1),// Factor 1 400 ACCIn); 401 402 // replace uses of sube and subc here 403 if (!SDValue(SUBCNode, 0).use_empty()) { 404 SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32); 405 SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub, 406 LoIdx); 407 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBCNode, 0), LoOut); 408 } 409 if (!SDValue(SUBENode, 0).use_empty()) { 410 SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32); 411 SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub, 412 HiIdx); 413 CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBENode, 0), HiOut); 414 } 415 416 return true; 417} 418 419static SDValue performADDECombine(SDNode *N, SelectionDAG &DAG, 420 TargetLowering::DAGCombinerInfo &DCI, 421 const MipsSubtarget *Subtarget) { 422 if (DCI.isBeforeLegalize()) 423 return SDValue(); 424 425 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 && 426 selectMADD(N, &DAG)) 427 return SDValue(N, 0); 428 429 return SDValue(); 430} 431 432// Fold zero extensions into MipsISD::VEXTRACT_[SZ]EXT_ELT 433// 434// Performs the following transformations: 435// - Changes MipsISD::VEXTRACT_[SZ]EXT_ELT to zero extension if its 436// sign/zero-extension is completely overwritten by the new one performed by 437// the ISD::AND. 438// - Removes redundant zero extensions performed by an ISD::AND. 439static SDValue performANDCombine(SDNode *N, SelectionDAG &DAG, 440 TargetLowering::DAGCombinerInfo &DCI, 441 const MipsSubtarget *Subtarget) { 442 if (!Subtarget->hasMSA()) 443 return SDValue(); 444 445 SDValue Op0 = N->getOperand(0); 446 SDValue Op1 = N->getOperand(1); 447 unsigned Op0Opcode = Op0->getOpcode(); 448 449 // (and (MipsVExtract[SZ]Ext $a, $b, $c), imm:$d) 450 // where $d + 1 == 2^n and n == 32 451 // or $d + 1 == 2^n and n <= 32 and ZExt 452 // -> (MipsVExtractZExt $a, $b, $c) 453 if (Op0Opcode == MipsISD::VEXTRACT_SEXT_ELT || 454 Op0Opcode == MipsISD::VEXTRACT_ZEXT_ELT) { 455 ConstantSDNode *Mask = dyn_cast<ConstantSDNode>(Op1); 456 457 if (!Mask) 458 return SDValue(); 459 460 int32_t Log2IfPositive = (Mask->getAPIntValue() + 1).exactLogBase2(); 461 462 if (Log2IfPositive <= 0) 463 return SDValue(); // Mask+1 is not a power of 2 464 465 SDValue Op0Op2 = Op0->getOperand(2); 466 EVT ExtendTy = cast<VTSDNode>(Op0Op2)->getVT(); 467 unsigned ExtendTySize = ExtendTy.getSizeInBits(); 468 unsigned Log2 = Log2IfPositive; 469 470 if ((Op0Opcode == MipsISD::VEXTRACT_ZEXT_ELT && Log2 >= ExtendTySize) || 471 Log2 == ExtendTySize) { 472 SDValue Ops[] = { Op0->getOperand(0), Op0->getOperand(1), Op0Op2 }; 473 DAG.MorphNodeTo(Op0.getNode(), MipsISD::VEXTRACT_ZEXT_ELT, 474 Op0->getVTList(), Ops, Op0->getNumOperands()); 475 return Op0; 476 } 477 } 478 479 return SDValue(); 480} 481 482static SDValue performSUBECombine(SDNode *N, SelectionDAG &DAG, 483 TargetLowering::DAGCombinerInfo &DCI, 484 const MipsSubtarget *Subtarget) { 485 if (DCI.isBeforeLegalize()) 486 return SDValue(); 487 488 if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 && 489 selectMSUB(N, &DAG)) 490 return SDValue(N, 0); 491 492 return SDValue(); 493} 494 495static SDValue genConstMult(SDValue X, uint64_t C, SDLoc DL, EVT VT, 496 EVT ShiftTy, SelectionDAG &DAG) { 497 // Clear the upper (64 - VT.sizeInBits) bits. 498 C &= ((uint64_t)-1) >> (64 - VT.getSizeInBits()); 499 500 // Return 0. 501 if (C == 0) 502 return DAG.getConstant(0, VT); 503 504 // Return x. 505 if (C == 1) 506 return X; 507 508 // If c is power of 2, return (shl x, log2(c)). 509 if (isPowerOf2_64(C)) 510 return DAG.getNode(ISD::SHL, DL, VT, X, 511 DAG.getConstant(Log2_64(C), ShiftTy)); 512 513 unsigned Log2Ceil = Log2_64_Ceil(C); 514 uint64_t Floor = 1LL << Log2_64(C); 515 uint64_t Ceil = Log2Ceil == 64 ? 0LL : 1LL << Log2Ceil; 516 517 // If |c - floor_c| <= |c - ceil_c|, 518 // where floor_c = pow(2, floor(log2(c))) and ceil_c = pow(2, ceil(log2(c))), 519 // return (add constMult(x, floor_c), constMult(x, c - floor_c)). 520 if (C - Floor <= Ceil - C) { 521 SDValue Op0 = genConstMult(X, Floor, DL, VT, ShiftTy, DAG); 522 SDValue Op1 = genConstMult(X, C - Floor, DL, VT, ShiftTy, DAG); 523 return DAG.getNode(ISD::ADD, DL, VT, Op0, Op1); 524 } 525 526 // If |c - floor_c| > |c - ceil_c|, 527 // return (sub constMult(x, ceil_c), constMult(x, ceil_c - c)). 528 SDValue Op0 = genConstMult(X, Ceil, DL, VT, ShiftTy, DAG); 529 SDValue Op1 = genConstMult(X, Ceil - C, DL, VT, ShiftTy, DAG); 530 return DAG.getNode(ISD::SUB, DL, VT, Op0, Op1); 531} 532 533static SDValue performMULCombine(SDNode *N, SelectionDAG &DAG, 534 const TargetLowering::DAGCombinerInfo &DCI, 535 const MipsSETargetLowering *TL) { 536 EVT VT = N->getValueType(0); 537 538 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1))) 539 if (!VT.isVector()) 540 return genConstMult(N->getOperand(0), C->getZExtValue(), SDLoc(N), 541 VT, TL->getScalarShiftAmountTy(VT), DAG); 542 543 return SDValue(N, 0); 544} 545 546static SDValue performDSPShiftCombine(unsigned Opc, SDNode *N, EVT Ty, 547 SelectionDAG &DAG, 548 const MipsSubtarget *Subtarget) { 549 // See if this is a vector splat immediate node. 550 APInt SplatValue, SplatUndef; 551 unsigned SplatBitSize; 552 bool HasAnyUndefs; 553 unsigned EltSize = Ty.getVectorElementType().getSizeInBits(); 554 BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(N->getOperand(1)); 555 556 if (!BV || 557 !BV->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, HasAnyUndefs, 558 EltSize, !Subtarget->isLittle()) || 559 (SplatBitSize != EltSize) || 560 (SplatValue.getZExtValue() >= EltSize)) 561 return SDValue(); 562 563 return DAG.getNode(Opc, SDLoc(N), Ty, N->getOperand(0), 564 DAG.getConstant(SplatValue.getZExtValue(), MVT::i32)); 565} 566 567static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG, 568 TargetLowering::DAGCombinerInfo &DCI, 569 const MipsSubtarget *Subtarget) { 570 EVT Ty = N->getValueType(0); 571 572 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8)) 573 return SDValue(); 574 575 return performDSPShiftCombine(MipsISD::SHLL_DSP, N, Ty, DAG, Subtarget); 576} 577 578// Fold sign-extensions into MipsISD::VEXTRACT_[SZ]EXT_ELT for MSA and fold 579// constant splats into MipsISD::SHRA_DSP for DSPr2. 580// 581// Performs the following transformations: 582// - Changes MipsISD::VEXTRACT_[SZ]EXT_ELT to sign extension if its 583// sign/zero-extension is completely overwritten by the new one performed by 584// the ISD::SRA and ISD::SHL nodes. 585// - Removes redundant sign extensions performed by an ISD::SRA and ISD::SHL 586// sequence. 587// 588// See performDSPShiftCombine for more information about the transformation 589// used for DSPr2. 590static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG, 591 TargetLowering::DAGCombinerInfo &DCI, 592 const MipsSubtarget *Subtarget) { 593 EVT Ty = N->getValueType(0); 594 595 if (Subtarget->hasMSA()) { 596 SDValue Op0 = N->getOperand(0); 597 SDValue Op1 = N->getOperand(1); 598 599 // (sra (shl (MipsVExtract[SZ]Ext $a, $b, $c), imm:$d), imm:$d) 600 // where $d + sizeof($c) == 32 601 // or $d + sizeof($c) <= 32 and SExt 602 // -> (MipsVExtractSExt $a, $b, $c) 603 if (Op0->getOpcode() == ISD::SHL && Op1 == Op0->getOperand(1)) { 604 SDValue Op0Op0 = Op0->getOperand(0); 605 ConstantSDNode *ShAmount = dyn_cast<ConstantSDNode>(Op1); 606 607 if (!ShAmount) 608 return SDValue(); 609 610 EVT ExtendTy = cast<VTSDNode>(Op0Op0->getOperand(2))->getVT(); 611 unsigned TotalBits = ShAmount->getZExtValue() + ExtendTy.getSizeInBits(); 612 613 if (TotalBits == 32 || 614 (Op0Op0->getOpcode() == MipsISD::VEXTRACT_SEXT_ELT && 615 TotalBits <= 32)) { 616 SDValue Ops[] = { Op0Op0->getOperand(0), Op0Op0->getOperand(1), 617 Op0Op0->getOperand(2) }; 618 DAG.MorphNodeTo(Op0Op0.getNode(), MipsISD::VEXTRACT_SEXT_ELT, 619 Op0Op0->getVTList(), Ops, Op0Op0->getNumOperands()); 620 return Op0Op0; 621 } 622 } 623 } 624 625 if ((Ty != MVT::v2i16) && ((Ty != MVT::v4i8) || !Subtarget->hasDSPR2())) 626 return SDValue(); 627 628 return performDSPShiftCombine(MipsISD::SHRA_DSP, N, Ty, DAG, Subtarget); 629} 630 631 632static SDValue performSRLCombine(SDNode *N, SelectionDAG &DAG, 633 TargetLowering::DAGCombinerInfo &DCI, 634 const MipsSubtarget *Subtarget) { 635 EVT Ty = N->getValueType(0); 636 637 if (((Ty != MVT::v2i16) || !Subtarget->hasDSPR2()) && (Ty != MVT::v4i8)) 638 return SDValue(); 639 640 return performDSPShiftCombine(MipsISD::SHRL_DSP, N, Ty, DAG, Subtarget); 641} 642 643static bool isLegalDSPCondCode(EVT Ty, ISD::CondCode CC) { 644 bool IsV216 = (Ty == MVT::v2i16); 645 646 switch (CC) { 647 case ISD::SETEQ: 648 case ISD::SETNE: return true; 649 case ISD::SETLT: 650 case ISD::SETLE: 651 case ISD::SETGT: 652 case ISD::SETGE: return IsV216; 653 case ISD::SETULT: 654 case ISD::SETULE: 655 case ISD::SETUGT: 656 case ISD::SETUGE: return !IsV216; 657 default: return false; 658 } 659} 660 661static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG) { 662 EVT Ty = N->getValueType(0); 663 664 if ((Ty != MVT::v2i16) && (Ty != MVT::v4i8)) 665 return SDValue(); 666 667 if (!isLegalDSPCondCode(Ty, cast<CondCodeSDNode>(N->getOperand(2))->get())) 668 return SDValue(); 669 670 return DAG.getNode(MipsISD::SETCC_DSP, SDLoc(N), Ty, N->getOperand(0), 671 N->getOperand(1), N->getOperand(2)); 672} 673 674static SDValue performVSELECTCombine(SDNode *N, SelectionDAG &DAG) { 675 EVT Ty = N->getValueType(0); 676 677 if (Ty.is128BitVector() && Ty.isInteger()) { 678 // Try the following combines: 679 // (vselect (setcc $a, $b, SETLT), $b, $a)) -> (vsmax $a, $b) 680 // (vselect (setcc $a, $b, SETLE), $b, $a)) -> (vsmax $a, $b) 681 // (vselect (setcc $a, $b, SETLT), $a, $b)) -> (vsmin $a, $b) 682 // (vselect (setcc $a, $b, SETLE), $a, $b)) -> (vsmin $a, $b) 683 // (vselect (setcc $a, $b, SETULT), $b, $a)) -> (vumax $a, $b) 684 // (vselect (setcc $a, $b, SETULE), $b, $a)) -> (vumax $a, $b) 685 // (vselect (setcc $a, $b, SETULT), $a, $b)) -> (vumin $a, $b) 686 // (vselect (setcc $a, $b, SETULE), $a, $b)) -> (vumin $a, $b) 687 // SETGT/SETGE/SETUGT/SETUGE variants of these will show up initially but 688 // will be expanded to equivalent SETLT/SETLE/SETULT/SETULE versions by the 689 // legalizer. 690 SDValue Op0 = N->getOperand(0); 691 692 if (Op0->getOpcode() != ISD::SETCC) 693 return SDValue(); 694 695 ISD::CondCode CondCode = cast<CondCodeSDNode>(Op0->getOperand(2))->get(); 696 bool Signed; 697 698 if (CondCode == ISD::SETLT || CondCode == ISD::SETLE) 699 Signed = true; 700 else if (CondCode == ISD::SETULT || CondCode == ISD::SETULE) 701 Signed = false; 702 else 703 return SDValue(); 704 705 SDValue Op1 = N->getOperand(1); 706 SDValue Op2 = N->getOperand(2); 707 SDValue Op0Op0 = Op0->getOperand(0); 708 SDValue Op0Op1 = Op0->getOperand(1); 709 710 if (Op1 == Op0Op0 && Op2 == Op0Op1) 711 return DAG.getNode(Signed ? MipsISD::VSMIN : MipsISD::VUMIN, SDLoc(N), 712 Ty, Op1, Op2); 713 else if (Op1 == Op0Op1 && Op2 == Op0Op0) 714 return DAG.getNode(Signed ? MipsISD::VSMAX : MipsISD::VUMAX, SDLoc(N), 715 Ty, Op1, Op2); 716 } else if ((Ty == MVT::v2i16) || (Ty == MVT::v4i8)) { 717 SDValue SetCC = N->getOperand(0); 718 719 if (SetCC.getOpcode() != MipsISD::SETCC_DSP) 720 return SDValue(); 721 722 return DAG.getNode(MipsISD::SELECT_CC_DSP, SDLoc(N), Ty, 723 SetCC.getOperand(0), SetCC.getOperand(1), 724 N->getOperand(1), N->getOperand(2), SetCC.getOperand(2)); 725 } 726 727 return SDValue(); 728} 729 730static SDValue performXORCombine(SDNode *N, SelectionDAG &DAG, 731 const MipsSubtarget *Subtarget) { 732 EVT Ty = N->getValueType(0); 733 734 if (Subtarget->hasMSA() && Ty.is128BitVector() && Ty.isInteger()) { 735 // Try the following combines: 736 // (xor (or $a, $b), (build_vector allones)) 737 // (xor (or $a, $b), (bitcast (build_vector allones))) 738 SDValue Op0 = N->getOperand(0); 739 SDValue Op1 = N->getOperand(1); 740 SDValue NotOp; 741 ConstantSDNode *Const; 742 743 if (ISD::isBuildVectorAllOnes(Op0.getNode())) 744 NotOp = Op1; 745 else if (ISD::isBuildVectorAllOnes(Op1.getNode())) 746 NotOp = Op0; 747 else if ((Op0->getOpcode() == MipsISD::VSPLAT || 748 Op0->getOpcode() == MipsISD::VSPLATD) && 749 (Const = dyn_cast<ConstantSDNode>(Op0->getOperand(0))) && 750 Const->isAllOnesValue()) 751 NotOp = Op1; 752 else if ((Op1->getOpcode() == MipsISD::VSPLAT || 753 Op1->getOpcode() == MipsISD::VSPLATD) && 754 (Const = dyn_cast<ConstantSDNode>(Op1->getOperand(0))) && 755 Const->isAllOnesValue()) 756 NotOp = Op0; 757 else 758 return SDValue(); 759 760 if (NotOp->getOpcode() == ISD::OR) 761 return DAG.getNode(MipsISD::VNOR, SDLoc(N), Ty, NotOp->getOperand(0), 762 NotOp->getOperand(1)); 763 } 764 765 return SDValue(); 766} 767 768SDValue 769MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const { 770 SelectionDAG &DAG = DCI.DAG; 771 SDValue Val; 772 773 switch (N->getOpcode()) { 774 case ISD::ADDE: 775 return performADDECombine(N, DAG, DCI, Subtarget); 776 case ISD::AND: 777 Val = performANDCombine(N, DAG, DCI, Subtarget); 778 break; 779 case ISD::SUBE: 780 return performSUBECombine(N, DAG, DCI, Subtarget); 781 case ISD::MUL: 782 return performMULCombine(N, DAG, DCI, this); 783 case ISD::SHL: 784 return performSHLCombine(N, DAG, DCI, Subtarget); 785 case ISD::SRA: 786 return performSRACombine(N, DAG, DCI, Subtarget); 787 case ISD::SRL: 788 return performSRLCombine(N, DAG, DCI, Subtarget); 789 case ISD::VSELECT: 790 return performVSELECTCombine(N, DAG); 791 case ISD::XOR: 792 Val = performXORCombine(N, DAG, Subtarget); 793 break; 794 case ISD::SETCC: 795 Val = performSETCCCombine(N, DAG); 796 break; 797 } 798 799 if (Val.getNode()) 800 return Val; 801 802 return MipsTargetLowering::PerformDAGCombine(N, DCI); 803} 804 805MachineBasicBlock * 806MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 807 MachineBasicBlock *BB) const { 808 switch (MI->getOpcode()) { 809 default: 810 return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB); 811 case Mips::BPOSGE32_PSEUDO: 812 return emitBPOSGE32(MI, BB); 813 case Mips::SNZ_B_PSEUDO: 814 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_B); 815 case Mips::SNZ_H_PSEUDO: 816 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_H); 817 case Mips::SNZ_W_PSEUDO: 818 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_W); 819 case Mips::SNZ_D_PSEUDO: 820 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_D); 821 case Mips::SNZ_V_PSEUDO: 822 return emitMSACBranchPseudo(MI, BB, Mips::BNZ_V); 823 case Mips::SZ_B_PSEUDO: 824 return emitMSACBranchPseudo(MI, BB, Mips::BZ_B); 825 case Mips::SZ_H_PSEUDO: 826 return emitMSACBranchPseudo(MI, BB, Mips::BZ_H); 827 case Mips::SZ_W_PSEUDO: 828 return emitMSACBranchPseudo(MI, BB, Mips::BZ_W); 829 case Mips::SZ_D_PSEUDO: 830 return emitMSACBranchPseudo(MI, BB, Mips::BZ_D); 831 case Mips::SZ_V_PSEUDO: 832 return emitMSACBranchPseudo(MI, BB, Mips::BZ_V); 833 } 834} 835 836bool MipsSETargetLowering:: 837isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo, 838 unsigned NextStackOffset, 839 const MipsFunctionInfo& FI) const { 840 if (!EnableMipsTailCalls) 841 return false; 842 843 // Return false if either the callee or caller has a byval argument. 844 if (MipsCCInfo.hasByValArg() || FI.hasByvalArg()) 845 return false; 846 847 // Return true if the callee's argument area is no larger than the 848 // caller's. 849 return NextStackOffset <= FI.getIncomingArgSize(); 850} 851 852void MipsSETargetLowering:: 853getOpndList(SmallVectorImpl<SDValue> &Ops, 854 std::deque< std::pair<unsigned, SDValue> > &RegsToPass, 855 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage, 856 CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const { 857 // T9 should contain the address of the callee function if 858 // -reloction-model=pic or it is an indirect call. 859 if (IsPICCall || !GlobalOrExternal) { 860 unsigned T9Reg = IsN64 ? Mips::T9_64 : Mips::T9; 861 RegsToPass.push_front(std::make_pair(T9Reg, Callee)); 862 } else 863 Ops.push_back(Callee); 864 865 MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal, 866 InternalLinkage, CLI, Callee, Chain); 867} 868 869SDValue MipsSETargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const { 870 LoadSDNode &Nd = *cast<LoadSDNode>(Op); 871 872 if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore) 873 return MipsTargetLowering::lowerLOAD(Op, DAG); 874 875 // Replace a double precision load with two i32 loads and a buildpair64. 876 SDLoc DL(Op); 877 SDValue Ptr = Nd.getBasePtr(), Chain = Nd.getChain(); 878 EVT PtrVT = Ptr.getValueType(); 879 880 // i32 load from lower address. 881 SDValue Lo = DAG.getLoad(MVT::i32, DL, Chain, Ptr, 882 MachinePointerInfo(), Nd.isVolatile(), 883 Nd.isNonTemporal(), Nd.isInvariant(), 884 Nd.getAlignment()); 885 886 // i32 load from higher address. 887 Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Ptr, DAG.getConstant(4, PtrVT)); 888 SDValue Hi = DAG.getLoad(MVT::i32, DL, Lo.getValue(1), Ptr, 889 MachinePointerInfo(), Nd.isVolatile(), 890 Nd.isNonTemporal(), Nd.isInvariant(), 891 std::min(Nd.getAlignment(), 4U)); 892 893 if (!Subtarget->isLittle()) 894 std::swap(Lo, Hi); 895 896 SDValue BP = DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, Lo, Hi); 897 SDValue Ops[2] = {BP, Hi.getValue(1)}; 898 return DAG.getMergeValues(Ops, 2, DL); 899} 900 901SDValue MipsSETargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const { 902 StoreSDNode &Nd = *cast<StoreSDNode>(Op); 903 904 if (Nd.getMemoryVT() != MVT::f64 || !NoDPLoadStore) 905 return MipsTargetLowering::lowerSTORE(Op, DAG); 906 907 // Replace a double precision store with two extractelement64s and i32 stores. 908 SDLoc DL(Op); 909 SDValue Val = Nd.getValue(), Ptr = Nd.getBasePtr(), Chain = Nd.getChain(); 910 EVT PtrVT = Ptr.getValueType(); 911 SDValue Lo = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, 912 Val, DAG.getConstant(0, MVT::i32)); 913 SDValue Hi = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, 914 Val, DAG.getConstant(1, MVT::i32)); 915 916 if (!Subtarget->isLittle()) 917 std::swap(Lo, Hi); 918 919 // i32 store to lower address. 920 Chain = DAG.getStore(Chain, DL, Lo, Ptr, MachinePointerInfo(), 921 Nd.isVolatile(), Nd.isNonTemporal(), Nd.getAlignment(), 922 Nd.getTBAAInfo()); 923 924 // i32 store to higher address. 925 Ptr = DAG.getNode(ISD::ADD, DL, PtrVT, Ptr, DAG.getConstant(4, PtrVT)); 926 return DAG.getStore(Chain, DL, Hi, Ptr, MachinePointerInfo(), 927 Nd.isVolatile(), Nd.isNonTemporal(), 928 std::min(Nd.getAlignment(), 4U), Nd.getTBAAInfo()); 929} 930 931SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc, 932 bool HasLo, bool HasHi, 933 SelectionDAG &DAG) const { 934 EVT Ty = Op.getOperand(0).getValueType(); 935 SDLoc DL(Op); 936 SDValue Mult = DAG.getNode(NewOpc, DL, MVT::Untyped, 937 Op.getOperand(0), Op.getOperand(1)); 938 SDValue Lo, Hi; 939 940 if (HasLo) 941 Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult, 942 DAG.getConstant(Mips::sub_lo, MVT::i32)); 943 if (HasHi) 944 Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult, 945 DAG.getConstant(Mips::sub_hi, MVT::i32)); 946 947 if (!HasLo || !HasHi) 948 return HasLo ? Lo : Hi; 949 950 SDValue Vals[] = { Lo, Hi }; 951 return DAG.getMergeValues(Vals, 2, DL); 952} 953 954 955static SDValue initAccumulator(SDValue In, SDLoc DL, SelectionDAG &DAG) { 956 SDValue InLo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In, 957 DAG.getConstant(0, MVT::i32)); 958 SDValue InHi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, In, 959 DAG.getConstant(1, MVT::i32)); 960 return DAG.getNode(MipsISD::InsertLOHI, DL, MVT::Untyped, InLo, InHi); 961} 962 963static SDValue extractLOHI(SDValue Op, SDLoc DL, SelectionDAG &DAG) { 964 SDValue Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op, 965 DAG.getConstant(Mips::sub_lo, MVT::i32)); 966 SDValue Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, MVT::i32, Op, 967 DAG.getConstant(Mips::sub_hi, MVT::i32)); 968 return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Lo, Hi); 969} 970 971// This function expands mips intrinsic nodes which have 64-bit input operands 972// or output values. 973// 974// out64 = intrinsic-node in64 975// => 976// lo = copy (extract-element (in64, 0)) 977// hi = copy (extract-element (in64, 1)) 978// mips-specific-node 979// v0 = copy lo 980// v1 = copy hi 981// out64 = merge-values (v0, v1) 982// 983static SDValue lowerDSPIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) { 984 SDLoc DL(Op); 985 bool HasChainIn = Op->getOperand(0).getValueType() == MVT::Other; 986 SmallVector<SDValue, 3> Ops; 987 unsigned OpNo = 0; 988 989 // See if Op has a chain input. 990 if (HasChainIn) 991 Ops.push_back(Op->getOperand(OpNo++)); 992 993 // The next operand is the intrinsic opcode. 994 assert(Op->getOperand(OpNo).getOpcode() == ISD::TargetConstant); 995 996 // See if the next operand has type i64. 997 SDValue Opnd = Op->getOperand(++OpNo), In64; 998 999 if (Opnd.getValueType() == MVT::i64) 1000 In64 = initAccumulator(Opnd, DL, DAG); 1001 else 1002 Ops.push_back(Opnd); 1003 1004 // Push the remaining operands. 1005 for (++OpNo ; OpNo < Op->getNumOperands(); ++OpNo) 1006 Ops.push_back(Op->getOperand(OpNo)); 1007 1008 // Add In64 to the end of the list. 1009 if (In64.getNode()) 1010 Ops.push_back(In64); 1011 1012 // Scan output. 1013 SmallVector<EVT, 2> ResTys; 1014 1015 for (SDNode::value_iterator I = Op->value_begin(), E = Op->value_end(); 1016 I != E; ++I) 1017 ResTys.push_back((*I == MVT::i64) ? MVT::Untyped : *I); 1018 1019 // Create node. 1020 SDValue Val = DAG.getNode(Opc, DL, ResTys, &Ops[0], Ops.size()); 1021 SDValue Out = (ResTys[0] == MVT::Untyped) ? extractLOHI(Val, DL, DAG) : Val; 1022 1023 if (!HasChainIn) 1024 return Out; 1025 1026 assert(Val->getValueType(1) == MVT::Other); 1027 SDValue Vals[] = { Out, SDValue(Val.getNode(), 1) }; 1028 return DAG.getMergeValues(Vals, 2, DL); 1029} 1030 1031static SDValue lowerMSABinaryIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) { 1032 SDLoc DL(Op); 1033 SDValue LHS = Op->getOperand(1); 1034 SDValue RHS = Op->getOperand(2); 1035 EVT ResTy = Op->getValueType(0); 1036 1037 SDValue Result = DAG.getNode(Opc, DL, ResTy, LHS, RHS); 1038 1039 return Result; 1040} 1041 1042static SDValue lowerMSABinaryImmIntr(SDValue Op, SelectionDAG &DAG, 1043 unsigned Opc, SDValue RHS) { 1044 SDValue LHS = Op->getOperand(1); 1045 EVT ResTy = Op->getValueType(0); 1046 1047 return DAG.getNode(Opc, SDLoc(Op), ResTy, LHS, RHS); 1048} 1049 1050static SDValue lowerMSABranchIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) { 1051 SDLoc DL(Op); 1052 SDValue Value = Op->getOperand(1); 1053 EVT ResTy = Op->getValueType(0); 1054 1055 SDValue Result = DAG.getNode(Opc, DL, ResTy, Value); 1056 1057 return Result; 1058} 1059 1060// Lower an MSA copy intrinsic into the specified SelectionDAG node 1061static SDValue lowerMSACopyIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) { 1062 SDLoc DL(Op); 1063 SDValue Vec = Op->getOperand(1); 1064 SDValue Idx = Op->getOperand(2); 1065 EVT ResTy = Op->getValueType(0); 1066 EVT EltTy = Vec->getValueType(0).getVectorElementType(); 1067 1068 SDValue Result = DAG.getNode(Opc, DL, ResTy, Vec, Idx, 1069 DAG.getValueType(EltTy)); 1070 1071 return Result; 1072} 1073 1074// Lower an MSA insert intrinsic into the specified SelectionDAG node 1075static SDValue lowerMSAInsertIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) { 1076 SDLoc DL(Op); 1077 SDValue Op0 = Op->getOperand(1); 1078 SDValue Op1 = Op->getOperand(2); 1079 SDValue Op2 = Op->getOperand(3); 1080 EVT ResTy = Op->getValueType(0); 1081 1082 SDValue Result = DAG.getNode(Opc, DL, ResTy, Op0, Op2, Op1); 1083 1084 return Result; 1085} 1086 1087static SDValue lowerMSASplatImm(SDValue Op, unsigned ImmOp, SelectionDAG &DAG) { 1088 EVT ResTy = Op->getValueType(0); 1089 1090 unsigned SplatOp = MipsISD::VSPLAT; 1091 if (ResTy == MVT::v2i64) 1092 SplatOp = MipsISD::VSPLATD; 1093 1094 return DAG.getNode(SplatOp, SDLoc(Op), ResTy, Op->getOperand(ImmOp)); 1095} 1096 1097static SDValue lowerMSAUnaryIntr(SDValue Op, SelectionDAG &DAG, unsigned Opc) { 1098 SDLoc DL(Op); 1099 SDValue Value = Op->getOperand(1); 1100 EVT ResTy = Op->getValueType(0); 1101 1102 SDValue Result = DAG.getNode(Opc, DL, ResTy, Value); 1103 1104 return Result; 1105} 1106 1107SDValue MipsSETargetLowering::lowerINTRINSIC_WO_CHAIN(SDValue Op, 1108 SelectionDAG &DAG) const { 1109 switch (cast<ConstantSDNode>(Op->getOperand(0))->getZExtValue()) { 1110 default: 1111 return SDValue(); 1112 case Intrinsic::mips_shilo: 1113 return lowerDSPIntr(Op, DAG, MipsISD::SHILO); 1114 case Intrinsic::mips_dpau_h_qbl: 1115 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBL); 1116 case Intrinsic::mips_dpau_h_qbr: 1117 return lowerDSPIntr(Op, DAG, MipsISD::DPAU_H_QBR); 1118 case Intrinsic::mips_dpsu_h_qbl: 1119 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBL); 1120 case Intrinsic::mips_dpsu_h_qbr: 1121 return lowerDSPIntr(Op, DAG, MipsISD::DPSU_H_QBR); 1122 case Intrinsic::mips_dpa_w_ph: 1123 return lowerDSPIntr(Op, DAG, MipsISD::DPA_W_PH); 1124 case Intrinsic::mips_dps_w_ph: 1125 return lowerDSPIntr(Op, DAG, MipsISD::DPS_W_PH); 1126 case Intrinsic::mips_dpax_w_ph: 1127 return lowerDSPIntr(Op, DAG, MipsISD::DPAX_W_PH); 1128 case Intrinsic::mips_dpsx_w_ph: 1129 return lowerDSPIntr(Op, DAG, MipsISD::DPSX_W_PH); 1130 case Intrinsic::mips_mulsa_w_ph: 1131 return lowerDSPIntr(Op, DAG, MipsISD::MULSA_W_PH); 1132 case Intrinsic::mips_mult: 1133 return lowerDSPIntr(Op, DAG, MipsISD::Mult); 1134 case Intrinsic::mips_multu: 1135 return lowerDSPIntr(Op, DAG, MipsISD::Multu); 1136 case Intrinsic::mips_madd: 1137 return lowerDSPIntr(Op, DAG, MipsISD::MAdd); 1138 case Intrinsic::mips_maddu: 1139 return lowerDSPIntr(Op, DAG, MipsISD::MAddu); 1140 case Intrinsic::mips_msub: 1141 return lowerDSPIntr(Op, DAG, MipsISD::MSub); 1142 case Intrinsic::mips_msubu: 1143 return lowerDSPIntr(Op, DAG, MipsISD::MSubu); 1144 case Intrinsic::mips_addv_b: 1145 case Intrinsic::mips_addv_h: 1146 case Intrinsic::mips_addv_w: 1147 case Intrinsic::mips_addv_d: 1148 return lowerMSABinaryIntr(Op, DAG, ISD::ADD); 1149 case Intrinsic::mips_addvi_b: 1150 case Intrinsic::mips_addvi_h: 1151 case Intrinsic::mips_addvi_w: 1152 case Intrinsic::mips_addvi_d: 1153 return lowerMSABinaryImmIntr(Op, DAG, ISD::ADD, 1154 lowerMSASplatImm(Op, 2, DAG)); 1155 case Intrinsic::mips_and_v: 1156 return lowerMSABinaryIntr(Op, DAG, ISD::AND); 1157 case Intrinsic::mips_andi_b: 1158 return lowerMSABinaryImmIntr(Op, DAG, ISD::AND, 1159 lowerMSASplatImm(Op, 2, DAG)); 1160 case Intrinsic::mips_bnz_b: 1161 case Intrinsic::mips_bnz_h: 1162 case Intrinsic::mips_bnz_w: 1163 case Intrinsic::mips_bnz_d: 1164 return lowerMSABranchIntr(Op, DAG, MipsISD::VALL_NONZERO); 1165 case Intrinsic::mips_bnz_v: 1166 return lowerMSABranchIntr(Op, DAG, MipsISD::VANY_NONZERO); 1167 case Intrinsic::mips_bsel_v: 1168 return DAG.getNode(ISD::VSELECT, SDLoc(Op), Op->getValueType(0), 1169 Op->getOperand(1), Op->getOperand(2), 1170 Op->getOperand(3)); 1171 case Intrinsic::mips_bseli_b: 1172 return DAG.getNode(ISD::VSELECT, SDLoc(Op), Op->getValueType(0), 1173 Op->getOperand(1), Op->getOperand(2), 1174 lowerMSASplatImm(Op, 3, DAG)); 1175 case Intrinsic::mips_bz_b: 1176 case Intrinsic::mips_bz_h: 1177 case Intrinsic::mips_bz_w: 1178 case Intrinsic::mips_bz_d: 1179 return lowerMSABranchIntr(Op, DAG, MipsISD::VALL_ZERO); 1180 case Intrinsic::mips_bz_v: 1181 return lowerMSABranchIntr(Op, DAG, MipsISD::VANY_ZERO); 1182 case Intrinsic::mips_ceq_b: 1183 case Intrinsic::mips_ceq_h: 1184 case Intrinsic::mips_ceq_w: 1185 case Intrinsic::mips_ceq_d: 1186 return DAG.getSetCC(SDLoc(Op), Op->getValueType(0), Op->getOperand(1), 1187 Op->getOperand(2), ISD::SETEQ); 1188 case Intrinsic::mips_ceqi_b: 1189 case Intrinsic::mips_ceqi_h: 1190 case Intrinsic::mips_ceqi_w: 1191 case Intrinsic::mips_ceqi_d: 1192 return DAG.getSetCC(SDLoc(Op), Op->getValueType(0), Op->getOperand(1), 1193 lowerMSASplatImm(Op, 2, DAG), ISD::SETEQ); 1194 case Intrinsic::mips_cle_s_b: 1195 case Intrinsic::mips_cle_s_h: 1196 case Intrinsic::mips_cle_s_w: 1197 case Intrinsic::mips_cle_s_d: 1198 return DAG.getSetCC(SDLoc(Op), Op->getValueType(0), Op->getOperand(1), 1199 Op->getOperand(2), ISD::SETLE); 1200 case Intrinsic::mips_clei_s_b: 1201 case Intrinsic::mips_clei_s_h: 1202 case Intrinsic::mips_clei_s_w: 1203 case Intrinsic::mips_clei_s_d: 1204 return DAG.getSetCC(SDLoc(Op), Op->getValueType(0), Op->getOperand(1), 1205 lowerMSASplatImm(Op, 2, DAG), ISD::SETLE); 1206 case Intrinsic::mips_cle_u_b: 1207 case Intrinsic::mips_cle_u_h: 1208 case Intrinsic::mips_cle_u_w: 1209 case Intrinsic::mips_cle_u_d: 1210 return DAG.getSetCC(SDLoc(Op), Op->getValueType(0), Op->getOperand(1), 1211 Op->getOperand(2), ISD::SETULE); 1212 case Intrinsic::mips_clei_u_b: 1213 case Intrinsic::mips_clei_u_h: 1214 case Intrinsic::mips_clei_u_w: 1215 case Intrinsic::mips_clei_u_d: 1216 return DAG.getSetCC(SDLoc(Op), Op->getValueType(0), Op->getOperand(1), 1217 lowerMSASplatImm(Op, 2, DAG), ISD::SETULE); 1218 case Intrinsic::mips_clt_s_b: 1219 case Intrinsic::mips_clt_s_h: 1220 case Intrinsic::mips_clt_s_w: 1221 case Intrinsic::mips_clt_s_d: 1222 return DAG.getSetCC(SDLoc(Op), Op->getValueType(0), Op->getOperand(1), 1223 Op->getOperand(2), ISD::SETLT); 1224 case Intrinsic::mips_clti_s_b: 1225 case Intrinsic::mips_clti_s_h: 1226 case Intrinsic::mips_clti_s_w: 1227 case Intrinsic::mips_clti_s_d: 1228 return DAG.getSetCC(SDLoc(Op), Op->getValueType(0), Op->getOperand(1), 1229 lowerMSASplatImm(Op, 2, DAG), ISD::SETLT); 1230 case Intrinsic::mips_clt_u_b: 1231 case Intrinsic::mips_clt_u_h: 1232 case Intrinsic::mips_clt_u_w: 1233 case Intrinsic::mips_clt_u_d: 1234 return DAG.getSetCC(SDLoc(Op), Op->getValueType(0), Op->getOperand(1), 1235 Op->getOperand(2), ISD::SETULT); 1236 case Intrinsic::mips_clti_u_b: 1237 case Intrinsic::mips_clti_u_h: 1238 case Intrinsic::mips_clti_u_w: 1239 case Intrinsic::mips_clti_u_d: 1240 return DAG.getSetCC(SDLoc(Op), Op->getValueType(0), Op->getOperand(1), 1241 lowerMSASplatImm(Op, 2, DAG), ISD::SETULT); 1242 case Intrinsic::mips_copy_s_b: 1243 case Intrinsic::mips_copy_s_h: 1244 case Intrinsic::mips_copy_s_w: 1245 return lowerMSACopyIntr(Op, DAG, MipsISD::VEXTRACT_SEXT_ELT); 1246 case Intrinsic::mips_copy_u_b: 1247 case Intrinsic::mips_copy_u_h: 1248 case Intrinsic::mips_copy_u_w: 1249 return lowerMSACopyIntr(Op, DAG, MipsISD::VEXTRACT_ZEXT_ELT); 1250 case Intrinsic::mips_div_s_b: 1251 case Intrinsic::mips_div_s_h: 1252 case Intrinsic::mips_div_s_w: 1253 case Intrinsic::mips_div_s_d: 1254 return lowerMSABinaryIntr(Op, DAG, ISD::SDIV); 1255 case Intrinsic::mips_div_u_b: 1256 case Intrinsic::mips_div_u_h: 1257 case Intrinsic::mips_div_u_w: 1258 case Intrinsic::mips_div_u_d: 1259 return lowerMSABinaryIntr(Op, DAG, ISD::UDIV); 1260 case Intrinsic::mips_fadd_w: 1261 case Intrinsic::mips_fadd_d: 1262 return lowerMSABinaryIntr(Op, DAG, ISD::FADD); 1263 // Don't lower mips_fcaf_[wd] since LLVM folds SETFALSE condcodes away 1264 case Intrinsic::mips_fceq_w: 1265 case Intrinsic::mips_fceq_d: 1266 return DAG.getSetCC(SDLoc(Op), Op->getValueType(0), Op->getOperand(1), 1267 Op->getOperand(2), ISD::SETOEQ); 1268 case Intrinsic::mips_fcle_w: 1269 case Intrinsic::mips_fcle_d: 1270 return DAG.getSetCC(SDLoc(Op), Op->getValueType(0), Op->getOperand(1), 1271 Op->getOperand(2), ISD::SETOLE); 1272 case Intrinsic::mips_fclt_w: 1273 case Intrinsic::mips_fclt_d: 1274 return DAG.getSetCC(SDLoc(Op), Op->getValueType(0), Op->getOperand(1), 1275 Op->getOperand(2), ISD::SETOLT); 1276 case Intrinsic::mips_fcne_w: 1277 case Intrinsic::mips_fcne_d: 1278 return DAG.getSetCC(SDLoc(Op), Op->getValueType(0), Op->getOperand(1), 1279 Op->getOperand(2), ISD::SETONE); 1280 case Intrinsic::mips_fcor_w: 1281 case Intrinsic::mips_fcor_d: 1282 return DAG.getSetCC(SDLoc(Op), Op->getValueType(0), Op->getOperand(1), 1283 Op->getOperand(2), ISD::SETO); 1284 case Intrinsic::mips_fcueq_w: 1285 case Intrinsic::mips_fcueq_d: 1286 return DAG.getSetCC(SDLoc(Op), Op->getValueType(0), Op->getOperand(1), 1287 Op->getOperand(2), ISD::SETUEQ); 1288 case Intrinsic::mips_fcule_w: 1289 case Intrinsic::mips_fcule_d: 1290 return DAG.getSetCC(SDLoc(Op), Op->getValueType(0), Op->getOperand(1), 1291 Op->getOperand(2), ISD::SETULE); 1292 case Intrinsic::mips_fcult_w: 1293 case Intrinsic::mips_fcult_d: 1294 return DAG.getSetCC(SDLoc(Op), Op->getValueType(0), Op->getOperand(1), 1295 Op->getOperand(2), ISD::SETULT); 1296 case Intrinsic::mips_fcun_w: 1297 case Intrinsic::mips_fcun_d: 1298 return DAG.getSetCC(SDLoc(Op), Op->getValueType(0), Op->getOperand(1), 1299 Op->getOperand(2), ISD::SETUO); 1300 case Intrinsic::mips_fcune_w: 1301 case Intrinsic::mips_fcune_d: 1302 return DAG.getSetCC(SDLoc(Op), Op->getValueType(0), Op->getOperand(1), 1303 Op->getOperand(2), ISD::SETUNE); 1304 case Intrinsic::mips_fdiv_w: 1305 case Intrinsic::mips_fdiv_d: 1306 return lowerMSABinaryIntr(Op, DAG, ISD::FDIV); 1307 case Intrinsic::mips_fill_b: 1308 case Intrinsic::mips_fill_h: 1309 case Intrinsic::mips_fill_w: 1310 return lowerMSAUnaryIntr(Op, DAG, MipsISD::VSPLAT); 1311 case Intrinsic::mips_flog2_w: 1312 case Intrinsic::mips_flog2_d: 1313 return lowerMSAUnaryIntr(Op, DAG, ISD::FLOG2); 1314 case Intrinsic::mips_fmul_w: 1315 case Intrinsic::mips_fmul_d: 1316 return lowerMSABinaryIntr(Op, DAG, ISD::FMUL); 1317 case Intrinsic::mips_frint_w: 1318 case Intrinsic::mips_frint_d: 1319 return lowerMSAUnaryIntr(Op, DAG, ISD::FRINT); 1320 case Intrinsic::mips_fsqrt_w: 1321 case Intrinsic::mips_fsqrt_d: 1322 return lowerMSAUnaryIntr(Op, DAG, ISD::FSQRT); 1323 case Intrinsic::mips_fsub_w: 1324 case Intrinsic::mips_fsub_d: 1325 return lowerMSABinaryIntr(Op, DAG, ISD::FSUB); 1326 case Intrinsic::mips_insert_b: 1327 case Intrinsic::mips_insert_h: 1328 case Intrinsic::mips_insert_w: 1329 return lowerMSAInsertIntr(Op, DAG, ISD::INSERT_VECTOR_ELT); 1330 case Intrinsic::mips_ldi_b: 1331 case Intrinsic::mips_ldi_h: 1332 case Intrinsic::mips_ldi_w: 1333 case Intrinsic::mips_ldi_d: 1334 return lowerMSAUnaryIntr(Op, DAG, MipsISD::VSPLAT); 1335 case Intrinsic::mips_max_s_b: 1336 case Intrinsic::mips_max_s_h: 1337 case Intrinsic::mips_max_s_w: 1338 case Intrinsic::mips_max_s_d: 1339 return lowerMSABinaryIntr(Op, DAG, MipsISD::VSMAX); 1340 case Intrinsic::mips_max_u_b: 1341 case Intrinsic::mips_max_u_h: 1342 case Intrinsic::mips_max_u_w: 1343 case Intrinsic::mips_max_u_d: 1344 return lowerMSABinaryIntr(Op, DAG, MipsISD::VUMAX); 1345 case Intrinsic::mips_maxi_s_b: 1346 case Intrinsic::mips_maxi_s_h: 1347 case Intrinsic::mips_maxi_s_w: 1348 case Intrinsic::mips_maxi_s_d: 1349 return lowerMSABinaryImmIntr(Op, DAG, MipsISD::VSMAX, 1350 lowerMSASplatImm(Op, 2, DAG)); 1351 case Intrinsic::mips_maxi_u_b: 1352 case Intrinsic::mips_maxi_u_h: 1353 case Intrinsic::mips_maxi_u_w: 1354 case Intrinsic::mips_maxi_u_d: 1355 return lowerMSABinaryImmIntr(Op, DAG, MipsISD::VUMAX, 1356 lowerMSASplatImm(Op, 2, DAG)); 1357 case Intrinsic::mips_min_s_b: 1358 case Intrinsic::mips_min_s_h: 1359 case Intrinsic::mips_min_s_w: 1360 case Intrinsic::mips_min_s_d: 1361 return lowerMSABinaryIntr(Op, DAG, MipsISD::VSMIN); 1362 case Intrinsic::mips_min_u_b: 1363 case Intrinsic::mips_min_u_h: 1364 case Intrinsic::mips_min_u_w: 1365 case Intrinsic::mips_min_u_d: 1366 return lowerMSABinaryIntr(Op, DAG, MipsISD::VUMIN); 1367 case Intrinsic::mips_mini_s_b: 1368 case Intrinsic::mips_mini_s_h: 1369 case Intrinsic::mips_mini_s_w: 1370 case Intrinsic::mips_mini_s_d: 1371 return lowerMSABinaryImmIntr(Op, DAG, MipsISD::VSMIN, 1372 lowerMSASplatImm(Op, 2, DAG)); 1373 case Intrinsic::mips_mini_u_b: 1374 case Intrinsic::mips_mini_u_h: 1375 case Intrinsic::mips_mini_u_w: 1376 case Intrinsic::mips_mini_u_d: 1377 return lowerMSABinaryImmIntr(Op, DAG, MipsISD::VUMIN, 1378 lowerMSASplatImm(Op, 2, DAG)); 1379 case Intrinsic::mips_mulv_b: 1380 case Intrinsic::mips_mulv_h: 1381 case Intrinsic::mips_mulv_w: 1382 case Intrinsic::mips_mulv_d: 1383 return lowerMSABinaryIntr(Op, DAG, ISD::MUL); 1384 case Intrinsic::mips_nlzc_b: 1385 case Intrinsic::mips_nlzc_h: 1386 case Intrinsic::mips_nlzc_w: 1387 case Intrinsic::mips_nlzc_d: 1388 return lowerMSAUnaryIntr(Op, DAG, ISD::CTLZ); 1389 case Intrinsic::mips_nor_v: { 1390 SDValue Res = lowerMSABinaryIntr(Op, DAG, ISD::OR); 1391 return DAG.getNOT(SDLoc(Op), Res, Res->getValueType(0)); 1392 } 1393 case Intrinsic::mips_nori_b: { 1394 SDValue Res = lowerMSABinaryImmIntr(Op, DAG, ISD::OR, 1395 lowerMSASplatImm(Op, 2, DAG)); 1396 return DAG.getNOT(SDLoc(Op), Res, Res->getValueType(0)); 1397 } 1398 case Intrinsic::mips_or_v: 1399 return lowerMSABinaryIntr(Op, DAG, ISD::OR); 1400 case Intrinsic::mips_ori_b: 1401 return lowerMSABinaryImmIntr(Op, DAG, ISD::OR, 1402 lowerMSASplatImm(Op, 2, DAG)); 1403 case Intrinsic::mips_pcnt_b: 1404 case Intrinsic::mips_pcnt_h: 1405 case Intrinsic::mips_pcnt_w: 1406 case Intrinsic::mips_pcnt_d: 1407 return lowerMSAUnaryIntr(Op, DAG, ISD::CTPOP); 1408 case Intrinsic::mips_sll_b: 1409 case Intrinsic::mips_sll_h: 1410 case Intrinsic::mips_sll_w: 1411 case Intrinsic::mips_sll_d: 1412 return lowerMSABinaryIntr(Op, DAG, ISD::SHL); 1413 case Intrinsic::mips_slli_b: 1414 case Intrinsic::mips_slli_h: 1415 case Intrinsic::mips_slli_w: 1416 case Intrinsic::mips_slli_d: 1417 return lowerMSABinaryImmIntr(Op, DAG, ISD::SHL, 1418 lowerMSASplatImm(Op, 2, DAG)); 1419 case Intrinsic::mips_sra_b: 1420 case Intrinsic::mips_sra_h: 1421 case Intrinsic::mips_sra_w: 1422 case Intrinsic::mips_sra_d: 1423 return lowerMSABinaryIntr(Op, DAG, ISD::SRA); 1424 case Intrinsic::mips_srai_b: 1425 case Intrinsic::mips_srai_h: 1426 case Intrinsic::mips_srai_w: 1427 case Intrinsic::mips_srai_d: 1428 return lowerMSABinaryImmIntr(Op, DAG, ISD::SRA, 1429 lowerMSASplatImm(Op, 2, DAG)); 1430 case Intrinsic::mips_srl_b: 1431 case Intrinsic::mips_srl_h: 1432 case Intrinsic::mips_srl_w: 1433 case Intrinsic::mips_srl_d: 1434 return lowerMSABinaryIntr(Op, DAG, ISD::SRL); 1435 case Intrinsic::mips_srli_b: 1436 case Intrinsic::mips_srli_h: 1437 case Intrinsic::mips_srli_w: 1438 case Intrinsic::mips_srli_d: 1439 return lowerMSABinaryImmIntr(Op, DAG, ISD::SRL, 1440 lowerMSASplatImm(Op, 2, DAG)); 1441 case Intrinsic::mips_subv_b: 1442 case Intrinsic::mips_subv_h: 1443 case Intrinsic::mips_subv_w: 1444 case Intrinsic::mips_subv_d: 1445 return lowerMSABinaryIntr(Op, DAG, ISD::SUB); 1446 case Intrinsic::mips_subvi_b: 1447 case Intrinsic::mips_subvi_h: 1448 case Intrinsic::mips_subvi_w: 1449 case Intrinsic::mips_subvi_d: 1450 return lowerMSABinaryImmIntr(Op, DAG, ISD::SUB, 1451 lowerMSASplatImm(Op, 2, DAG)); 1452 case Intrinsic::mips_xor_v: 1453 return lowerMSABinaryIntr(Op, DAG, ISD::XOR); 1454 case Intrinsic::mips_xori_b: 1455 return lowerMSABinaryImmIntr(Op, DAG, ISD::XOR, 1456 lowerMSASplatImm(Op, 2, DAG)); 1457 } 1458} 1459 1460static SDValue lowerMSALoadIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr) { 1461 SDLoc DL(Op); 1462 SDValue ChainIn = Op->getOperand(0); 1463 SDValue Address = Op->getOperand(2); 1464 SDValue Offset = Op->getOperand(3); 1465 EVT ResTy = Op->getValueType(0); 1466 EVT PtrTy = Address->getValueType(0); 1467 1468 Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset); 1469 1470 return DAG.getLoad(ResTy, DL, ChainIn, Address, MachinePointerInfo(), false, 1471 false, false, 16); 1472} 1473 1474SDValue MipsSETargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op, 1475 SelectionDAG &DAG) const { 1476 unsigned Intr = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue(); 1477 switch (Intr) { 1478 default: 1479 return SDValue(); 1480 case Intrinsic::mips_extp: 1481 return lowerDSPIntr(Op, DAG, MipsISD::EXTP); 1482 case Intrinsic::mips_extpdp: 1483 return lowerDSPIntr(Op, DAG, MipsISD::EXTPDP); 1484 case Intrinsic::mips_extr_w: 1485 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_W); 1486 case Intrinsic::mips_extr_r_w: 1487 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_R_W); 1488 case Intrinsic::mips_extr_rs_w: 1489 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_RS_W); 1490 case Intrinsic::mips_extr_s_h: 1491 return lowerDSPIntr(Op, DAG, MipsISD::EXTR_S_H); 1492 case Intrinsic::mips_mthlip: 1493 return lowerDSPIntr(Op, DAG, MipsISD::MTHLIP); 1494 case Intrinsic::mips_mulsaq_s_w_ph: 1495 return lowerDSPIntr(Op, DAG, MipsISD::MULSAQ_S_W_PH); 1496 case Intrinsic::mips_maq_s_w_phl: 1497 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHL); 1498 case Intrinsic::mips_maq_s_w_phr: 1499 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_S_W_PHR); 1500 case Intrinsic::mips_maq_sa_w_phl: 1501 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHL); 1502 case Intrinsic::mips_maq_sa_w_phr: 1503 return lowerDSPIntr(Op, DAG, MipsISD::MAQ_SA_W_PHR); 1504 case Intrinsic::mips_dpaq_s_w_ph: 1505 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_S_W_PH); 1506 case Intrinsic::mips_dpsq_s_w_ph: 1507 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_S_W_PH); 1508 case Intrinsic::mips_dpaq_sa_l_w: 1509 return lowerDSPIntr(Op, DAG, MipsISD::DPAQ_SA_L_W); 1510 case Intrinsic::mips_dpsq_sa_l_w: 1511 return lowerDSPIntr(Op, DAG, MipsISD::DPSQ_SA_L_W); 1512 case Intrinsic::mips_dpaqx_s_w_ph: 1513 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_S_W_PH); 1514 case Intrinsic::mips_dpaqx_sa_w_ph: 1515 return lowerDSPIntr(Op, DAG, MipsISD::DPAQX_SA_W_PH); 1516 case Intrinsic::mips_dpsqx_s_w_ph: 1517 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_S_W_PH); 1518 case Intrinsic::mips_dpsqx_sa_w_ph: 1519 return lowerDSPIntr(Op, DAG, MipsISD::DPSQX_SA_W_PH); 1520 case Intrinsic::mips_ld_b: 1521 case Intrinsic::mips_ld_h: 1522 case Intrinsic::mips_ld_w: 1523 case Intrinsic::mips_ld_d: 1524 case Intrinsic::mips_ldx_b: 1525 case Intrinsic::mips_ldx_h: 1526 case Intrinsic::mips_ldx_w: 1527 case Intrinsic::mips_ldx_d: 1528 return lowerMSALoadIntr(Op, DAG, Intr); 1529 } 1530} 1531 1532static SDValue lowerMSAStoreIntr(SDValue Op, SelectionDAG &DAG, unsigned Intr) { 1533 SDLoc DL(Op); 1534 SDValue ChainIn = Op->getOperand(0); 1535 SDValue Value = Op->getOperand(2); 1536 SDValue Address = Op->getOperand(3); 1537 SDValue Offset = Op->getOperand(4); 1538 EVT PtrTy = Address->getValueType(0); 1539 1540 Address = DAG.getNode(ISD::ADD, DL, PtrTy, Address, Offset); 1541 1542 return DAG.getStore(ChainIn, DL, Value, Address, MachinePointerInfo(), false, 1543 false, 16); 1544} 1545 1546SDValue MipsSETargetLowering::lowerINTRINSIC_VOID(SDValue Op, 1547 SelectionDAG &DAG) const { 1548 unsigned Intr = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue(); 1549 switch (Intr) { 1550 default: 1551 return SDValue(); 1552 case Intrinsic::mips_st_b: 1553 case Intrinsic::mips_st_h: 1554 case Intrinsic::mips_st_w: 1555 case Intrinsic::mips_st_d: 1556 case Intrinsic::mips_stx_b: 1557 case Intrinsic::mips_stx_h: 1558 case Intrinsic::mips_stx_w: 1559 case Intrinsic::mips_stx_d: 1560 return lowerMSAStoreIntr(Op, DAG, Intr); 1561 } 1562} 1563 1564/// \brief Check if the given BuildVectorSDNode is a splat. 1565/// This method currently relies on DAG nodes being reused when equivalent, 1566/// so it's possible for this to return false even when isConstantSplat returns 1567/// true. 1568static bool isSplatVector(const BuildVectorSDNode *N) { 1569 unsigned int nOps = N->getNumOperands(); 1570 assert(nOps > 1 && "isSplat has 0 or 1 sized build vector"); 1571 1572 SDValue Operand0 = N->getOperand(0); 1573 1574 for (unsigned int i = 1; i < nOps; ++i) { 1575 if (N->getOperand(i) != Operand0) 1576 return false; 1577 } 1578 1579 return true; 1580} 1581 1582// Lower ISD::EXTRACT_VECTOR_ELT into MipsISD::VEXTRACT_SEXT_ELT. 1583// 1584// The non-value bits resulting from ISD::EXTRACT_VECTOR_ELT are undefined. We 1585// choose to sign-extend but we could have equally chosen zero-extend. The 1586// DAGCombiner will fold any sign/zero extension of the ISD::EXTRACT_VECTOR_ELT 1587// result into this node later (possibly changing it to a zero-extend in the 1588// process). 1589SDValue MipsSETargetLowering:: 1590lowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const { 1591 SDLoc DL(Op); 1592 EVT ResTy = Op->getValueType(0); 1593 SDValue Op0 = Op->getOperand(0); 1594 SDValue Op1 = Op->getOperand(1); 1595 EVT EltTy = Op0->getValueType(0).getVectorElementType(); 1596 return DAG.getNode(MipsISD::VEXTRACT_SEXT_ELT, DL, ResTy, Op0, Op1, 1597 DAG.getValueType(EltTy)); 1598} 1599 1600// Lowers ISD::BUILD_VECTOR into appropriate SelectionDAG nodes for the 1601// backend. 1602// 1603// Lowers according to the following rules: 1604// - Vectors of 128-bits may be legal subject to the other rules. Other sizes 1605// are not legal. 1606// - Non-constant splats are legal and are lowered to MipsISD::VSPLAT. 1607// - Constant splats with an element size of 32-bits or less are legal and are 1608// lowered to MipsISD::VSPLAT. 1609// - Constant splats with an element size of 64-bits but whose value would fit 1610// within a 10 bit immediate are legal and are lowered to MipsISD::VSPLATD. 1611// - All other ISD::BUILD_VECTORS are not legal 1612SDValue MipsSETargetLowering::lowerBUILD_VECTOR(SDValue Op, 1613 SelectionDAG &DAG) const { 1614 BuildVectorSDNode *Node = cast<BuildVectorSDNode>(Op); 1615 EVT ResTy = Op->getValueType(0); 1616 SDLoc DL(Op); 1617 APInt SplatValue, SplatUndef; 1618 unsigned SplatBitSize; 1619 bool HasAnyUndefs; 1620 1621 if (!Subtarget->hasMSA() || !ResTy.is128BitVector()) 1622 return SDValue(); 1623 1624 if (Node->isConstantSplat(SplatValue, SplatUndef, SplatBitSize, 1625 HasAnyUndefs, 8, 1626 !Subtarget->isLittle())) { 1627 SDValue Result; 1628 EVT TmpVecTy; 1629 EVT ConstTy = MVT::i32; 1630 unsigned SplatOp = MipsISD::VSPLAT; 1631 1632 switch (SplatBitSize) { 1633 default: 1634 return SDValue(); 1635 case 64: 1636 TmpVecTy = MVT::v2i64; 1637 1638 // i64 is an illegal type on Mips32, but if it the constant fits into a 1639 // signed 10-bit value then we can still handle it using VSPLATD and an 1640 // i32 constant 1641 if (HasMips64) 1642 ConstTy = MVT::i64; 1643 else if (isInt<10>(SplatValue.getSExtValue())) { 1644 SplatValue = SplatValue.trunc(32); 1645 SplatOp = MipsISD::VSPLATD; 1646 } else 1647 return SDValue(); 1648 break; 1649 case 32: 1650 TmpVecTy = MVT::v4i32; 1651 break; 1652 case 16: 1653 TmpVecTy = MVT::v8i16; 1654 SplatValue = SplatValue.sext(32); 1655 break; 1656 case 8: 1657 TmpVecTy = MVT::v16i8; 1658 SplatValue = SplatValue.sext(32); 1659 break; 1660 } 1661 1662 Result = DAG.getNode(SplatOp, DL, TmpVecTy, 1663 DAG.getConstant(SplatValue, ConstTy)); 1664 if (ResTy != Result.getValueType()) 1665 Result = DAG.getNode(ISD::BITCAST, DL, ResTy, Result); 1666 1667 return Result; 1668 } 1669 else if (isSplatVector(Node)) 1670 return DAG.getNode(MipsISD::VSPLAT, DL, ResTy, Op->getOperand(0)); 1671 else { 1672 // Use INSERT_VECTOR_ELT operations rather than expand to stores. 1673 // The resulting code is the same length as the expansion, but it doesn't 1674 // use memory operations 1675 EVT ResTy = Node->getValueType(0); 1676 1677 assert(ResTy.isVector()); 1678 1679 unsigned NumElts = ResTy.getVectorNumElements(); 1680 SDValue Vector = DAG.getUNDEF(ResTy); 1681 for (unsigned i = 0; i < NumElts; ++i) { 1682 Vector = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, ResTy, Vector, 1683 Node->getOperand(i), 1684 DAG.getConstant(i, MVT::i32)); 1685 } 1686 return Vector; 1687 } 1688 1689 return SDValue(); 1690} 1691 1692MachineBasicBlock * MipsSETargetLowering:: 1693emitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{ 1694 // $bb: 1695 // bposge32_pseudo $vr0 1696 // => 1697 // $bb: 1698 // bposge32 $tbb 1699 // $fbb: 1700 // li $vr2, 0 1701 // b $sink 1702 // $tbb: 1703 // li $vr1, 1 1704 // $sink: 1705 // $vr0 = phi($vr2, $fbb, $vr1, $tbb) 1706 1707 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); 1708 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); 1709 const TargetRegisterClass *RC = &Mips::GPR32RegClass; 1710 DebugLoc DL = MI->getDebugLoc(); 1711 const BasicBlock *LLVM_BB = BB->getBasicBlock(); 1712 MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB)); 1713 MachineFunction *F = BB->getParent(); 1714 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB); 1715 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB); 1716 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB); 1717 F->insert(It, FBB); 1718 F->insert(It, TBB); 1719 F->insert(It, Sink); 1720 1721 // Transfer the remainder of BB and its successor edges to Sink. 1722 Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)), 1723 BB->end()); 1724 Sink->transferSuccessorsAndUpdatePHIs(BB); 1725 1726 // Add successors. 1727 BB->addSuccessor(FBB); 1728 BB->addSuccessor(TBB); 1729 FBB->addSuccessor(Sink); 1730 TBB->addSuccessor(Sink); 1731 1732 // Insert the real bposge32 instruction to $BB. 1733 BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB); 1734 1735 // Fill $FBB. 1736 unsigned VR2 = RegInfo.createVirtualRegister(RC); 1737 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), VR2) 1738 .addReg(Mips::ZERO).addImm(0); 1739 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink); 1740 1741 // Fill $TBB. 1742 unsigned VR1 = RegInfo.createVirtualRegister(RC); 1743 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1) 1744 .addReg(Mips::ZERO).addImm(1); 1745 1746 // Insert phi function to $Sink. 1747 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI), 1748 MI->getOperand(0).getReg()) 1749 .addReg(VR2).addMBB(FBB).addReg(VR1).addMBB(TBB); 1750 1751 MI->eraseFromParent(); // The pseudo instruction is gone now. 1752 return Sink; 1753} 1754 1755MachineBasicBlock * MipsSETargetLowering:: 1756emitMSACBranchPseudo(MachineInstr *MI, MachineBasicBlock *BB, 1757 unsigned BranchOp) const{ 1758 // $bb: 1759 // vany_nonzero $rd, $ws 1760 // => 1761 // $bb: 1762 // bnz.b $ws, $tbb 1763 // b $fbb 1764 // $fbb: 1765 // li $rd1, 0 1766 // b $sink 1767 // $tbb: 1768 // li $rd2, 1 1769 // $sink: 1770 // $rd = phi($rd1, $fbb, $rd2, $tbb) 1771 1772 MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo(); 1773 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); 1774 const TargetRegisterClass *RC = &Mips::GPR32RegClass; 1775 DebugLoc DL = MI->getDebugLoc(); 1776 const BasicBlock *LLVM_BB = BB->getBasicBlock(); 1777 MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB)); 1778 MachineFunction *F = BB->getParent(); 1779 MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB); 1780 MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB); 1781 MachineBasicBlock *Sink = F->CreateMachineBasicBlock(LLVM_BB); 1782 F->insert(It, FBB); 1783 F->insert(It, TBB); 1784 F->insert(It, Sink); 1785 1786 // Transfer the remainder of BB and its successor edges to Sink. 1787 Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)), 1788 BB->end()); 1789 Sink->transferSuccessorsAndUpdatePHIs(BB); 1790 1791 // Add successors. 1792 BB->addSuccessor(FBB); 1793 BB->addSuccessor(TBB); 1794 FBB->addSuccessor(Sink); 1795 TBB->addSuccessor(Sink); 1796 1797 // Insert the real bnz.b instruction to $BB. 1798 BuildMI(BB, DL, TII->get(BranchOp)) 1799 .addReg(MI->getOperand(1).getReg()) 1800 .addMBB(TBB); 1801 1802 // Fill $FBB. 1803 unsigned RD1 = RegInfo.createVirtualRegister(RC); 1804 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), RD1) 1805 .addReg(Mips::ZERO).addImm(0); 1806 BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink); 1807 1808 // Fill $TBB. 1809 unsigned RD2 = RegInfo.createVirtualRegister(RC); 1810 BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), RD2) 1811 .addReg(Mips::ZERO).addImm(1); 1812 1813 // Insert phi function to $Sink. 1814 BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI), 1815 MI->getOperand(0).getReg()) 1816 .addReg(RD1).addMBB(FBB).addReg(RD2).addMBB(TBB); 1817 1818 MI->eraseFromParent(); // The pseudo instruction is gone now. 1819 return Sink; 1820} 1821