dec_reshuffle.c 1.3 KB

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