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