dec_reshuffle.c 1.1 KB

12345678910111213141516171819202122232425262728293031323334
  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. const __m128i merge_ab_and_bc = _mm_maddubs_epi16(in, _mm_set1_epi32(0x01400140));
  10. // 0000kkkk LLllllll 0000JJJJ JJjjKKKK
  11. // 0000hhhh IIiiiiii 0000GGGG GGggHHHH
  12. // 0000eeee FFffffff 0000DDDD DDddEEEE
  13. // 0000bbbb CCcccccc 0000AAAA AAaaBBBB
  14. const __m128i out = _mm_madd_epi16(merge_ab_and_bc, _mm_set1_epi32(0x00011000));
  15. // 00000000 JJJJJJjj KKKKkkkk LLllllll
  16. // 00000000 GGGGGGgg HHHHhhhh IIiiiiii
  17. // 00000000 DDDDDDdd EEEEeeee FFffffff
  18. // 00000000 AAAAAAaa BBBBbbbb CCcccccc
  19. // Pack bytes together:
  20. return _mm_shuffle_epi8(out, _mm_setr_epi8(
  21. 2, 1, 0,
  22. 6, 5, 4,
  23. 10, 9, 8,
  24. 14, 13, 12,
  25. -1, -1, -1, -1));
  26. // 00000000 00000000 00000000 00000000
  27. // LLllllll KKKKkkkk JJJJJJjj IIiiiiii
  28. // HHHHhhhh GGGGGGgg FFffffff EEEEeeee
  29. // DDDDDDdd CCcccccc BBBBbbbb AAAAAAaa
  30. }