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