mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-03 01:12:59 +00:00
Factor out target shuffle mask decoding from getShuffleScalarElt and use a SmallVector of int instead of unsigned for shuffle mask in decode functions. Preparation for another change.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153079 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0c9da210f7
commit
a1ffc681ed
@ -29,7 +29,7 @@ using namespace llvm;
|
||||
void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS,
|
||||
const char *(*getRegName)(unsigned)) {
|
||||
// If this is a shuffle operation, the switch should fill in this state.
|
||||
SmallVector<unsigned, 8> ShuffleMask;
|
||||
SmallVector<int, 8> ShuffleMask;
|
||||
const char *DestName = 0, *Src1Name = 0, *Src2Name = 0;
|
||||
|
||||
switch (MI->getOpcode()) {
|
||||
@ -500,7 +500,7 @@ void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS,
|
||||
if (Src1Name == Src2Name) {
|
||||
for (unsigned i = 0, e = ShuffleMask.size(); i != e; ++i) {
|
||||
if ((int)ShuffleMask[i] >= 0 && // Not sentinel.
|
||||
ShuffleMask[i] >= e) // From second mask.
|
||||
ShuffleMask[i] >= (int)e) // From second mask.
|
||||
ShuffleMask[i] -= e;
|
||||
}
|
||||
}
|
||||
@ -511,20 +511,20 @@ void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS,
|
||||
for (unsigned i = 0, e = ShuffleMask.size(); i != e; ++i) {
|
||||
if (i != 0)
|
||||
OS << ',';
|
||||
if (ShuffleMask[i] == SM_SentinelZero) {
|
||||
if (ShuffleMask[i] == (int)SM_SentinelZero) {
|
||||
OS << "zero";
|
||||
continue;
|
||||
}
|
||||
|
||||
// Otherwise, it must come from src1 or src2. Print the span of elements
|
||||
// that comes from this src.
|
||||
bool isSrc1 = ShuffleMask[i] < ShuffleMask.size();
|
||||
bool isSrc1 = ShuffleMask[i] < (int)ShuffleMask.size();
|
||||
const char *SrcName = isSrc1 ? Src1Name : Src2Name;
|
||||
OS << (SrcName ? SrcName : "mem") << '[';
|
||||
bool IsFirst = true;
|
||||
while (i != e &&
|
||||
(int)ShuffleMask[i] >= 0 &&
|
||||
(ShuffleMask[i] < ShuffleMask.size()) == isSrc1) {
|
||||
(ShuffleMask[i] < (int)ShuffleMask.size()) == isSrc1) {
|
||||
if (!IsFirst)
|
||||
OS << ',';
|
||||
else
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
void DecodeINSERTPSMask(unsigned Imm, SmallVectorImpl<unsigned> &ShuffleMask) {
|
||||
void DecodeINSERTPSMask(unsigned Imm, SmallVectorImpl<int> &ShuffleMask) {
|
||||
// Defaults the copying the dest value.
|
||||
ShuffleMask.push_back(0);
|
||||
ShuffleMask.push_back(1);
|
||||
@ -44,8 +44,7 @@ void DecodeINSERTPSMask(unsigned Imm, SmallVectorImpl<unsigned> &ShuffleMask) {
|
||||
}
|
||||
|
||||
// <3,1> or <6,7,2,3>
|
||||
void DecodeMOVHLPSMask(unsigned NElts,
|
||||
SmallVectorImpl<unsigned> &ShuffleMask) {
|
||||
void DecodeMOVHLPSMask(unsigned NElts, SmallVectorImpl<int> &ShuffleMask) {
|
||||
for (unsigned i = NElts/2; i != NElts; ++i)
|
||||
ShuffleMask.push_back(NElts+i);
|
||||
|
||||
@ -54,8 +53,7 @@ void DecodeMOVHLPSMask(unsigned NElts,
|
||||
}
|
||||
|
||||
// <0,2> or <0,1,4,5>
|
||||
void DecodeMOVLHPSMask(unsigned NElts,
|
||||
SmallVectorImpl<unsigned> &ShuffleMask) {
|
||||
void DecodeMOVLHPSMask(unsigned NElts, SmallVectorImpl<int> &ShuffleMask) {
|
||||
for (unsigned i = 0; i != NElts/2; ++i)
|
||||
ShuffleMask.push_back(i);
|
||||
|
||||
@ -66,8 +64,7 @@ void DecodeMOVLHPSMask(unsigned NElts,
|
||||
/// DecodePSHUFMask - This decodes the shuffle masks for pshufd, and vpermilp*.
|
||||
/// VT indicates the type of the vector allowing it to handle different
|
||||
/// datatypes and vector widths.
|
||||
void DecodePSHUFMask(EVT VT, unsigned Imm,
|
||||
SmallVectorImpl<unsigned> &ShuffleMask) {
|
||||
void DecodePSHUFMask(EVT VT, unsigned Imm, SmallVectorImpl<int> &ShuffleMask) {
|
||||
unsigned NumElts = VT.getVectorNumElements();
|
||||
|
||||
unsigned NumLanes = VT.getSizeInBits() / 128;
|
||||
@ -83,8 +80,7 @@ void DecodePSHUFMask(EVT VT, unsigned Imm,
|
||||
}
|
||||
}
|
||||
|
||||
void DecodePSHUFHWMask(unsigned Imm,
|
||||
SmallVectorImpl<unsigned> &ShuffleMask) {
|
||||
void DecodePSHUFHWMask(unsigned Imm, SmallVectorImpl<int> &ShuffleMask) {
|
||||
ShuffleMask.push_back(0);
|
||||
ShuffleMask.push_back(1);
|
||||
ShuffleMask.push_back(2);
|
||||
@ -95,8 +91,7 @@ void DecodePSHUFHWMask(unsigned Imm,
|
||||
}
|
||||
}
|
||||
|
||||
void DecodePSHUFLWMask(unsigned Imm,
|
||||
SmallVectorImpl<unsigned> &ShuffleMask) {
|
||||
void DecodePSHUFLWMask(unsigned Imm, SmallVectorImpl<int> &ShuffleMask) {
|
||||
for (unsigned i = 0; i != 4; ++i) {
|
||||
ShuffleMask.push_back((Imm & 3));
|
||||
Imm >>= 2;
|
||||
@ -110,8 +105,7 @@ void DecodePSHUFLWMask(unsigned Imm,
|
||||
/// DecodeSHUFPMask - This decodes the shuffle masks for shufp*. VT indicates
|
||||
/// the type of the vector allowing it to handle different datatypes and vector
|
||||
/// widths.
|
||||
void DecodeSHUFPMask(EVT VT, unsigned Imm,
|
||||
SmallVectorImpl<unsigned> &ShuffleMask) {
|
||||
void DecodeSHUFPMask(EVT VT, unsigned Imm, SmallVectorImpl<int> &ShuffleMask) {
|
||||
unsigned NumElts = VT.getVectorNumElements();
|
||||
|
||||
unsigned NumLanes = VT.getSizeInBits() / 128;
|
||||
@ -136,7 +130,7 @@ void DecodeSHUFPMask(EVT VT, unsigned Imm,
|
||||
/// DecodeUNPCKHMask - This decodes the shuffle masks for unpckhps/unpckhpd
|
||||
/// and punpckh*. VT indicates the type of the vector allowing it to handle
|
||||
/// different datatypes and vector widths.
|
||||
void DecodeUNPCKHMask(EVT VT, SmallVectorImpl<unsigned> &ShuffleMask) {
|
||||
void DecodeUNPCKHMask(EVT VT, SmallVectorImpl<int> &ShuffleMask) {
|
||||
unsigned NumElts = VT.getVectorNumElements();
|
||||
|
||||
// Handle 128 and 256-bit vector lengths. AVX defines UNPCK* to operate
|
||||
@ -156,7 +150,7 @@ void DecodeUNPCKHMask(EVT VT, SmallVectorImpl<unsigned> &ShuffleMask) {
|
||||
/// DecodeUNPCKLMask - This decodes the shuffle masks for unpcklps/unpcklpd
|
||||
/// and punpckl*. VT indicates the type of the vector allowing it to handle
|
||||
/// different datatypes and vector widths.
|
||||
void DecodeUNPCKLMask(EVT VT, SmallVectorImpl<unsigned> &ShuffleMask) {
|
||||
void DecodeUNPCKLMask(EVT VT, SmallVectorImpl<int> &ShuffleMask) {
|
||||
unsigned NumElts = VT.getVectorNumElements();
|
||||
|
||||
// Handle 128 and 256-bit vector lengths. AVX defines UNPCK* to operate
|
||||
@ -174,7 +168,7 @@ void DecodeUNPCKLMask(EVT VT, SmallVectorImpl<unsigned> &ShuffleMask) {
|
||||
}
|
||||
|
||||
void DecodeVPERM2X128Mask(EVT VT, unsigned Imm,
|
||||
SmallVectorImpl<unsigned> &ShuffleMask) {
|
||||
SmallVectorImpl<int> &ShuffleMask) {
|
||||
unsigned HalfSize = VT.getVectorNumElements()/2;
|
||||
unsigned FstHalfBegin = (Imm & 0x3) * HalfSize;
|
||||
unsigned SndHalfBegin = ((Imm >> 4) & 0x3) * HalfSize;
|
||||
|
@ -27,44 +27,38 @@ enum {
|
||||
SM_SentinelZero = ~0U
|
||||
};
|
||||
|
||||
void DecodeINSERTPSMask(unsigned Imm, SmallVectorImpl<unsigned> &ShuffleMask);
|
||||
void DecodeINSERTPSMask(unsigned Imm, SmallVectorImpl<int> &ShuffleMask);
|
||||
|
||||
// <3,1> or <6,7,2,3>
|
||||
void DecodeMOVHLPSMask(unsigned NElts,
|
||||
SmallVectorImpl<unsigned> &ShuffleMask);
|
||||
void DecodeMOVHLPSMask(unsigned NElts, SmallVectorImpl<int> &ShuffleMask);
|
||||
|
||||
// <0,2> or <0,1,4,5>
|
||||
void DecodeMOVLHPSMask(unsigned NElts,
|
||||
SmallVectorImpl<unsigned> &ShuffleMask);
|
||||
void DecodeMOVLHPSMask(unsigned NElts, SmallVectorImpl<int> &ShuffleMask);
|
||||
|
||||
void DecodePSHUFMask(EVT VT, unsigned Imm,
|
||||
SmallVectorImpl<unsigned> &ShuffleMask);
|
||||
void DecodePSHUFMask(EVT VT, unsigned Imm, SmallVectorImpl<int> &ShuffleMask);
|
||||
|
||||
void DecodePSHUFHWMask(unsigned Imm,
|
||||
SmallVectorImpl<unsigned> &ShuffleMask);
|
||||
void DecodePSHUFHWMask(unsigned Imm, SmallVectorImpl<int> &ShuffleMask);
|
||||
|
||||
void DecodePSHUFLWMask(unsigned Imm,
|
||||
SmallVectorImpl<unsigned> &ShuffleMask);
|
||||
void DecodePSHUFLWMask(unsigned Imm, SmallVectorImpl<int> &ShuffleMask);
|
||||
|
||||
/// DecodeSHUFPMask - This decodes the shuffle masks for shufp*. VT indicates
|
||||
/// the type of the vector allowing it to handle different datatypes and vector
|
||||
/// widths.
|
||||
void DecodeSHUFPMask(EVT VT, unsigned Imm,
|
||||
SmallVectorImpl<unsigned> &ShuffleMask);
|
||||
void DecodeSHUFPMask(EVT VT, unsigned Imm, SmallVectorImpl<int> &ShuffleMask);
|
||||
|
||||
/// DecodeUNPCKHMask - This decodes the shuffle masks for unpckhps/unpckhpd
|
||||
/// and punpckh*. VT indicates the type of the vector allowing it to handle
|
||||
/// different datatypes and vector widths.
|
||||
void DecodeUNPCKHMask(EVT VT, SmallVectorImpl<unsigned> &ShuffleMask);
|
||||
void DecodeUNPCKHMask(EVT VT, SmallVectorImpl<int> &ShuffleMask);
|
||||
|
||||
/// DecodeUNPCKLMask - This decodes the shuffle masks for unpcklps/unpcklpd
|
||||
/// and punpckl*. VT indicates the type of the vector allowing it to handle
|
||||
/// different datatypes and vector widths.
|
||||
void DecodeUNPCKLMask(EVT VT, SmallVectorImpl<unsigned> &ShuffleMask);
|
||||
void DecodeUNPCKLMask(EVT VT, SmallVectorImpl<int> &ShuffleMask);
|
||||
|
||||
|
||||
void DecodeVPERM2X128Mask(EVT VT, unsigned Imm,
|
||||
SmallVectorImpl<unsigned> &ShuffleMask);
|
||||
SmallVectorImpl<int> &ShuffleMask);
|
||||
|
||||
} // llvm namespace
|
||||
|
||||
|
@ -4344,6 +4344,73 @@ static SDValue getShuffleVectorZeroOrUndef(SDValue V2, unsigned Idx,
|
||||
return DAG.getVectorShuffle(VT, V2.getDebugLoc(), V1, V2, &MaskVec[0]);
|
||||
}
|
||||
|
||||
/// getTargetShuffleMask - Calculates the shuffle mask corresponding to the
|
||||
/// target specific opcode. Returns true if the Mask could be calculated.
|
||||
static bool getTargetShuffleMask(SDNode *N, EVT VT,
|
||||
SmallVectorImpl<int> &Mask) {
|
||||
unsigned NumElems = VT.getVectorNumElements();
|
||||
SDValue ImmN;
|
||||
|
||||
switch(N->getOpcode()) {
|
||||
case X86ISD::SHUFP:
|
||||
ImmN = N->getOperand(N->getNumOperands()-1);
|
||||
DecodeSHUFPMask(VT, cast<ConstantSDNode>(ImmN)->getZExtValue(), Mask);
|
||||
break;
|
||||
case X86ISD::UNPCKH:
|
||||
DecodeUNPCKHMask(VT, Mask);
|
||||
break;
|
||||
case X86ISD::UNPCKL:
|
||||
DecodeUNPCKLMask(VT, Mask);
|
||||
break;
|
||||
case X86ISD::MOVHLPS:
|
||||
DecodeMOVHLPSMask(NumElems, Mask);
|
||||
break;
|
||||
case X86ISD::MOVLHPS:
|
||||
DecodeMOVLHPSMask(NumElems, Mask);
|
||||
break;
|
||||
case X86ISD::PSHUFD:
|
||||
case X86ISD::VPERMILP:
|
||||
ImmN = N->getOperand(N->getNumOperands()-1);
|
||||
DecodePSHUFMask(VT, cast<ConstantSDNode>(ImmN)->getZExtValue(), Mask);
|
||||
break;
|
||||
case X86ISD::PSHUFHW:
|
||||
ImmN = N->getOperand(N->getNumOperands()-1);
|
||||
DecodePSHUFHWMask(cast<ConstantSDNode>(ImmN)->getZExtValue(), Mask);
|
||||
break;
|
||||
case X86ISD::PSHUFLW:
|
||||
ImmN = N->getOperand(N->getNumOperands()-1);
|
||||
DecodePSHUFLWMask(cast<ConstantSDNode>(ImmN)->getZExtValue(), Mask);
|
||||
break;
|
||||
case X86ISD::MOVSS:
|
||||
case X86ISD::MOVSD: {
|
||||
// The index 0 always comes from the first element of the second source,
|
||||
// this is why MOVSS and MOVSD are used in the first place. The other
|
||||
// elements come from the other positions of the first source vector
|
||||
Mask.push_back(NumElems);
|
||||
for (unsigned i = 1; i != NumElems; ++i) {
|
||||
Mask.push_back(i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case X86ISD::VPERM2X128:
|
||||
ImmN = N->getOperand(N->getNumOperands()-1);
|
||||
DecodeVPERM2X128Mask(VT, cast<ConstantSDNode>(ImmN)->getZExtValue(), Mask);
|
||||
break;
|
||||
case X86ISD::MOVDDUP:
|
||||
case X86ISD::MOVLHPD:
|
||||
case X86ISD::MOVLPD:
|
||||
case X86ISD::MOVLPS:
|
||||
case X86ISD::MOVSHDUP:
|
||||
case X86ISD::MOVSLDUP:
|
||||
case X86ISD::PALIGN:
|
||||
// Not yet implemented
|
||||
return false;
|
||||
default: llvm_unreachable("unknown target shuffle node");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// getShuffleScalarElt - Returns the scalar element that will make up the ith
|
||||
/// element of the result of the vector shuffle.
|
||||
static SDValue getShuffleScalarElt(SDNode *N, int Index, SelectionDAG &DAG,
|
||||
@ -4371,67 +4438,11 @@ static SDValue getShuffleScalarElt(SDNode *N, int Index, SelectionDAG &DAG,
|
||||
// Recurse into target specific vector shuffles to find scalars.
|
||||
if (isTargetShuffle(Opcode)) {
|
||||
unsigned NumElems = VT.getVectorNumElements();
|
||||
SmallVector<unsigned, 16> ShuffleMask;
|
||||
SmallVector<int, 16> ShuffleMask;
|
||||
SDValue ImmN;
|
||||
|
||||
switch(Opcode) {
|
||||
case X86ISD::SHUFP:
|
||||
ImmN = N->getOperand(N->getNumOperands()-1);
|
||||
DecodeSHUFPMask(VT, cast<ConstantSDNode>(ImmN)->getZExtValue(),
|
||||
ShuffleMask);
|
||||
break;
|
||||
case X86ISD::UNPCKH:
|
||||
DecodeUNPCKHMask(VT, ShuffleMask);
|
||||
break;
|
||||
case X86ISD::UNPCKL:
|
||||
DecodeUNPCKLMask(VT, ShuffleMask);
|
||||
break;
|
||||
case X86ISD::MOVHLPS:
|
||||
DecodeMOVHLPSMask(NumElems, ShuffleMask);
|
||||
break;
|
||||
case X86ISD::MOVLHPS:
|
||||
DecodeMOVLHPSMask(NumElems, ShuffleMask);
|
||||
break;
|
||||
case X86ISD::PSHUFD:
|
||||
case X86ISD::VPERMILP:
|
||||
ImmN = N->getOperand(N->getNumOperands()-1);
|
||||
DecodePSHUFMask(VT, cast<ConstantSDNode>(ImmN)->getZExtValue(),
|
||||
ShuffleMask);
|
||||
break;
|
||||
case X86ISD::PSHUFHW:
|
||||
ImmN = N->getOperand(N->getNumOperands()-1);
|
||||
DecodePSHUFHWMask(cast<ConstantSDNode>(ImmN)->getZExtValue(),
|
||||
ShuffleMask);
|
||||
break;
|
||||
case X86ISD::PSHUFLW:
|
||||
ImmN = N->getOperand(N->getNumOperands()-1);
|
||||
DecodePSHUFLWMask(cast<ConstantSDNode>(ImmN)->getZExtValue(),
|
||||
ShuffleMask);
|
||||
break;
|
||||
case X86ISD::MOVSS:
|
||||
case X86ISD::MOVSD: {
|
||||
// The index 0 always comes from the first element of the second source,
|
||||
// this is why MOVSS and MOVSD are used in the first place. The other
|
||||
// elements come from the other positions of the first source vector.
|
||||
unsigned OpNum = (Index == 0) ? 1 : 0;
|
||||
return getShuffleScalarElt(V.getOperand(OpNum).getNode(), Index, DAG,
|
||||
Depth+1);
|
||||
}
|
||||
case X86ISD::VPERM2X128:
|
||||
ImmN = N->getOperand(N->getNumOperands()-1);
|
||||
DecodeVPERM2X128Mask(VT, cast<ConstantSDNode>(ImmN)->getZExtValue(),
|
||||
ShuffleMask);
|
||||
break;
|
||||
case X86ISD::MOVDDUP:
|
||||
case X86ISD::MOVLHPD:
|
||||
case X86ISD::MOVLPD:
|
||||
case X86ISD::MOVLPS:
|
||||
case X86ISD::MOVSHDUP:
|
||||
case X86ISD::MOVSLDUP:
|
||||
case X86ISD::PALIGN:
|
||||
return SDValue(); // Not yet implemented.
|
||||
default: llvm_unreachable("unknown target shuffle node");
|
||||
}
|
||||
if (!getTargetShuffleMask(N, VT, ShuffleMask))
|
||||
return SDValue();
|
||||
|
||||
Index = ShuffleMask[Index];
|
||||
if (Index < 0)
|
||||
|
Loading…
Reference in New Issue
Block a user