highbd_idct8x8_add_sse4.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. * Copyright (c) 2017 The WebM project authors. All Rights Reserved.
  3. *
  4. * Use of this source code is governed by a BSD-style license
  5. * that can be found in the LICENSE file in the root of the source
  6. * tree. An additional intellectual property rights grant can be found
  7. * in the file PATENTS. All contributing project authors may
  8. * be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #include <smmintrin.h> // SSE4.1
  11. #include "./vpx_dsp_rtcd.h"
  12. #include "vpx_dsp/x86/highbd_inv_txfm_sse2.h"
  13. #include "vpx_dsp/x86/highbd_inv_txfm_sse4.h"
  14. #include "vpx_dsp/x86/inv_txfm_sse2.h"
  15. #include "vpx_dsp/x86/inv_txfm_ssse3.h"
  16. #include "vpx_dsp/x86/transpose_sse2.h"
  17. void vpx_highbd_idct8x8_half1d_sse4_1(__m128i *const io) {
  18. __m128i step1[8], step2[8];
  19. transpose_32bit_4x4x2(io, io);
  20. // stage 1
  21. step1[0] = io[0];
  22. step1[2] = io[4];
  23. step1[1] = io[2];
  24. step1[3] = io[6];
  25. highbd_butterfly_sse4_1(io[1], io[7], cospi_28_64, cospi_4_64, &step1[4],
  26. &step1[7]);
  27. highbd_butterfly_sse4_1(io[5], io[3], cospi_12_64, cospi_20_64, &step1[5],
  28. &step1[6]);
  29. // stage 2
  30. highbd_butterfly_cospi16_sse4_1(step1[0], step1[2], &step2[0], &step2[1]);
  31. highbd_butterfly_sse4_1(step1[1], step1[3], cospi_24_64, cospi_8_64,
  32. &step2[2], &step2[3]);
  33. step2[4] = _mm_add_epi32(step1[4], step1[5]);
  34. step2[5] = _mm_sub_epi32(step1[4], step1[5]);
  35. step2[6] = _mm_sub_epi32(step1[7], step1[6]);
  36. step2[7] = _mm_add_epi32(step1[7], step1[6]);
  37. // stage 3
  38. step1[0] = _mm_add_epi32(step2[0], step2[3]);
  39. step1[1] = _mm_add_epi32(step2[1], step2[2]);
  40. step1[2] = _mm_sub_epi32(step2[1], step2[2]);
  41. step1[3] = _mm_sub_epi32(step2[0], step2[3]);
  42. step1[4] = step2[4];
  43. highbd_butterfly_cospi16_sse4_1(step2[6], step2[5], &step1[6], &step1[5]);
  44. step1[7] = step2[7];
  45. // stage 4
  46. highbd_idct8_stage4(step1, io);
  47. }
  48. static void highbd_idct8x8_12_half1d(__m128i *const io) {
  49. __m128i temp1[2], step1[8], step2[8];
  50. transpose_32bit_4x4(io, io);
  51. // stage 1
  52. step1[0] = io[0];
  53. step1[1] = io[2];
  54. extend_64bit(io[1], temp1);
  55. step1[4] = multiplication_round_shift_sse4_1(temp1, cospi_28_64);
  56. step1[7] = multiplication_round_shift_sse4_1(temp1, cospi_4_64);
  57. extend_64bit(io[3], temp1);
  58. step1[5] = multiplication_round_shift_sse4_1(temp1, -cospi_20_64);
  59. step1[6] = multiplication_round_shift_sse4_1(temp1, cospi_12_64);
  60. // stage 2
  61. extend_64bit(step1[0], temp1);
  62. step2[0] = multiplication_round_shift_sse4_1(temp1, cospi_16_64);
  63. extend_64bit(step1[1], temp1);
  64. step2[2] = multiplication_round_shift_sse4_1(temp1, cospi_24_64);
  65. step2[3] = multiplication_round_shift_sse4_1(temp1, cospi_8_64);
  66. step2[4] = _mm_add_epi32(step1[4], step1[5]);
  67. step2[5] = _mm_sub_epi32(step1[4], step1[5]);
  68. step2[6] = _mm_sub_epi32(step1[7], step1[6]);
  69. step2[7] = _mm_add_epi32(step1[7], step1[6]);
  70. // stage 3
  71. step1[0] = _mm_add_epi32(step2[0], step2[3]);
  72. step1[1] = _mm_add_epi32(step2[0], step2[2]);
  73. step1[2] = _mm_sub_epi32(step2[0], step2[2]);
  74. step1[3] = _mm_sub_epi32(step2[0], step2[3]);
  75. step1[4] = step2[4];
  76. highbd_butterfly_cospi16_sse4_1(step2[6], step2[5], &step1[6], &step1[5]);
  77. step1[7] = step2[7];
  78. // stage 4
  79. highbd_idct8_stage4(step1, io);
  80. }
  81. void vpx_highbd_idct8x8_64_add_sse4_1(const tran_low_t *input, uint16_t *dest,
  82. int stride, int bd) {
  83. __m128i io[16];
  84. io[0] = _mm_load_si128((const __m128i *)(input + 0 * 8 + 0));
  85. io[4] = _mm_load_si128((const __m128i *)(input + 0 * 8 + 4));
  86. io[1] = _mm_load_si128((const __m128i *)(input + 1 * 8 + 0));
  87. io[5] = _mm_load_si128((const __m128i *)(input + 1 * 8 + 4));
  88. io[2] = _mm_load_si128((const __m128i *)(input + 2 * 8 + 0));
  89. io[6] = _mm_load_si128((const __m128i *)(input + 2 * 8 + 4));
  90. io[3] = _mm_load_si128((const __m128i *)(input + 3 * 8 + 0));
  91. io[7] = _mm_load_si128((const __m128i *)(input + 3 * 8 + 4));
  92. if (bd == 8) {
  93. __m128i io_short[8];
  94. io_short[0] = _mm_packs_epi32(io[0], io[4]);
  95. io_short[1] = _mm_packs_epi32(io[1], io[5]);
  96. io_short[2] = _mm_packs_epi32(io[2], io[6]);
  97. io_short[3] = _mm_packs_epi32(io[3], io[7]);
  98. io[8] = _mm_load_si128((const __m128i *)(input + 4 * 8 + 0));
  99. io[12] = _mm_load_si128((const __m128i *)(input + 4 * 8 + 4));
  100. io[9] = _mm_load_si128((const __m128i *)(input + 5 * 8 + 0));
  101. io[13] = _mm_load_si128((const __m128i *)(input + 5 * 8 + 4));
  102. io[10] = _mm_load_si128((const __m128i *)(input + 6 * 8 + 0));
  103. io[14] = _mm_load_si128((const __m128i *)(input + 6 * 8 + 4));
  104. io[11] = _mm_load_si128((const __m128i *)(input + 7 * 8 + 0));
  105. io[15] = _mm_load_si128((const __m128i *)(input + 7 * 8 + 4));
  106. io_short[4] = _mm_packs_epi32(io[8], io[12]);
  107. io_short[5] = _mm_packs_epi32(io[9], io[13]);
  108. io_short[6] = _mm_packs_epi32(io[10], io[14]);
  109. io_short[7] = _mm_packs_epi32(io[11], io[15]);
  110. vpx_idct8_sse2(io_short);
  111. vpx_idct8_sse2(io_short);
  112. round_shift_8x8(io_short, io);
  113. } else {
  114. __m128i temp[4];
  115. vpx_highbd_idct8x8_half1d_sse4_1(io);
  116. io[8] = _mm_load_si128((const __m128i *)(input + 4 * 8 + 0));
  117. io[12] = _mm_load_si128((const __m128i *)(input + 4 * 8 + 4));
  118. io[9] = _mm_load_si128((const __m128i *)(input + 5 * 8 + 0));
  119. io[13] = _mm_load_si128((const __m128i *)(input + 5 * 8 + 4));
  120. io[10] = _mm_load_si128((const __m128i *)(input + 6 * 8 + 0));
  121. io[14] = _mm_load_si128((const __m128i *)(input + 6 * 8 + 4));
  122. io[11] = _mm_load_si128((const __m128i *)(input + 7 * 8 + 0));
  123. io[15] = _mm_load_si128((const __m128i *)(input + 7 * 8 + 4));
  124. vpx_highbd_idct8x8_half1d_sse4_1(&io[8]);
  125. temp[0] = io[4];
  126. temp[1] = io[5];
  127. temp[2] = io[6];
  128. temp[3] = io[7];
  129. io[4] = io[8];
  130. io[5] = io[9];
  131. io[6] = io[10];
  132. io[7] = io[11];
  133. vpx_highbd_idct8x8_half1d_sse4_1(io);
  134. io[8] = temp[0];
  135. io[9] = temp[1];
  136. io[10] = temp[2];
  137. io[11] = temp[3];
  138. vpx_highbd_idct8x8_half1d_sse4_1(&io[8]);
  139. highbd_idct8x8_final_round(io);
  140. }
  141. recon_and_store_8x8(io, dest, stride, bd);
  142. }
  143. void vpx_highbd_idct8x8_12_add_sse4_1(const tran_low_t *input, uint16_t *dest,
  144. int stride, int bd) {
  145. const __m128i zero = _mm_setzero_si128();
  146. __m128i io[16];
  147. io[0] = _mm_load_si128((const __m128i *)(input + 0 * 8 + 0));
  148. io[1] = _mm_load_si128((const __m128i *)(input + 1 * 8 + 0));
  149. io[2] = _mm_load_si128((const __m128i *)(input + 2 * 8 + 0));
  150. io[3] = _mm_load_si128((const __m128i *)(input + 3 * 8 + 0));
  151. if (bd == 8) {
  152. __m128i io_short[8];
  153. io_short[0] = _mm_packs_epi32(io[0], zero);
  154. io_short[1] = _mm_packs_epi32(io[1], zero);
  155. io_short[2] = _mm_packs_epi32(io[2], zero);
  156. io_short[3] = _mm_packs_epi32(io[3], zero);
  157. idct8x8_12_add_kernel_ssse3(io_short);
  158. round_shift_8x8(io_short, io);
  159. } else {
  160. __m128i temp[4];
  161. highbd_idct8x8_12_half1d(io);
  162. temp[0] = io[4];
  163. temp[1] = io[5];
  164. temp[2] = io[6];
  165. temp[3] = io[7];
  166. highbd_idct8x8_12_half1d(io);
  167. io[8] = temp[0];
  168. io[9] = temp[1];
  169. io[10] = temp[2];
  170. io[11] = temp[3];
  171. highbd_idct8x8_12_half1d(&io[8]);
  172. highbd_idct8x8_final_round(io);
  173. }
  174. recon_and_store_8x8(io, dest, stride, bd);
  175. }