diff options
author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2016-04-16 17:52:07 +0000 |
---|---|---|
committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2016-04-16 17:52:07 +0000 |
commit | fd4b9b02a31febf107560a4196e30c0aede2bc5d (patch) | |
tree | 955e0c6f5e5006cae97a7dc4a702298620a86f80 /llvm/lib/Target/X86/Utils | |
parent | 04b579367dba7103e863fa976b5ac1e162d6b5f4 (diff) | |
download | bcm5719-llvm-fd4b9b02a31febf107560a4196e30c0aede2bc5d.tar.gz bcm5719-llvm-fd4b9b02a31febf107560a4196e30c0aede2bc5d.zip |
[X86][XOP] Added VPPERM constant mask decoding and target shuffle combining support
Added additional test that peeks through bitcast to v16i8 mask
llvm-svn: 266533
Diffstat (limited to 'llvm/lib/Target/X86/Utils')
-rw-r--r-- | llvm/lib/Target/X86/Utils/X86ShuffleDecode.cpp | 41 | ||||
-rw-r--r-- | llvm/lib/Target/X86/Utils/X86ShuffleDecode.h | 9 |
2 files changed, 48 insertions, 2 deletions
diff --git a/llvm/lib/Target/X86/Utils/X86ShuffleDecode.cpp b/llvm/lib/Target/X86/Utils/X86ShuffleDecode.cpp index f007349d184..768f688a09d 100644 --- a/llvm/lib/Target/X86/Utils/X86ShuffleDecode.cpp +++ b/llvm/lib/Target/X86/Utils/X86ShuffleDecode.cpp @@ -342,7 +342,46 @@ void DecodeBLENDMask(MVT VT, unsigned Imm, SmallVectorImpl<int> &ShuffleMask) { } } -/// DecodeVPERMMask - this decodes the shuffle masks for VPERMQ/VPERMPD. +void DecodeVPPERMMask(ArrayRef<uint64_t> RawMask, + SmallVectorImpl<int> &ShuffleMask) { + assert(RawMask.size() == 16 && "Illegal VPPERM shuffle mask size"); + + // VPPERM Operation + // Bits[4:0] - Byte Index (0 - 31) + // Bits[7:5] - Permute Operation + // + // Permute Operation: + // 0 - Source byte (no logical operation). + // 1 - Invert source byte. + // 2 - Bit reverse of source byte. + // 3 - Bit reverse of inverted source byte. + // 4 - 00h (zero - fill). + // 5 - FFh (ones - fill). + // 6 - Most significant bit of source byte replicated in all bit positions. + // 7 - Invert most significant bit of source byte and replicate in all bit positions. + for (int i = 0, e = RawMask.size(); i < e; ++i) { + uint64_t M = RawMask[i]; + if (M == (uint64_t)SM_SentinelUndef) { + ShuffleMask.push_back(M); + continue; + } + + uint64_t PermuteOp = (M >> 5) & 0x3; + if (PermuteOp == 4) { + ShuffleMask.push_back(SM_SentinelZero); + continue; + } + if (PermuteOp != 0) { + ShuffleMask.clear(); + return; + } + + uint64_t Index = M & 0x1F; + ShuffleMask.push_back((int)Index); + } +} + + /// DecodeVPERMMask - this decodes the shuffle masks for VPERMQ/VPERMPD. /// No VT provided since it only works on 256-bit, 4 element vectors. void DecodeVPERMMask(unsigned Imm, SmallVectorImpl<int> &ShuffleMask) { for (unsigned i = 0; i != 4; ++i) { diff --git a/llvm/lib/Target/X86/Utils/X86ShuffleDecode.h b/llvm/lib/Target/X86/Utils/X86ShuffleDecode.h index 0c92b39e07f..4a4d33b3689 100644 --- a/llvm/lib/Target/X86/Utils/X86ShuffleDecode.h +++ b/llvm/lib/Target/X86/Utils/X86ShuffleDecode.h @@ -73,7 +73,7 @@ void DecodePSHUFLWMask(MVT VT, unsigned Imm, SmallVectorImpl<int> &ShuffleMask); /// Decodes a PSWAPD 3DNow! instruction. void DecodePSWAPMask(MVT VT, SmallVectorImpl<int> &ShuffleMask); -/// Decodes the shuffle masks for shufp*. +/// Decodes the shuffle masks for shufp*. /// VT indicates the type of the vector allowing it to handle different /// datatypes and vector widths. void DecodeSHUFPMask(MVT VT, unsigned Imm, SmallVectorImpl<int> &ShuffleMask); @@ -108,6 +108,13 @@ void decodeVSHUF64x2FamilyMask(MVT VT, unsigned Imm, /// No VT provided since it only works on 256-bit, 4 element vectors. void DecodeVPERMMask(unsigned Imm, SmallVectorImpl<int> &ShuffleMask); +/// Decode a VPPERM mask from a raw array of constants such as from +/// BUILD_VECTOR. +/// This can only basic masks (permutes + zeros), not any of the other +/// operations that VPPERM can perform. +void DecodeVPPERMMask(ArrayRef<uint64_t> RawMask, + SmallVectorImpl<int> &ShuffleMask); + /// Decode a zero extension instruction as a shuffle mask. void DecodeZeroExtendMask(MVT SrcScalarVT, MVT DstVT, SmallVectorImpl<int> &ShuffleMask); |