2
0

rnd_template.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /*
  2. * SIMD-optimized halfpel functions are compiled twice for rnd/no_rnd
  3. * Copyright (c) 2000, 2001 Fabrice Bellard
  4. * Copyright (c) 2003-2004 Michael Niedermayer <michaelni@gmx.at>
  5. *
  6. * MMX optimization by Nick Kurshev <nickols_k@mail.ru>
  7. * mostly rewritten by Michael Niedermayer <michaelni@gmx.at>
  8. * and improved by Zdenek Kabelac <kabi@users.sf.net>
  9. *
  10. * This file is part of FFmpeg.
  11. *
  12. * FFmpeg is free software; you can redistribute it and/or
  13. * modify it under the terms of the GNU Lesser General Public
  14. * License as published by the Free Software Foundation; either
  15. * version 2.1 of the License, or (at your option) any later version.
  16. *
  17. * FFmpeg is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  20. * Lesser General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU Lesser General Public
  23. * License along with FFmpeg; if not, write to the Free Software
  24. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  25. */
  26. #include <stddef.h>
  27. #include <stdint.h>
  28. #include "inline_asm.h"
  29. // put_pixels
  30. av_unused STATIC void DEF(put, pixels8_xy2)(uint8_t *block, const uint8_t *pixels,
  31. ptrdiff_t line_size, int h)
  32. {
  33. MOVQ_ZERO(mm7);
  34. SET_RND(mm6); // =2 for rnd and =1 for no_rnd version
  35. __asm__ volatile(
  36. "movq (%1), %%mm0 \n\t"
  37. "movq 1(%1), %%mm4 \n\t"
  38. "movq %%mm0, %%mm1 \n\t"
  39. "movq %%mm4, %%mm5 \n\t"
  40. "punpcklbw %%mm7, %%mm0 \n\t"
  41. "punpcklbw %%mm7, %%mm4 \n\t"
  42. "punpckhbw %%mm7, %%mm1 \n\t"
  43. "punpckhbw %%mm7, %%mm5 \n\t"
  44. "paddusw %%mm0, %%mm4 \n\t"
  45. "paddusw %%mm1, %%mm5 \n\t"
  46. "xor %%"FF_REG_a", %%"FF_REG_a" \n\t"
  47. "add %3, %1 \n\t"
  48. ".p2align 3 \n\t"
  49. "1: \n\t"
  50. "movq (%1, %%"FF_REG_a"), %%mm0 \n\t"
  51. "movq 1(%1, %%"FF_REG_a"), %%mm2 \n\t"
  52. "movq %%mm0, %%mm1 \n\t"
  53. "movq %%mm2, %%mm3 \n\t"
  54. "punpcklbw %%mm7, %%mm0 \n\t"
  55. "punpcklbw %%mm7, %%mm2 \n\t"
  56. "punpckhbw %%mm7, %%mm1 \n\t"
  57. "punpckhbw %%mm7, %%mm3 \n\t"
  58. "paddusw %%mm2, %%mm0 \n\t"
  59. "paddusw %%mm3, %%mm1 \n\t"
  60. "paddusw %%mm6, %%mm4 \n\t"
  61. "paddusw %%mm6, %%mm5 \n\t"
  62. "paddusw %%mm0, %%mm4 \n\t"
  63. "paddusw %%mm1, %%mm5 \n\t"
  64. "psrlw $2, %%mm4 \n\t"
  65. "psrlw $2, %%mm5 \n\t"
  66. "packuswb %%mm5, %%mm4 \n\t"
  67. "movq %%mm4, (%2, %%"FF_REG_a") \n\t"
  68. "add %3, %%"FF_REG_a" \n\t"
  69. "movq (%1, %%"FF_REG_a"), %%mm2 \n\t" // 0 <-> 2 1 <-> 3
  70. "movq 1(%1, %%"FF_REG_a"), %%mm4 \n\t"
  71. "movq %%mm2, %%mm3 \n\t"
  72. "movq %%mm4, %%mm5 \n\t"
  73. "punpcklbw %%mm7, %%mm2 \n\t"
  74. "punpcklbw %%mm7, %%mm4 \n\t"
  75. "punpckhbw %%mm7, %%mm3 \n\t"
  76. "punpckhbw %%mm7, %%mm5 \n\t"
  77. "paddusw %%mm2, %%mm4 \n\t"
  78. "paddusw %%mm3, %%mm5 \n\t"
  79. "paddusw %%mm6, %%mm0 \n\t"
  80. "paddusw %%mm6, %%mm1 \n\t"
  81. "paddusw %%mm4, %%mm0 \n\t"
  82. "paddusw %%mm5, %%mm1 \n\t"
  83. "psrlw $2, %%mm0 \n\t"
  84. "psrlw $2, %%mm1 \n\t"
  85. "packuswb %%mm1, %%mm0 \n\t"
  86. "movq %%mm0, (%2, %%"FF_REG_a") \n\t"
  87. "add %3, %%"FF_REG_a" \n\t"
  88. "subl $2, %0 \n\t"
  89. "jnz 1b \n\t"
  90. :"+g"(h), "+S"(pixels)
  91. :"D"(block), "r"((x86_reg)line_size)
  92. :FF_REG_a, "memory");
  93. }
  94. // avg_pixels
  95. // this routine is 'slightly' suboptimal but mostly unused
  96. av_unused STATIC void DEF(avg, pixels8_xy2)(uint8_t *block, const uint8_t *pixels,
  97. ptrdiff_t line_size, int h)
  98. {
  99. MOVQ_ZERO(mm7);
  100. SET_RND(mm6); // =2 for rnd and =1 for no_rnd version
  101. __asm__ volatile(
  102. "movq (%1), %%mm0 \n\t"
  103. "movq 1(%1), %%mm4 \n\t"
  104. "movq %%mm0, %%mm1 \n\t"
  105. "movq %%mm4, %%mm5 \n\t"
  106. "punpcklbw %%mm7, %%mm0 \n\t"
  107. "punpcklbw %%mm7, %%mm4 \n\t"
  108. "punpckhbw %%mm7, %%mm1 \n\t"
  109. "punpckhbw %%mm7, %%mm5 \n\t"
  110. "paddusw %%mm0, %%mm4 \n\t"
  111. "paddusw %%mm1, %%mm5 \n\t"
  112. "xor %%"FF_REG_a", %%"FF_REG_a" \n\t"
  113. "add %3, %1 \n\t"
  114. ".p2align 3 \n\t"
  115. "1: \n\t"
  116. "movq (%1, %%"FF_REG_a"), %%mm0 \n\t"
  117. "movq 1(%1, %%"FF_REG_a"), %%mm2 \n\t"
  118. "movq %%mm0, %%mm1 \n\t"
  119. "movq %%mm2, %%mm3 \n\t"
  120. "punpcklbw %%mm7, %%mm0 \n\t"
  121. "punpcklbw %%mm7, %%mm2 \n\t"
  122. "punpckhbw %%mm7, %%mm1 \n\t"
  123. "punpckhbw %%mm7, %%mm3 \n\t"
  124. "paddusw %%mm2, %%mm0 \n\t"
  125. "paddusw %%mm3, %%mm1 \n\t"
  126. "paddusw %%mm6, %%mm4 \n\t"
  127. "paddusw %%mm6, %%mm5 \n\t"
  128. "paddusw %%mm0, %%mm4 \n\t"
  129. "paddusw %%mm1, %%mm5 \n\t"
  130. "psrlw $2, %%mm4 \n\t"
  131. "psrlw $2, %%mm5 \n\t"
  132. "movq (%2, %%"FF_REG_a"), %%mm3 \n\t"
  133. "packuswb %%mm5, %%mm4 \n\t"
  134. "pcmpeqd %%mm2, %%mm2 \n\t"
  135. "paddb %%mm2, %%mm2 \n\t"
  136. PAVGB_MMX(%%mm3, %%mm4, %%mm5, %%mm2)
  137. "movq %%mm5, (%2, %%"FF_REG_a") \n\t"
  138. "add %3, %%"FF_REG_a" \n\t"
  139. "movq (%1, %%"FF_REG_a"), %%mm2 \n\t" // 0 <-> 2 1 <-> 3
  140. "movq 1(%1, %%"FF_REG_a"), %%mm4 \n\t"
  141. "movq %%mm2, %%mm3 \n\t"
  142. "movq %%mm4, %%mm5 \n\t"
  143. "punpcklbw %%mm7, %%mm2 \n\t"
  144. "punpcklbw %%mm7, %%mm4 \n\t"
  145. "punpckhbw %%mm7, %%mm3 \n\t"
  146. "punpckhbw %%mm7, %%mm5 \n\t"
  147. "paddusw %%mm2, %%mm4 \n\t"
  148. "paddusw %%mm3, %%mm5 \n\t"
  149. "paddusw %%mm6, %%mm0 \n\t"
  150. "paddusw %%mm6, %%mm1 \n\t"
  151. "paddusw %%mm4, %%mm0 \n\t"
  152. "paddusw %%mm5, %%mm1 \n\t"
  153. "psrlw $2, %%mm0 \n\t"
  154. "psrlw $2, %%mm1 \n\t"
  155. "movq (%2, %%"FF_REG_a"), %%mm3 \n\t"
  156. "packuswb %%mm1, %%mm0 \n\t"
  157. "pcmpeqd %%mm2, %%mm2 \n\t"
  158. "paddb %%mm2, %%mm2 \n\t"
  159. PAVGB_MMX(%%mm3, %%mm0, %%mm1, %%mm2)
  160. "movq %%mm1, (%2, %%"FF_REG_a") \n\t"
  161. "add %3, %%"FF_REG_a" \n\t"
  162. "subl $2, %0 \n\t"
  163. "jnz 1b \n\t"
  164. :"+g"(h), "+S"(pixels)
  165. :"D"(block), "r"((x86_reg)line_size)
  166. :FF_REG_a, "memory");
  167. }