| 1 | static inline __m128i |
| 2 | dec_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 | |