diff options
author | Logan Chien <loganchien@google.com> | 2011-10-20 00:08:13 +0800 |
---|---|---|
committer | Logan Chien <loganchien@google.com> | 2011-10-20 00:09:35 +0800 |
commit | 0ebc07a576037e4e36f68bf5cece32740ca120c0 (patch) | |
tree | c2e40648043d01498ee25af839a071193561e425 /lib/Target/X86/Utils | |
parent | 62383e889e0b06fd12a6b88311717cd33a1925c4 (diff) | |
parent | cdd8e46bec4e975d00a5abea808d8eb4138515c5 (diff) | |
download | external_llvm-0ebc07a576037e4e36f68bf5cece32740ca120c0.zip external_llvm-0ebc07a576037e4e36f68bf5cece32740ca120c0.tar.gz external_llvm-0ebc07a576037e4e36f68bf5cece32740ca120c0.tar.bz2 |
Merge with LLVM upstream 2011/10/20 (r142530)
Conflicts:
lib/Support/Unix/Host.inc
Change-Id: Idc00db3b63912dca6348bddd9f8a1af2a8d5d147
Diffstat (limited to 'lib/Target/X86/Utils')
-rw-r--r-- | lib/Target/X86/Utils/CMakeLists.txt | 8 | ||||
-rw-r--r-- | lib/Target/X86/Utils/X86ShuffleDecode.cpp | 75 | ||||
-rw-r--r-- | lib/Target/X86/Utils/X86ShuffleDecode.h | 20 |
3 files changed, 91 insertions, 12 deletions
diff --git a/lib/Target/X86/Utils/CMakeLists.txt b/lib/Target/X86/Utils/CMakeLists.txt index 3ad5f99..caffd8b 100644 --- a/lib/Target/X86/Utils/CMakeLists.txt +++ b/lib/Target/X86/Utils/CMakeLists.txt @@ -3,4 +3,10 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/ add_llvm_library(LLVMX86Utils X86ShuffleDecode.cpp ) -add_dependencies(LLVMX86Utils X86CodeGenTable_gen) + +add_llvm_library_dependencies(LLVMX86Utils + LLVMCore + LLVMSupport + ) + +add_dependencies(LLVMX86Utils X86CommonTableGen) diff --git a/lib/Target/X86/Utils/X86ShuffleDecode.cpp b/lib/Target/X86/Utils/X86ShuffleDecode.cpp index cd06060..aeb3309 100644 --- a/lib/Target/X86/Utils/X86ShuffleDecode.cpp +++ b/lib/Target/X86/Utils/X86ShuffleDecode.cpp @@ -167,24 +167,77 @@ void DecodeUNPCKLPMask(EVT VT, SmallVectorImpl<unsigned> &ShuffleMask) { unsigned NumElts = VT.getVectorNumElements(); - // Handle vector lengths > 128 bits. Define a "section" as a set of - // 128 bits. AVX defines UNPCK* to operate independently on 128-bit - // sections. - unsigned NumSections = VT.getSizeInBits() / 128; - if (NumSections == 0 ) NumSections = 1; // Handle MMX - unsigned NumSectionElts = NumElts / NumSections; + // Handle 128 and 256-bit vector lengths. AVX defines UNPCK* to operate + // independently on 128-bit lanes. + unsigned NumLanes = VT.getSizeInBits() / 128; + if (NumLanes == 0 ) NumLanes = 1; // Handle MMX + unsigned NumLaneElts = NumElts / NumLanes; unsigned Start = 0; - unsigned End = NumSectionElts / 2; - for (unsigned s = 0; s < NumSections; ++s) { + unsigned End = NumLaneElts / 2; + for (unsigned s = 0; s < NumLanes; ++s) { for (unsigned i = Start; i != End; ++i) { ShuffleMask.push_back(i); // Reads from dest/src1 - ShuffleMask.push_back(i+NumSectionElts); // Reads from src/src2 + ShuffleMask.push_back(i+NumLaneElts); // Reads from src/src2 } // Process the next 128 bits. - Start += NumSectionElts; - End += NumSectionElts; + Start += NumLaneElts; + End += NumLaneElts; } } +// DecodeVPERMILPSMask - Decodes VPERMILPS permutes for any 128-bit 32-bit +// elements. For 256-bit vectors, it's considered as two 128 lanes, the +// referenced elements can't cross lanes and the mask of the first lane must +// be the same of the second. +void DecodeVPERMILPSMask(unsigned NumElts, unsigned Imm, + SmallVectorImpl<unsigned> &ShuffleMask) { + unsigned NumLanes = (NumElts*32)/128; + unsigned LaneSize = NumElts/NumLanes; + + for (unsigned l = 0; l != NumLanes; ++l) { + for (unsigned i = 0; i != LaneSize; ++i) { + unsigned Idx = (Imm >> (i*2)) & 0x3 ; + ShuffleMask.push_back(Idx+(l*LaneSize)); + } + } +} + +// DecodeVPERMILPDMask - Decodes VPERMILPD permutes for any 128-bit 64-bit +// elements. For 256-bit vectors, it's considered as two 128 lanes, the +// referenced elements can't cross lanes but the mask of the first lane can +// be the different of the second (not like VPERMILPS). +void DecodeVPERMILPDMask(unsigned NumElts, unsigned Imm, + SmallVectorImpl<unsigned> &ShuffleMask) { + unsigned NumLanes = (NumElts*64)/128; + unsigned LaneSize = NumElts/NumLanes; + + for (unsigned l = 0; l < NumLanes; ++l) { + for (unsigned i = l*LaneSize; i < LaneSize*(l+1); ++i) { + unsigned Idx = (Imm >> i) & 0x1; + ShuffleMask.push_back(Idx+(l*LaneSize)); + } + } +} + +void DecodeVPERM2F128Mask(EVT VT, unsigned Imm, + SmallVectorImpl<unsigned> &ShuffleMask) { + unsigned HalfSize = VT.getVectorNumElements()/2; + unsigned FstHalfBegin = (Imm & 0x3) * HalfSize; + unsigned SndHalfBegin = ((Imm >> 4) & 0x3) * HalfSize; + + for (int i = FstHalfBegin, e = FstHalfBegin+HalfSize; i != e; ++i) + ShuffleMask.push_back(i); + for (int i = SndHalfBegin, e = SndHalfBegin+HalfSize; i != e; ++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 diff --git a/lib/Target/X86/Utils/X86ShuffleDecode.h b/lib/Target/X86/Utils/X86ShuffleDecode.h index b18f670..58193e6 100644 --- a/lib/Target/X86/Utils/X86ShuffleDecode.h +++ b/lib/Target/X86/Utils/X86ShuffleDecode.h @@ -82,6 +82,26 @@ void DecodeUNPCKLPDMask(unsigned NElts, void DecodeUNPCKLPMask(EVT VT, SmallVectorImpl<unsigned> &ShuffleMask); + +// DecodeVPERMILPSMask - Decodes VPERMILPS permutes for any 128-bit 32-bit +// elements. For 256-bit vectors, it's considered as two 128 lanes, the +// referenced elements can't cross lanes and the mask of the first lane must +// be the same of the second. +void DecodeVPERMILPSMask(unsigned NElts, unsigned Imm, + SmallVectorImpl<unsigned> &ShuffleMask); + +// DecodeVPERMILPDMask - Decodes VPERMILPD permutes for any 128-bit 64-bit +// elements. For 256-bit vectors, it's considered as two 128 lanes, the +// referenced elements can't cross lanes but the mask of the first lane can +// be the different of the second (not like VPERMILPS). +void DecodeVPERMILPDMask(unsigned NElts, unsigned Imm, + SmallVectorImpl<unsigned> &ShuffleMask); + +void DecodeVPERM2F128Mask(unsigned Imm, + SmallVectorImpl<unsigned> &ShuffleMask); +void DecodeVPERM2F128Mask(EVT VT, unsigned Imm, + SmallVectorImpl<unsigned> &ShuffleMask); + } // llvm namespace #endif |