你真的需要使用SSSE3,这比尝试使用<= SSE2更加干净。
你的代码将类似于这样:
#include <tmmintrin.h> // _mm_shuffle_epi8
#include <tmmintrin.h> // _mm_set_epi8
...
// check if your hardware supports SSSE3
...
__m128i mask = _mm_set_epi8(15, 11, 7, 3,
14, 10, 6, 2,
13, 9, 5, 1,
12, 8, 4, 0)
__m128i mtrx = _mm_set_epi8(16, 12, 8, 4,
15, 11, 7, 3,
14, 10, 6, 2,
13, 9, 5, 1)
mtrx = _mm_shuffle_epi8(mtrx, mask)
如果您确实需要SSE2,那么以下内容就足够了:
(假设我正确解释了您最初的顺序)
__m128i mask = _mm_set_epi8(0x00, 0xFF, 0x00, 0xFF,
0x00, 0xFF, 0x00, 0xFF,
0x00, 0xFF, 0x00, 0xFF,
0x00, 0xFF, 0x00, 0xFF)
__m128i mtrx = _mm_set_epi8(16, 12, 8, 4,
15, 11, 7, 3,
14, 10, 6, 2,
13, 9, 5, 1)
mtrx = _mm_packus_epi16(_mm_and_si128(mtrx, mask), _mm_srli_epi16(mtrx, 8))
mtrx = _mm_packus_epi16(_mm_and_si128(mtrx, mask), _mm_srli_epi16(mtrx, 8))
更容易调试:
__m128i mtrx = _mm_set_epi8(16, 12, 8, 4,
15, 11, 7, 3,
14, 10, 6, 2,
13, 9, 5, 1);
__m128i mask = _mm_set_epi8(0x00, 0xFF, 0x00, 0xFF,
0x00, 0xFF, 0x00, 0xFF,
0x00, 0xFF, 0x00, 0xFF,
0x00, 0xFF, 0x00, 0xFF);
__m128i temp = _mm_srli_epi16(mtrx, 8);
mtrx = _mm_and_si128(mtrx, mask);
mtrx = _mm_packus_epi16(mtrx, temp);
temp = _mm_srli_epi16(mtrx, 8);
mtrx = _mm_and_si128(mtrx, mask);
mtrx = _mm_packus_epi16(mtrx, temp);
PSHUFB
,这在旧CPU上有点像是Intel的专属功能之外,你需要看一下一系列混乱的SSE2PUNPCK(L/H)BW
指令,正如@harold所指出的那样。 - Iwillnotexist Idonotexist