1static inline __m128i
2dec_reshuffle (const __m128i in)
3{
4 // in, bits, upper case are most significant bits, lower case are least significant bits
5 // 00llllll 00kkkkLL 00jjKKKK 00JJJJJJ
6 // 00iiiiii 00hhhhII 00ggHHHH 00GGGGGG
7 // 00ffffff 00eeeeFF 00ddEEEE 00DDDDDD
8 // 00cccccc 00bbbbCC 00aaBBBB 00AAAAAA
9
10 const __m128i merge_ab_and_bc = _mm_maddubs_epi16(in, _mm_set1_epi32(0x01400140));
11 // 0000kkkk LLllllll 0000JJJJ JJjjKKKK
12 // 0000hhhh IIiiiiii 0000GGGG GGggHHHH
13 // 0000eeee FFffffff 0000DDDD DDddEEEE
14 // 0000bbbb CCcccccc 0000AAAA AAaaBBBB
15
16 const __m128i out = _mm_madd_epi16(merge_ab_and_bc, _mm_set1_epi32(0x00011000));
17 // 00000000 JJJJJJjj KKKKkkkk LLllllll
18 // 00000000 GGGGGGgg HHHHhhhh IIiiiiii
19 // 00000000 DDDDDDdd EEEEeeee FFffffff
20 // 00000000 AAAAAAaa BBBBbbbb CCcccccc
21
22 // Pack bytes together:
23 return _mm_shuffle_epi8(out, _mm_setr_epi8(
24 2, 1, 0,
25 6, 5, 4,
26 10, 9, 8,
27 14, 13, 12,
28 -1, -1, -1, -1));
29 // 00000000 00000000 00000000 00000000
30 // LLllllll KKKKkkkk JJJJJJjj IIiiiiii
31 // HHHHhhhh GGGGGGgg FFffffff EEEEeeee
32 // DDDDDDdd CCcccccc BBBBbbbb AAAAAAaa
33}
34