summaryrefslogtreecommitdiff
path: root/lib/Target/X86/Utils
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@gmail.com>2012-02-06 07:17:51 +0000
committerCraig Topper <craig.topper@gmail.com>2012-02-06 07:17:51 +0000
commitd156dc11f9acd83e3369c069d5006a0203be13d6 (patch)
tree77c950c1af8490a5e6a3139838cded3c391ad595 /lib/Target/X86/Utils
parent1230ad6e8cb7977527ac64dcf5005464d7d6c20b (diff)
downloadllvm-d156dc11f9acd83e3369c069d5006a0203be13d6.tar.gz
llvm-d156dc11f9acd83e3369c069d5006a0203be13d6.tar.bz2
llvm-d156dc11f9acd83e3369c069d5006a0203be13d6.tar.xz
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
Diffstat (limited to 'lib/Target/X86/Utils')
-rw-r--r--lib/Target/X86/Utils/X86ShuffleDecode.cpp80
-rw-r--r--lib/Target/X86/Utils/X86ShuffleDecode.h24
2 files changed, 41 insertions, 63 deletions
diff --git a/lib/Target/X86/Utils/X86ShuffleDecode.cpp b/lib/Target/X86/Utils/X86ShuffleDecode.cpp
index e7631b6557..f4b85aeaf5 100644
--- a/lib/Target/X86/Utils/X86ShuffleDecode.cpp
+++ b/lib/Target/X86/Utils/X86ShuffleDecode.cpp
@@ -63,11 +63,23 @@ void DecodeMOVLHPSMask(unsigned NElts,
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) {
- for (unsigned i = 0; i != NElts; ++i) {
- ShuffleMask.push_back(Imm % NElts);
- Imm /= NElts;
+ unsigned NumElts = VT.getVectorNumElements();
+
+ 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);
}
+/// 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) {
unsigned NumElts = VT.getVectorNumElements();
@@ -103,22 +118,24 @@ void DecodeSHUFPMask(EVT VT, unsigned Imm,
unsigned NumLaneElts = NumElts / NumLanes;
int NewImm = Imm;
- for (unsigned l = 0; l < NumLanes; ++l) {
- unsigned LaneStart = l * NumLaneElts;
+ for (unsigned l = 0; l != NumElts; l += NumLaneElts) {
// Part that reads from dest.
for (unsigned i = 0; i != NumLaneElts/2; ++i) {
- ShuffleMask.push_back(NewImm % NumLaneElts + LaneStart);
+ ShuffleMask.push_back(NewImm % NumLaneElts + l);
NewImm /= NumLaneElts;
}
// Part that reads from src.
for (unsigned i = 0; i != NumLaneElts/2; ++i) {
- ShuffleMask.push_back(NewImm % NumLaneElts + NumElts + LaneStart);
+ ShuffleMask.push_back(NewImm % NumLaneElts + NumElts + l);
NewImm /= NumLaneElts;
}
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) {
unsigned NumElts = VT.getVectorNumElements();
@@ -128,10 +145,8 @@ void DecodeUNPCKHMask(EVT VT, SmallVectorImpl<unsigned> &ShuffleMask) {
if (NumLanes == 0 ) NumLanes = 1; // Handle MMX
unsigned NumLaneElts = NumElts / NumLanes;
- for (unsigned s = 0; s < NumLanes; ++s) {
- unsigned Start = s * NumLaneElts + NumLaneElts/2;
- unsigned End = s * NumLaneElts + NumLaneElts;
- for (unsigned i = Start; i != End; ++i) {
+ for (unsigned l = 0; l != NumElts; l += NumLaneElts) {
+ for (unsigned i = l + NumLaneElts/2, e = l + NumLaneElts; i != e; ++i) {
ShuffleMask.push_back(i); // Reads from dest/src1
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
-/// etc. VT indicates the type of the vector allowing it to handle different
-/// datatypes and vector widths.
+/// 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) {
unsigned NumElts = VT.getVectorNumElements();
@@ -150,38 +165,15 @@ void DecodeUNPCKLMask(EVT VT, SmallVectorImpl<unsigned> &ShuffleMask) {
if (NumLanes == 0 ) NumLanes = 1; // Handle MMX
unsigned NumLaneElts = NumElts / NumLanes;
- for (unsigned s = 0; s < NumLanes; ++s) {
- unsigned Start = s * NumLaneElts;
- unsigned End = s * NumLaneElts + NumLaneElts/2;
- for (unsigned i = Start; i != End; ++i) {
+ for (unsigned l = 0; l != NumElts; l += NumLaneElts) {
+ for (unsigned i = l, e = l + NumLaneElts/2; i != e; ++i) {
ShuffleMask.push_back(i); // Reads from dest/src1
ShuffleMask.push_back(i+NumElts); // Reads from src/src2
}
}
}
-// DecodeVPERMILPMask - Decodes VPERMILPS/ VPERMILPD permutes for any 128-bit
-// 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,
+void DecodeVPERM2X128Mask(EVT VT, unsigned Imm,
SmallVectorImpl<unsigned> &ShuffleMask) {
unsigned HalfSize = VT.getVectorNumElements()/2;
unsigned FstHalfBegin = (Imm & 0x3) * HalfSize;
@@ -193,12 +185,4 @@ void DecodeVPERM2F128Mask(EVT VT, unsigned Imm,
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
diff --git a/lib/Target/X86/Utils/X86ShuffleDecode.h b/lib/Target/X86/Utils/X86ShuffleDecode.h
index 243728f81e..877c9bd543 100644
--- a/lib/Target/X86/Utils/X86ShuffleDecode.h
+++ b/lib/Target/X86/Utils/X86ShuffleDecode.h
@@ -37,7 +37,7 @@ void DecodeMOVHLPSMask(unsigned NElts,
void DecodeMOVLHPSMask(unsigned NElts,
SmallVectorImpl<unsigned> &ShuffleMask);
-void DecodePSHUFMask(unsigned NElts, unsigned Imm,
+void DecodePSHUFMask(EVT VT, unsigned Imm,
SmallVectorImpl<unsigned> &ShuffleMask);
void DecodePSHUFHWMask(unsigned Imm,
@@ -46,30 +46,24 @@ void DecodePSHUFHWMask(unsigned Imm,
void DecodePSHUFLWMask(unsigned Imm,
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,
SmallVectorImpl<unsigned> &ShuffleMask);
/// DecodeUNPCKHMask - This decodes the shuffle masks for unpckhps/unpckhpd
-/// etc. VT indicates the type of the vector allowing it to handle different
-/// datatypes and vector widths.
+/// 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);
/// DecodeUNPCKLMask - This decodes the shuffle masks for unpcklps/unpcklpd
-/// etc. VT indicates the type of the vector allowing it to handle different
-/// datatypes and vector widths.
+/// 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);
-// DecodeVPERMILPMask - Decodes VPERMILPS/ VPERMILPD permutes for any 128-bit
-// 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,
+void DecodeVPERM2X128Mask(EVT VT, unsigned Imm,
SmallVectorImpl<unsigned> &ShuffleMask);
} // llvm namespace