diff options
Diffstat (limited to 'lib/Target/PowerPC/PPCISelLowering.cpp')
| -rw-r--r-- | lib/Target/PowerPC/PPCISelLowering.cpp | 92 | 
1 files changed, 89 insertions, 3 deletions
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index e65b1f1aa0a5..b90a5ee28342 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -1596,9 +1596,8 @@ bool PPC::isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize) {    return true;  } -bool PPC::isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, -                          unsigned &InsertAtByte, bool &Swap, bool IsLE) {    // Check that the mask is shuffling words +static bool isWordShuffleMask(ShuffleVectorSDNode *N) {    for (unsigned i = 0; i < 4; ++i) {      unsigned B0 = N->getMaskElt(i*4);      unsigned B1 = N->getMaskElt(i*4+1); @@ -1610,6 +1609,14 @@ bool PPC::isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts,        return false;    } +  return true; +} + +bool PPC::isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, +                          unsigned &InsertAtByte, bool &Swap, bool IsLE) { +  if (!isWordShuffleMask(N)) +    return false; +    // Now we look at mask elements 0,4,8,12    unsigned M0 = N->getMaskElt(0) / 4;    unsigned M1 = N->getMaskElt(4) / 4; @@ -1680,6 +1687,69 @@ bool PPC::isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts,    return false;  } +bool PPC::isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, +                               bool &Swap, bool IsLE) { +  assert(N->getValueType(0) == MVT::v16i8 && "Shuffle vector expects v16i8"); +  // Ensure each byte index of the word is consecutive. +  if (!isWordShuffleMask(N)) +    return false; + +  // Now we look at mask elements 0,4,8,12, which are the beginning of words. +  unsigned M0 = N->getMaskElt(0) / 4; +  unsigned M1 = N->getMaskElt(4) / 4; +  unsigned M2 = N->getMaskElt(8) / 4; +  unsigned M3 = N->getMaskElt(12) / 4; + +  // If both vector operands for the shuffle are the same vector, the mask will +  // contain only elements from the first one and the second one will be undef. +  if (N->getOperand(1).isUndef()) { +    assert(M0 < 4 && "Indexing into an undef vector?"); +    if (M1 != (M0 + 1) % 4 || M2 != (M1 + 1) % 4 || M3 != (M2 + 1) % 4) +      return false; + +    ShiftElts = IsLE ? (4 - M0) % 4 : M0; +    Swap = false; +    return true; +  } + +  // Ensure each word index of the ShuffleVector Mask is consecutive. +  if (M1 != (M0 + 1) % 8 || M2 != (M1 + 1) % 8 || M3 != (M2 + 1) % 8) +    return false; + +  if (IsLE) { +    if (M0 == 0 || M0 == 7 || M0 == 6 || M0 == 5) { +      // Input vectors don't need to be swapped if the leading element +      // of the result is one of the 3 left elements of the second vector +      // (or if there is no shift to be done at all). +      Swap = false; +      ShiftElts = (8 - M0) % 8; +    } else if (M0 == 4 || M0 == 3 || M0 == 2 || M0 == 1) { +      // Input vectors need to be swapped if the leading element +      // of the result is one of the 3 left elements of the first vector +      // (or if we're shifting by 4 - thereby simply swapping the vectors). +      Swap = true; +      ShiftElts = (4 - M0) % 4; +    } + +    return true; +  } else {                                          // BE +    if (M0 == 0 || M0 == 1 || M0 == 2 || M0 == 3) { +      // Input vectors don't need to be swapped if the leading element +      // of the result is one of the 4 elements of the first vector. +      Swap = false; +      ShiftElts = M0; +    } else if (M0 == 4 || M0 == 5 || M0 == 6 || M0 == 7) { +      // Input vectors need to be swapped if the leading element +      // of the result is one of the 4 elements of the right vector. +      Swap = true; +      ShiftElts = M0 - 4; +    } + +    return true; +  } +} + +  /// getVSPLTImmediate - Return the appropriate VSPLT* immediate to splat the  /// specified isSplatShuffleMask VECTOR_SHUFFLE mask.  unsigned PPC::getVSPLTImmediate(SDNode *N, unsigned EltSize, @@ -7679,6 +7749,20 @@ SDValue PPCTargetLowering::LowerVECTOR_SHUFFLE(SDValue Op,      return DAG.getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);    } + +  if (Subtarget.hasVSX() && +      PPC::isXXSLDWIShuffleMask(SVOp, ShiftElts, Swap, isLittleEndian)) { +    if (Swap) +      std::swap(V1, V2); +    SDValue Conv1 = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, V1); +    SDValue Conv2 = +        DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, V2.isUndef() ? V1 : V2); + +    SDValue Shl = DAG.getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv1, Conv2, +                              DAG.getConstant(ShiftElts, dl, MVT::i32)); +    return DAG.getNode(ISD::BITCAST, dl, MVT::v16i8, Shl); +  } +    if (Subtarget.hasVSX()) {      if (V2.isUndef() && PPC::isSplatShuffleMask(SVOp, 4)) {        int SplatIdx = PPC::getVSPLTImmediate(SVOp, 4, DAG); @@ -8212,10 +8296,12 @@ SDValue PPCTargetLowering::LowerINTRINSIC_VOID(SDValue Op,    SDLoc DL(Op);    switch (cast<ConstantSDNode>(Op.getOperand(ArgStart))->getZExtValue()) {    case Intrinsic::ppc_cfence: { +    assert(ArgStart == 1 && "llvm.ppc.cfence must carry a chain argument.");      assert(Subtarget.isPPC64() && "Only 64-bit is supported for now.");      return SDValue(DAG.getMachineNode(PPC::CFENCE8, DL, MVT::Other,                                        DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, -                                                  Op.getOperand(ArgStart + 1))), +                                                  Op.getOperand(ArgStart + 1)), +                                      Op.getOperand(0)),                     0);    }    default:  | 
