Add shuffle decoding support for 256-bit pshufd. Merge vpermilp* and pshufd decoding.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149859 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Craig Topper 2012-02-06 07:17:51 +00:00
parent 1230ad6e8c
commit d156dc11f9
4 changed files with 70 additions and 84 deletions

View File

@ -76,10 +76,19 @@ void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS,
case X86::PSHUFDmi: case X86::PSHUFDmi:
case X86::VPSHUFDmi: case X86::VPSHUFDmi:
DestName = getRegName(MI->getOperand(0).getReg()); DestName = getRegName(MI->getOperand(0).getReg());
DecodePSHUFMask(4, MI->getOperand(MI->getNumOperands()-1).getImm(), DecodePSHUFMask(MVT::v4i32, MI->getOperand(MI->getNumOperands()-1).getImm(),
ShuffleMask);
break;
case X86::VPSHUFDYri:
Src1Name = getRegName(MI->getOperand(1).getReg());
// FALL THROUGH.
case X86::VPSHUFDYmi:
DestName = getRegName(MI->getOperand(0).getReg());
DecodePSHUFMask(MVT::v8i32, MI->getOperand(MI->getNumOperands()-1).getImm(),
ShuffleMask); ShuffleMask);
break; break;
case X86::PSHUFHWri: case X86::PSHUFHWri:
case X86::VPSHUFHWri: case X86::VPSHUFHWri:
Src1Name = getRegName(MI->getOperand(1).getReg()); Src1Name = getRegName(MI->getOperand(1).getReg());
@ -437,31 +446,31 @@ void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS,
Src1Name = getRegName(MI->getOperand(1).getReg()); Src1Name = getRegName(MI->getOperand(1).getReg());
// FALL THROUGH. // FALL THROUGH.
case X86::VPERMILPSmi: case X86::VPERMILPSmi:
DecodeVPERMILPMask(MVT::v4f32, MI->getOperand(MI->getNumOperands()-1).getImm(), DecodePSHUFMask(MVT::v4f32, MI->getOperand(MI->getNumOperands()-1).getImm(),
ShuffleMask); ShuffleMask);
DestName = getRegName(MI->getOperand(0).getReg()); DestName = getRegName(MI->getOperand(0).getReg());
break; break;
case X86::VPERMILPSYri: case X86::VPERMILPSYri:
Src1Name = getRegName(MI->getOperand(1).getReg()); Src1Name = getRegName(MI->getOperand(1).getReg());
// FALL THROUGH. // FALL THROUGH.
case X86::VPERMILPSYmi: case X86::VPERMILPSYmi:
DecodeVPERMILPMask(MVT::v8f32, MI->getOperand(MI->getNumOperands()-1).getImm(), DecodePSHUFMask(MVT::v8f32, MI->getOperand(MI->getNumOperands()-1).getImm(),
ShuffleMask); ShuffleMask);
DestName = getRegName(MI->getOperand(0).getReg()); DestName = getRegName(MI->getOperand(0).getReg());
break; break;
case X86::VPERMILPDri: case X86::VPERMILPDri:
Src1Name = getRegName(MI->getOperand(1).getReg()); Src1Name = getRegName(MI->getOperand(1).getReg());
// FALL THROUGH. // FALL THROUGH.
case X86::VPERMILPDmi: case X86::VPERMILPDmi:
DecodeVPERMILPMask(MVT::v2f64, MI->getOperand(MI->getNumOperands()-1).getImm(), DecodePSHUFMask(MVT::v2f64, MI->getOperand(MI->getNumOperands()-1).getImm(),
ShuffleMask); ShuffleMask);
DestName = getRegName(MI->getOperand(0).getReg()); DestName = getRegName(MI->getOperand(0).getReg());
break; break;
case X86::VPERMILPDYri: case X86::VPERMILPDYri:
Src1Name = getRegName(MI->getOperand(1).getReg()); Src1Name = getRegName(MI->getOperand(1).getReg());
// FALL THROUGH. // FALL THROUGH.
case X86::VPERMILPDYmi: case X86::VPERMILPDYmi:
DecodeVPERMILPMask(MVT::v4f64, MI->getOperand(MI->getNumOperands()-1).getImm(), DecodePSHUFMask(MVT::v4f64, MI->getOperand(MI->getNumOperands()-1).getImm(),
ShuffleMask); ShuffleMask);
DestName = getRegName(MI->getOperand(0).getReg()); DestName = getRegName(MI->getOperand(0).getReg());
break; break;
@ -471,7 +480,9 @@ void llvm::EmitAnyX86InstComments(const MCInst *MI, raw_ostream &OS,
// FALL THROUGH. // FALL THROUGH.
case X86::VPERM2F128rm: case X86::VPERM2F128rm:
case X86::VPERM2I128rm: case X86::VPERM2I128rm:
DecodeVPERM2F128Mask(MI->getOperand(MI->getNumOperands()-1).getImm(), // For instruction comments purpose, assume the 256-bit vector is v4i64.
DecodeVPERM2X128Mask(MVT::v4i64,
MI->getOperand(MI->getNumOperands()-1).getImm(),
ShuffleMask); ShuffleMask);
Src1Name = getRegName(MI->getOperand(1).getReg()); Src1Name = getRegName(MI->getOperand(1).getReg());
DestName = getRegName(MI->getOperand(0).getReg()); DestName = getRegName(MI->getOperand(0).getReg());

View File

@ -63,11 +63,23 @@ void DecodeMOVLHPSMask(unsigned NElts,
ShuffleMask.push_back(NElts+i); ShuffleMask.push_back(NElts+i);
} }
void DecodePSHUFMask(unsigned NElts, unsigned Imm, /// 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) { SmallVectorImpl<unsigned> &ShuffleMask) {
for (unsigned i = 0; i != NElts; ++i) { unsigned NumElts = VT.getVectorNumElements();
ShuffleMask.push_back(Imm % NElts);
Imm /= NElts; unsigned NumLanes = VT.getSizeInBits() / 128;
unsigned NumLaneElts = NumElts / NumLanes;
int NewImm = Imm;
for (unsigned l = 0; l != NumElts; l += NumLaneElts) {
for (unsigned i = 0; i != NumLaneElts; ++i) {
ShuffleMask.push_back(NewImm % NumLaneElts + l);
NewImm /= NumLaneElts;
}
if (NumLaneElts == 4) NewImm = Imm; // reload imm
} }
} }
@ -95,6 +107,9 @@ void DecodePSHUFLWMask(unsigned Imm,
ShuffleMask.push_back(7); ShuffleMask.push_back(7);
} }
/// 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, void DecodeSHUFPMask(EVT VT, unsigned Imm,
SmallVectorImpl<unsigned> &ShuffleMask) { SmallVectorImpl<unsigned> &ShuffleMask) {
unsigned NumElts = VT.getVectorNumElements(); unsigned NumElts = VT.getVectorNumElements();
@ -103,22 +118,24 @@ void DecodeSHUFPMask(EVT VT, unsigned Imm,
unsigned NumLaneElts = NumElts / NumLanes; unsigned NumLaneElts = NumElts / NumLanes;
int NewImm = Imm; int NewImm = Imm;
for (unsigned l = 0; l < NumLanes; ++l) { for (unsigned l = 0; l != NumElts; l += NumLaneElts) {
unsigned LaneStart = l * NumLaneElts;
// Part that reads from dest. // Part that reads from dest.
for (unsigned i = 0; i != NumLaneElts/2; ++i) { for (unsigned i = 0; i != NumLaneElts/2; ++i) {
ShuffleMask.push_back(NewImm % NumLaneElts + LaneStart); ShuffleMask.push_back(NewImm % NumLaneElts + l);
NewImm /= NumLaneElts; NewImm /= NumLaneElts;
} }
// Part that reads from src. // Part that reads from src.
for (unsigned i = 0; i != NumLaneElts/2; ++i) { for (unsigned i = 0; i != NumLaneElts/2; ++i) {
ShuffleMask.push_back(NewImm % NumLaneElts + NumElts + LaneStart); ShuffleMask.push_back(NewImm % NumLaneElts + NumElts + l);
NewImm /= NumLaneElts; NewImm /= NumLaneElts;
} }
if (NumLaneElts == 4) NewImm = Imm; // reload imm if (NumLaneElts == 4) NewImm = Imm; // reload 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<unsigned> &ShuffleMask) {
unsigned NumElts = VT.getVectorNumElements(); unsigned NumElts = VT.getVectorNumElements();
@ -128,10 +145,8 @@ void DecodeUNPCKHMask(EVT VT, SmallVectorImpl<unsigned> &ShuffleMask) {
if (NumLanes == 0 ) NumLanes = 1; // Handle MMX if (NumLanes == 0 ) NumLanes = 1; // Handle MMX
unsigned NumLaneElts = NumElts / NumLanes; unsigned NumLaneElts = NumElts / NumLanes;
for (unsigned s = 0; s < NumLanes; ++s) { for (unsigned l = 0; l != NumElts; l += NumLaneElts) {
unsigned Start = s * NumLaneElts + NumLaneElts/2; for (unsigned i = l + NumLaneElts/2, e = l + NumLaneElts; i != e; ++i) {
unsigned End = s * NumLaneElts + NumLaneElts;
for (unsigned i = Start; i != End; ++i) {
ShuffleMask.push_back(i); // Reads from dest/src1 ShuffleMask.push_back(i); // Reads from dest/src1
ShuffleMask.push_back(i+NumElts); // Reads from src/src2 ShuffleMask.push_back(i+NumElts); // Reads from src/src2
} }
@ -139,8 +154,8 @@ void DecodeUNPCKHMask(EVT VT, SmallVectorImpl<unsigned> &ShuffleMask) {
} }
/// DecodeUNPCKLMask - This decodes the shuffle masks for unpcklps/unpcklpd /// DecodeUNPCKLMask - This decodes the shuffle masks for unpcklps/unpcklpd
/// etc. VT indicates the type of the vector allowing it to handle different /// and punpckl*. VT indicates the type of the vector allowing it to handle
/// datatypes and vector widths. /// different datatypes and vector widths.
void DecodeUNPCKLMask(EVT VT, SmallVectorImpl<unsigned> &ShuffleMask) { void DecodeUNPCKLMask(EVT VT, SmallVectorImpl<unsigned> &ShuffleMask) {
unsigned NumElts = VT.getVectorNumElements(); unsigned NumElts = VT.getVectorNumElements();
@ -150,38 +165,15 @@ void DecodeUNPCKLMask(EVT VT, SmallVectorImpl<unsigned> &ShuffleMask) {
if (NumLanes == 0 ) NumLanes = 1; // Handle MMX if (NumLanes == 0 ) NumLanes = 1; // Handle MMX
unsigned NumLaneElts = NumElts / NumLanes; unsigned NumLaneElts = NumElts / NumLanes;
for (unsigned s = 0; s < NumLanes; ++s) { for (unsigned l = 0; l != NumElts; l += NumLaneElts) {
unsigned Start = s * NumLaneElts; for (unsigned i = l, e = l + NumLaneElts/2; i != e; ++i) {
unsigned End = s * NumLaneElts + NumLaneElts/2;
for (unsigned i = Start; i != End; ++i) {
ShuffleMask.push_back(i); // Reads from dest/src1 ShuffleMask.push_back(i); // Reads from dest/src1
ShuffleMask.push_back(i+NumElts); // Reads from src/src2 ShuffleMask.push_back(i+NumElts); // Reads from src/src2
} }
} }
} }
// DecodeVPERMILPMask - Decodes VPERMILPS/ VPERMILPD permutes for any 128-bit void DecodeVPERM2X128Mask(EVT VT, unsigned Imm,
// 32-bit or 64-bit elements. For 256-bit vectors, it's considered as two 128
// lanes. For VPERMILPS, referenced elements can't cross lanes and the mask of
// the first lane must be the same of the second.
void DecodeVPERMILPMask(EVT VT, unsigned Imm,
SmallVectorImpl<unsigned> &ShuffleMask) {
unsigned NumElts = VT.getVectorNumElements();
unsigned NumLanes = VT.getSizeInBits() / 128;
unsigned NumLaneElts = NumElts / NumLanes;
for (unsigned l = 0; l != NumLanes; ++l) {
unsigned LaneStart = l*NumLaneElts;
for (unsigned i = 0; i != NumLaneElts; ++i) {
unsigned Idx = NumLaneElts == 4 ? (Imm >> (i*2)) & 0x3
: (Imm >> (i+LaneStart)) & 0x1;
ShuffleMask.push_back(Idx+LaneStart);
}
}
}
void DecodeVPERM2F128Mask(EVT VT, unsigned Imm,
SmallVectorImpl<unsigned> &ShuffleMask) { SmallVectorImpl<unsigned> &ShuffleMask) {
unsigned HalfSize = VT.getVectorNumElements()/2; unsigned HalfSize = VT.getVectorNumElements()/2;
unsigned FstHalfBegin = (Imm & 0x3) * HalfSize; unsigned FstHalfBegin = (Imm & 0x3) * HalfSize;
@ -193,12 +185,4 @@ void DecodeVPERM2F128Mask(EVT VT, unsigned Imm,
ShuffleMask.push_back(i); ShuffleMask.push_back(i);
} }
void DecodeVPERM2F128Mask(unsigned Imm,
SmallVectorImpl<unsigned> &ShuffleMask) {
// VPERM2F128 is used by any 256-bit EVT, but X86InstComments only
// has information about the instruction and not the types. So for
// instruction comments purpose, assume the 256-bit vector is v4i64.
return DecodeVPERM2F128Mask(MVT::v4i64, Imm, ShuffleMask);
}
} // llvm namespace } // llvm namespace

View File

@ -37,7 +37,7 @@ void DecodeMOVHLPSMask(unsigned NElts,
void DecodeMOVLHPSMask(unsigned NElts, void DecodeMOVLHPSMask(unsigned NElts,
SmallVectorImpl<unsigned> &ShuffleMask); SmallVectorImpl<unsigned> &ShuffleMask);
void DecodePSHUFMask(unsigned NElts, unsigned Imm, void DecodePSHUFMask(EVT VT, unsigned Imm,
SmallVectorImpl<unsigned> &ShuffleMask); SmallVectorImpl<unsigned> &ShuffleMask);
void DecodePSHUFHWMask(unsigned Imm, void DecodePSHUFHWMask(unsigned Imm,
@ -46,30 +46,24 @@ void DecodePSHUFHWMask(unsigned Imm,
void DecodePSHUFLWMask(unsigned Imm, void DecodePSHUFLWMask(unsigned Imm,
SmallVectorImpl<unsigned> &ShuffleMask); SmallVectorImpl<unsigned> &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, void DecodeSHUFPMask(EVT VT, unsigned Imm,
SmallVectorImpl<unsigned> &ShuffleMask); SmallVectorImpl<unsigned> &ShuffleMask);
/// DecodeUNPCKHMask - This decodes the shuffle masks for unpckhps/unpckhpd /// DecodeUNPCKHMask - This decodes the shuffle masks for unpckhps/unpckhpd
/// etc. VT indicates the type of the vector allowing it to handle different /// and punpckh*. VT indicates the type of the vector allowing it to handle
/// datatypes and vector widths. /// different datatypes and vector widths.
void DecodeUNPCKHMask(EVT VT, SmallVectorImpl<unsigned> &ShuffleMask); void DecodeUNPCKHMask(EVT VT, SmallVectorImpl<unsigned> &ShuffleMask);
/// DecodeUNPCKLMask - This decodes the shuffle masks for unpcklps/unpcklpd /// DecodeUNPCKLMask - This decodes the shuffle masks for unpcklps/unpcklpd
/// etc. VT indicates the type of the vector allowing it to handle different /// and punpckl*. VT indicates the type of the vector allowing it to handle
/// datatypes and vector widths. /// different datatypes and vector widths.
void DecodeUNPCKLMask(EVT VT, SmallVectorImpl<unsigned> &ShuffleMask); void DecodeUNPCKLMask(EVT VT, SmallVectorImpl<unsigned> &ShuffleMask);
// DecodeVPERMILPMask - Decodes VPERMILPS/ VPERMILPD permutes for any 128-bit void DecodeVPERM2X128Mask(EVT VT, unsigned Imm,
// 32-bit or 64-bit elements. For 256-bit vectors, it's considered as two 128
// lanes. For VPERMILPS, referenced elements can't cross lanes and the mask of
// the first lane must be the same of the second.
void DecodeVPERMILPMask(EVT VT, unsigned Imm,
SmallVectorImpl<unsigned> &ShuffleMask);
void DecodeVPERM2F128Mask(unsigned Imm,
SmallVectorImpl<unsigned> &ShuffleMask);
void DecodeVPERM2F128Mask(EVT VT, unsigned Imm,
SmallVectorImpl<unsigned> &ShuffleMask); SmallVectorImpl<unsigned> &ShuffleMask);
} // llvm namespace } // llvm namespace

View File

@ -4430,14 +4430,15 @@ static SDValue getShuffleScalarElt(SDNode *N, int Index, SelectionDAG &DAG,
if (Index < 0) if (Index < 0)
return DAG.getUNDEF(VT.getVectorElementType()); return DAG.getUNDEF(VT.getVectorElementType());
int NumElems = VT.getVectorNumElements(); unsigned NumElems = VT.getVectorNumElements();
SDValue NewV = (Index < NumElems) ? SV->getOperand(0) : SV->getOperand(1); SDValue NewV = (Index < (int)NumElems) ? SV->getOperand(0)
: SV->getOperand(1);
return getShuffleScalarElt(NewV.getNode(), Index % NumElems, DAG, Depth+1); return getShuffleScalarElt(NewV.getNode(), Index % NumElems, DAG, Depth+1);
} }
// Recurse into target specific vector shuffles to find scalars. // Recurse into target specific vector shuffles to find scalars.
if (isTargetShuffle(Opcode)) { if (isTargetShuffle(Opcode)) {
int NumElems = VT.getVectorNumElements(); unsigned NumElems = VT.getVectorNumElements();
SmallVector<unsigned, 16> ShuffleMask; SmallVector<unsigned, 16> ShuffleMask;
SDValue ImmN; SDValue ImmN;
@ -4460,9 +4461,9 @@ static SDValue getShuffleScalarElt(SDNode *N, int Index, SelectionDAG &DAG,
DecodeMOVLHPSMask(NumElems, ShuffleMask); DecodeMOVLHPSMask(NumElems, ShuffleMask);
break; break;
case X86ISD::PSHUFD: case X86ISD::PSHUFD:
case X86ISD::VPERMILP:
ImmN = N->getOperand(N->getNumOperands()-1); ImmN = N->getOperand(N->getNumOperands()-1);
DecodePSHUFMask(NumElems, DecodePSHUFMask(VT, cast<ConstantSDNode>(ImmN)->getZExtValue(),
cast<ConstantSDNode>(ImmN)->getZExtValue(),
ShuffleMask); ShuffleMask);
break; break;
case X86ISD::PSHUFHW: case X86ISD::PSHUFHW:
@ -4484,14 +4485,9 @@ static SDValue getShuffleScalarElt(SDNode *N, int Index, SelectionDAG &DAG,
return getShuffleScalarElt(V.getOperand(OpNum).getNode(), Index, DAG, return getShuffleScalarElt(V.getOperand(OpNum).getNode(), Index, DAG,
Depth+1); Depth+1);
} }
case X86ISD::VPERMILP:
ImmN = N->getOperand(N->getNumOperands()-1);
DecodeVPERMILPMask(VT, cast<ConstantSDNode>(ImmN)->getZExtValue(),
ShuffleMask);
break;
case X86ISD::VPERM2X128: case X86ISD::VPERM2X128:
ImmN = N->getOperand(N->getNumOperands()-1); ImmN = N->getOperand(N->getNumOperands()-1);
DecodeVPERM2F128Mask(VT, cast<ConstantSDNode>(ImmN)->getZExtValue(), DecodeVPERM2X128Mask(VT, cast<ConstantSDNode>(ImmN)->getZExtValue(),
ShuffleMask); ShuffleMask);
break; break;
case X86ISD::MOVDDUP: case X86ISD::MOVDDUP:
@ -4509,7 +4505,8 @@ static SDValue getShuffleScalarElt(SDNode *N, int Index, SelectionDAG &DAG,
if (Index < 0) if (Index < 0)
return DAG.getUNDEF(VT.getVectorElementType()); return DAG.getUNDEF(VT.getVectorElementType());
SDValue NewV = (Index < NumElems) ? N->getOperand(0) : N->getOperand(1); SDValue NewV = (Index < (int)NumElems) ? N->getOperand(0)
: N->getOperand(1);
return getShuffleScalarElt(NewV.getNode(), Index % NumElems, DAG, return getShuffleScalarElt(NewV.getNode(), Index % NumElems, DAG,
Depth+1); Depth+1);
} }