dsputil_mmx_rnd.h
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:16k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*
  2.  * DSP utils mmx 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.  * This library is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Lesser General Public
  8.  * License as published by the Free Software Foundation; either
  9.  * version 2 of the License, or (at your option) any later version.
  10.  *
  11.  * This library is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * Lesser General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Lesser General Public
  17.  * License along with this library; if not, write to the Free Software
  18.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19.  *
  20.  * MMX optimization by Nick Kurshev <nickols_k@mail.ru>
  21.  * mostly rewritten by Michael Niedermayer <michaelni@gmx.at>
  22.  * and improved by Zdenek Kabelac <kabi@users.sf.net>
  23.  */
  24. // put_pixels
  25. static void DEF(put, pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
  26. {
  27.     MOVQ_BFE(mm6);
  28.     __asm __volatile(
  29. "lea (%3, %3), %%"REG_a" nt"
  30. ".balign 8 nt"
  31. "1: nt"
  32. "movq (%1), %%mm0 nt"
  33. "movq 1(%1), %%mm1 nt"
  34. "movq (%1, %3), %%mm2 nt"
  35. "movq 1(%1, %3), %%mm3 nt"
  36. PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
  37. "movq %%mm4, (%2) nt"
  38. "movq %%mm5, (%2, %3) nt"
  39. "add %%"REG_a", %1 nt"
  40. "add %%"REG_a", %2 nt"
  41. "movq (%1), %%mm0 nt"
  42. "movq 1(%1), %%mm1 nt"
  43. "movq (%1, %3), %%mm2 nt"
  44. "movq 1(%1, %3), %%mm3 nt"
  45. PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
  46. "movq %%mm4, (%2) nt"
  47. "movq %%mm5, (%2, %3) nt"
  48. "add %%"REG_a", %1 nt"
  49. "add %%"REG_a", %2 nt"
  50. "subl $4, %0 nt"
  51. "jnz 1b nt"
  52. :"+g"(h), "+S"(pixels), "+D"(block)
  53. :"r"((long)line_size)
  54. :REG_a, "memory");
  55. }
  56. static void attribute_unused DEF(put, pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
  57. {
  58.     MOVQ_BFE(mm6);
  59.     __asm __volatile(
  60. "testl $1, %0 nt"
  61.         " jz 1f nt"
  62. "movq (%1), %%mm0 nt"
  63. "movq (%2), %%mm1 nt"
  64. "add %4, %1 nt"
  65. "add $8, %2 nt"
  66. PAVGB(%%mm0, %%mm1, %%mm4, %%mm6)
  67. "movq %%mm4, (%3) nt"
  68. "add %5, %3 nt"
  69.         "decl %0 nt"
  70. ".balign 8 nt"
  71. "1: nt"
  72. "movq (%1), %%mm0 nt"
  73. "movq (%2), %%mm1 nt"
  74. "add %4, %1 nt"
  75. "movq (%1), %%mm2 nt"
  76. "movq 8(%2), %%mm3 nt"
  77. "add %4, %1 nt"
  78. PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
  79. "movq %%mm4, (%3) nt"
  80. "add %5, %3 nt"
  81. "movq %%mm5, (%3) nt"
  82. "add %5, %3 nt"
  83. "movq (%1), %%mm0 nt"
  84. "movq 16(%2), %%mm1 nt"
  85. "add %4, %1 nt"
  86. "movq (%1), %%mm2 nt"
  87. "movq 24(%2), %%mm3 nt"
  88. "add %4, %1 nt"
  89. "add $32, %2 nt"
  90. PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
  91. "movq %%mm4, (%3) nt"
  92. "add %5, %3 nt"
  93. "movq %%mm5, (%3) nt"
  94. "add %5, %3 nt"
  95. "subl $4, %0 nt"
  96. "jnz 1b nt"
  97. #ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used
  98.         :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst)
  99. #else
  100.         :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst)
  101. #endif
  102. :"S"((long)src1Stride), "D"((long)dstStride)
  103. :"memory");
  104. }
  105. static void DEF(put, pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
  106. {
  107.     MOVQ_BFE(mm6);
  108.     __asm __volatile(
  109. "lea (%3, %3), %%"REG_a" nt"
  110. ".balign 8 nt"
  111. "1: nt"
  112. "movq (%1), %%mm0 nt"
  113. "movq 1(%1), %%mm1 nt"
  114. "movq (%1, %3), %%mm2 nt"
  115. "movq 1(%1, %3), %%mm3 nt"
  116. PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
  117. "movq %%mm4, (%2) nt"
  118. "movq %%mm5, (%2, %3) nt"
  119. "movq 8(%1), %%mm0 nt"
  120. "movq 9(%1), %%mm1 nt"
  121. "movq 8(%1, %3), %%mm2 nt"
  122. "movq 9(%1, %3), %%mm3 nt"
  123. PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
  124. "movq %%mm4, 8(%2) nt"
  125. "movq %%mm5, 8(%2, %3) nt"
  126. "add %%"REG_a", %1 nt"
  127. "add %%"REG_a", %2 nt"
  128. "movq (%1), %%mm0 nt"
  129. "movq 1(%1), %%mm1 nt"
  130. "movq (%1, %3), %%mm2 nt"
  131. "movq 1(%1, %3), %%mm3 nt"
  132. PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
  133. "movq %%mm4, (%2) nt"
  134. "movq %%mm5, (%2, %3) nt"
  135. "movq 8(%1), %%mm0 nt"
  136. "movq 9(%1), %%mm1 nt"
  137. "movq 8(%1, %3), %%mm2 nt"
  138. "movq 9(%1, %3), %%mm3 nt"
  139. PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
  140. "movq %%mm4, 8(%2) nt"
  141. "movq %%mm5, 8(%2, %3) nt"
  142. "add %%"REG_a", %1 nt"
  143. "add %%"REG_a", %2 nt"
  144. "subl $4, %0 nt"
  145. "jnz 1b nt"
  146. :"+g"(h), "+S"(pixels), "+D"(block)
  147. :"r"((long)line_size)
  148. :REG_a, "memory");
  149. }
  150. static void attribute_unused DEF(put, pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
  151. {
  152.     MOVQ_BFE(mm6);
  153.     __asm __volatile(
  154. "testl $1, %0 nt"
  155.         " jz 1f nt"
  156. "movq (%1), %%mm0 nt"
  157. "movq (%2), %%mm1 nt"
  158. "movq 8(%1), %%mm2 nt"
  159. "movq 8(%2), %%mm3 nt"
  160. "add %4, %1 nt"
  161. "add $16, %2 nt"
  162. PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
  163. "movq %%mm4, (%3) nt"
  164. "movq %%mm5, 8(%3) nt"
  165. "add %5, %3 nt"
  166. "decl %0 nt"
  167. ".balign 8 nt"
  168. "1: nt"
  169. "movq (%1), %%mm0 nt"
  170. "movq (%2), %%mm1 nt"
  171. "movq 8(%1), %%mm2 nt"
  172. "movq 8(%2), %%mm3 nt"
  173. "add %4, %1 nt"
  174. PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
  175. "movq %%mm4, (%3) nt"
  176. "movq %%mm5, 8(%3) nt"
  177. "add %5, %3 nt"
  178. "movq (%1), %%mm0 nt"
  179. "movq 16(%2), %%mm1 nt"
  180. "movq 8(%1), %%mm2 nt"
  181. "movq 24(%2), %%mm3 nt"
  182. "add %4, %1 nt"
  183. PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
  184. "movq %%mm4, (%3) nt"
  185. "movq %%mm5, 8(%3) nt"
  186. "add %5, %3 nt"
  187. "add $32, %2 nt"
  188. "subl $2, %0 nt"
  189. "jnz 1b nt"
  190. #ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used
  191. :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst)
  192. #else
  193. :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst)
  194. #endif
  195. :"S"((long)src1Stride), "D"((long)dstStride)
  196. :"memory"); 
  197. }
  198. static void DEF(put, pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
  199. {
  200.     MOVQ_BFE(mm6);
  201.     __asm __volatile(
  202. "lea (%3, %3), %%"REG_a" nt"
  203. "movq (%1), %%mm0 nt"
  204. ".balign 8 nt"
  205. "1: nt"
  206. "movq (%1, %3), %%mm1 nt"
  207. "movq (%1, %%"REG_a"),%%mm2 nt"
  208. PAVGBP(%%mm1, %%mm0, %%mm4,   %%mm2, %%mm1, %%mm5)
  209. "movq %%mm4, (%2) nt"
  210. "movq %%mm5, (%2, %3) nt"
  211. "add %%"REG_a", %1 nt"
  212. "add %%"REG_a", %2 nt"
  213. "movq (%1, %3), %%mm1 nt"
  214. "movq (%1, %%"REG_a"),%%mm0 nt"
  215. PAVGBP(%%mm1, %%mm2, %%mm4,   %%mm0, %%mm1, %%mm5)
  216. "movq %%mm4, (%2) nt"
  217. "movq %%mm5, (%2, %3) nt"
  218. "add %%"REG_a", %1 nt"
  219. "add %%"REG_a", %2 nt"
  220. "subl $4, %0 nt"
  221. "jnz 1b nt"
  222. :"+g"(h), "+S"(pixels), "+D"(block)
  223. :"r"((long)line_size)
  224. :REG_a, "memory");
  225. }
  226. static void DEF(put, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
  227. {
  228.     MOVQ_ZERO(mm7);
  229.     SET_RND(mm6); // =2 for rnd  and  =1 for no_rnd version
  230.     __asm __volatile(
  231. "movq (%1), %%mm0 nt"
  232. "movq 1(%1), %%mm4 nt"
  233. "movq %%mm0, %%mm1 nt"
  234. "movq %%mm4, %%mm5 nt"
  235. "punpcklbw %%mm7, %%mm0 nt"
  236. "punpcklbw %%mm7, %%mm4 nt"
  237. "punpckhbw %%mm7, %%mm1 nt"
  238. "punpckhbw %%mm7, %%mm5 nt"
  239. "paddusw %%mm0, %%mm4 nt"
  240. "paddusw %%mm1, %%mm5 nt"
  241. "xor %%"REG_a", %%"REG_a" nt"
  242. "add %3, %1 nt"
  243. ".balign 8       nt"
  244. "1: nt"
  245. "movq (%1, %%"REG_a"), %%mm0 nt"
  246. "movq 1(%1, %%"REG_a"), %%mm2 nt"
  247. "movq %%mm0, %%mm1 nt"
  248. "movq %%mm2, %%mm3 nt"
  249. "punpcklbw %%mm7, %%mm0 nt"
  250. "punpcklbw %%mm7, %%mm2 nt"
  251. "punpckhbw %%mm7, %%mm1 nt"
  252. "punpckhbw %%mm7, %%mm3 nt"
  253. "paddusw %%mm2, %%mm0   nt"
  254. "paddusw %%mm3, %%mm1 nt"
  255. "paddusw %%mm6, %%mm4 nt"
  256. "paddusw %%mm6, %%mm5 nt"
  257. "paddusw %%mm0, %%mm4 nt"
  258. "paddusw %%mm1, %%mm5 nt"
  259. "psrlw $2, %%mm4 nt"
  260. "psrlw $2, %%mm5 nt"
  261. "packuswb  %%mm5, %%mm4 nt"
  262. "movq %%mm4, (%2, %%"REG_a") nt"
  263. "add %3, %%"REG_a" nt"
  264. "movq (%1, %%"REG_a"), %%mm2 nt" // 0 <-> 2   1 <-> 3
  265. "movq 1(%1, %%"REG_a"), %%mm4 nt"
  266. "movq %%mm2, %%mm3 nt"
  267. "movq %%mm4, %%mm5 nt"
  268. "punpcklbw %%mm7, %%mm2 nt"
  269. "punpcklbw %%mm7, %%mm4 nt"
  270. "punpckhbw %%mm7, %%mm3 nt"
  271. "punpckhbw %%mm7, %%mm5 nt"
  272. "paddusw %%mm2, %%mm4   nt"
  273. "paddusw %%mm3, %%mm5 nt"
  274. "paddusw %%mm6, %%mm0 nt"
  275. "paddusw %%mm6, %%mm1 nt"
  276. "paddusw %%mm4, %%mm0 nt"
  277. "paddusw %%mm5, %%mm1 nt"
  278. "psrlw $2, %%mm0 nt"
  279. "psrlw $2, %%mm1 nt"
  280. "packuswb  %%mm1, %%mm0 nt"
  281. "movq %%mm0, (%2, %%"REG_a") nt"
  282. "add %3, %%"REG_a" nt"
  283. "subl $2, %0 nt"
  284. "jnz 1b nt"
  285. :"+g"(h), "+S"(pixels)
  286. :"D"(block), "r"((long)line_size)
  287. :REG_a, "memory");
  288. }
  289. // avg_pixels
  290. static void attribute_unused DEF(avg, pixels4)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
  291. {
  292.     MOVQ_BFE(mm6);
  293.     JUMPALIGN();
  294.     do {
  295. __asm __volatile(
  296.      "movd  %0, %%mm0 nt"
  297.      "movd  %1, %%mm1 nt"
  298.      PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
  299.      "movd  %%mm2, %0 nt"
  300.      :"+m"(*block)
  301.      :"m"(*pixels)
  302.      :"memory");
  303. pixels += line_size;
  304. block += line_size;
  305.     }
  306.     while (--h);
  307. }
  308. // in case more speed is needed - unroling would certainly help
  309. static void DEF(avg, pixels8)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
  310. {
  311.     MOVQ_BFE(mm6);
  312.     JUMPALIGN();
  313.     do {
  314. __asm __volatile(
  315.      "movq  %0, %%mm0 nt"
  316.      "movq  %1, %%mm1 nt"
  317.      PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
  318.      "movq  %%mm2, %0 nt"
  319.      :"+m"(*block)
  320.      :"m"(*pixels)
  321.      :"memory");
  322. pixels += line_size;
  323. block += line_size;
  324.     }
  325.     while (--h);
  326. }
  327. static void DEF(avg, pixels16)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
  328. {
  329.     MOVQ_BFE(mm6);
  330.     JUMPALIGN();
  331.     do {
  332. __asm __volatile(
  333.      "movq  %0, %%mm0 nt"
  334.      "movq  %1, %%mm1 nt"
  335.      PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
  336.      "movq  %%mm2, %0 nt"
  337.      "movq  8%0, %%mm0 nt"
  338.      "movq  8%1, %%mm1 nt"
  339.      PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
  340.      "movq  %%mm2, 8%0 nt"
  341.      :"+m"(*block)
  342.      :"m"(*pixels)
  343.      :"memory");
  344. pixels += line_size;
  345. block += line_size;
  346.     }
  347.     while (--h);
  348. }
  349. static void DEF(avg, pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
  350. {
  351.     MOVQ_BFE(mm6);
  352.     JUMPALIGN();
  353.     do {
  354. __asm __volatile(
  355.     "movq  %1, %%mm0 nt"
  356.     "movq  1%1, %%mm1 nt"
  357.     "movq  %0, %%mm3 nt"
  358.     PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
  359.     PAVGB(%%mm3, %%mm2, %%mm0, %%mm6)
  360.     "movq  %%mm0, %0 nt"
  361.     :"+m"(*block)
  362.     :"m"(*pixels)
  363.     :"memory");
  364. pixels += line_size;
  365. block += line_size;
  366.     } while (--h);
  367. }
  368. static __attribute__((unused)) void DEF(avg, pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
  369. {
  370.     MOVQ_BFE(mm6);
  371.     JUMPALIGN();
  372.     do {
  373. __asm __volatile(
  374.     "movq  %1, %%mm0 nt"
  375.     "movq  %2, %%mm1 nt"
  376.     "movq  %0, %%mm3 nt"
  377.     PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
  378.     PAVGB(%%mm3, %%mm2, %%mm0, %%mm6)
  379.     "movq  %%mm0, %0 nt"
  380.     :"+m"(*dst)
  381.     :"m"(*src1), "m"(*src2)
  382.     :"memory");
  383. dst += dstStride;
  384.         src1 += src1Stride;
  385.         src2 += 8;
  386.     } while (--h);
  387. }
  388. static void DEF(avg, pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
  389. {
  390.     MOVQ_BFE(mm6);
  391.     JUMPALIGN();
  392.     do {
  393. __asm __volatile(
  394.     "movq  %1, %%mm0 nt"
  395.     "movq  1%1, %%mm1 nt"
  396.     "movq  %0, %%mm3 nt"
  397.     PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
  398.     PAVGB(%%mm3, %%mm2, %%mm0, %%mm6)
  399.     "movq  %%mm0, %0 nt"
  400.     "movq  8%1, %%mm0 nt"
  401.     "movq  9%1, %%mm1 nt"
  402.     "movq  8%0, %%mm3 nt"
  403.     PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
  404.     PAVGB(%%mm3, %%mm2, %%mm0, %%mm6)
  405.     "movq  %%mm0, 8%0 nt"
  406.     :"+m"(*block)
  407.     :"m"(*pixels)
  408.     :"memory");
  409. pixels += line_size;
  410. block += line_size;
  411.     } while (--h);
  412. }
  413. static __attribute__((unused)) void DEF(avg, pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
  414. {
  415.     MOVQ_BFE(mm6);
  416.     JUMPALIGN();
  417.     do {
  418. __asm __volatile(
  419.     "movq  %1, %%mm0 nt"
  420.     "movq  %2, %%mm1 nt"
  421.     "movq  %0, %%mm3 nt"
  422.     PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
  423.     PAVGB(%%mm3, %%mm2, %%mm0, %%mm6)
  424.     "movq  %%mm0, %0 nt"
  425.     "movq  8%1, %%mm0 nt"
  426.     "movq  8%2, %%mm1 nt"
  427.     "movq  8%0, %%mm3 nt"
  428.     PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
  429.     PAVGB(%%mm3, %%mm2, %%mm0, %%mm6)
  430.     "movq  %%mm0, 8%0 nt"
  431.     :"+m"(*dst)
  432.     :"m"(*src1), "m"(*src2)
  433.     :"memory");
  434. dst += dstStride;
  435.         src1 += src1Stride;
  436.         src2 += 16;
  437.     } while (--h);
  438. }
  439. static void DEF(avg, pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
  440. {
  441.     MOVQ_BFE(mm6);
  442.     __asm __volatile(
  443. "lea (%3, %3), %%"REG_a" nt"
  444. "movq (%1), %%mm0 nt"
  445. ".balign 8 nt"
  446. "1: nt"
  447. "movq (%1, %3), %%mm1 nt"
  448. "movq (%1, %%"REG_a"), %%mm2 nt"
  449. PAVGBP(%%mm1, %%mm0, %%mm4,   %%mm2, %%mm1, %%mm5)
  450. "movq (%2), %%mm3 nt"
  451. PAVGB(%%mm3, %%mm4, %%mm0, %%mm6)
  452. "movq (%2, %3), %%mm3 nt"
  453. PAVGB(%%mm3, %%mm5, %%mm1, %%mm6)
  454. "movq %%mm0, (%2) nt"
  455. "movq %%mm1, (%2, %3) nt"
  456. "add %%"REG_a", %1 nt"
  457. "add %%"REG_a", %2 nt"
  458. "movq (%1, %3), %%mm1 nt"
  459. "movq (%1, %%"REG_a"), %%mm0 nt"
  460. PAVGBP(%%mm1, %%mm2, %%mm4,   %%mm0, %%mm1, %%mm5)
  461. "movq (%2), %%mm3 nt"
  462. PAVGB(%%mm3, %%mm4, %%mm2, %%mm6)
  463. "movq (%2, %3), %%mm3 nt"
  464. PAVGB(%%mm3, %%mm5, %%mm1, %%mm6)
  465. "movq %%mm2, (%2) nt"
  466. "movq %%mm1, (%2, %3) nt"
  467. "add %%"REG_a", %1 nt"
  468. "add %%"REG_a", %2 nt"
  469. "subl $4, %0 nt"
  470. "jnz 1b nt"
  471. :"+g"(h), "+S"(pixels), "+D"(block)
  472. :"r"((long)line_size)
  473. :REG_a, "memory");
  474. }
  475. // this routine is 'slightly' suboptimal but mostly unused
  476. static void DEF(avg, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
  477. {
  478.     MOVQ_ZERO(mm7);
  479.     SET_RND(mm6); // =2 for rnd  and  =1 for no_rnd version
  480.     __asm __volatile(
  481. "movq (%1), %%mm0 nt"
  482. "movq 1(%1), %%mm4 nt"
  483. "movq %%mm0, %%mm1 nt"
  484. "movq %%mm4, %%mm5 nt"
  485. "punpcklbw %%mm7, %%mm0 nt"
  486. "punpcklbw %%mm7, %%mm4 nt"
  487. "punpckhbw %%mm7, %%mm1 nt"
  488. "punpckhbw %%mm7, %%mm5 nt"
  489. "paddusw %%mm0, %%mm4 nt"
  490. "paddusw %%mm1, %%mm5 nt"
  491. "xor %%"REG_a", %%"REG_a" nt"
  492. "add %3, %1 nt"
  493. ".balign 8 nt"
  494. "1: nt"
  495. "movq (%1, %%"REG_a"), %%mm0 nt"
  496. "movq 1(%1, %%"REG_a"), %%mm2 nt"
  497. "movq %%mm0, %%mm1 nt"
  498. "movq %%mm2, %%mm3 nt"
  499. "punpcklbw %%mm7, %%mm0 nt"
  500. "punpcklbw %%mm7, %%mm2 nt"
  501. "punpckhbw %%mm7, %%mm1 nt"
  502. "punpckhbw %%mm7, %%mm3 nt"
  503. "paddusw %%mm2, %%mm0   nt"
  504. "paddusw %%mm3, %%mm1 nt"
  505. "paddusw %%mm6, %%mm4 nt"
  506. "paddusw %%mm6, %%mm5 nt"
  507. "paddusw %%mm0, %%mm4 nt"
  508. "paddusw %%mm1, %%mm5 nt"
  509. "psrlw $2, %%mm4 nt"
  510. "psrlw $2, %%mm5 nt"
  511. "movq (%2, %%"REG_a"), %%mm3 nt"
  512. "packuswb  %%mm5, %%mm4 nt"
  513. "pcmpeqd %%mm2, %%mm2 nt"
  514. "paddb %%mm2, %%mm2 nt"
  515. PAVGB(%%mm3, %%mm4, %%mm5, %%mm2)
  516. "movq %%mm5, (%2, %%"REG_a") nt"
  517. "add %3, %%"REG_a" nt"
  518. "movq (%1, %%"REG_a"), %%mm2 nt" // 0 <-> 2   1 <-> 3
  519. "movq 1(%1, %%"REG_a"), %%mm4 nt"
  520. "movq %%mm2, %%mm3 nt"
  521. "movq %%mm4, %%mm5 nt"
  522. "punpcklbw %%mm7, %%mm2 nt"
  523. "punpcklbw %%mm7, %%mm4 nt"
  524. "punpckhbw %%mm7, %%mm3 nt"
  525. "punpckhbw %%mm7, %%mm5 nt"
  526. "paddusw %%mm2, %%mm4   nt"
  527. "paddusw %%mm3, %%mm5 nt"
  528. "paddusw %%mm6, %%mm0 nt"
  529. "paddusw %%mm6, %%mm1 nt"
  530. "paddusw %%mm4, %%mm0 nt"
  531. "paddusw %%mm5, %%mm1 nt"
  532. "psrlw $2, %%mm0 nt"
  533. "psrlw $2, %%mm1 nt"
  534. "movq (%2, %%"REG_a"), %%mm3 nt"
  535. "packuswb  %%mm1, %%mm0 nt"
  536. "pcmpeqd %%mm2, %%mm2 nt"
  537. "paddb %%mm2, %%mm2 nt"
  538. PAVGB(%%mm3, %%mm0, %%mm1, %%mm2)
  539. "movq %%mm1, (%2, %%"REG_a") nt"
  540. "add %3, %%"REG_a" nt"
  541. "subl $2, %0 nt"
  542. "jnz 1b nt"
  543. :"+g"(h), "+S"(pixels)
  544. :"D"(block), "r"((long)line_size)
  545. :REG_a, "memory");
  546. }
  547. //FIXME optimize
  548. static void DEF(put, pixels16_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
  549.     DEF(put, pixels8_y2)(block  , pixels  , line_size, h);
  550.     DEF(put, pixels8_y2)(block+8, pixels+8, line_size, h);
  551. }
  552. static void DEF(put, pixels16_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
  553.     DEF(put, pixels8_xy2)(block  , pixels  , line_size, h);
  554.     DEF(put, pixels8_xy2)(block+8, pixels+8, line_size, h);
  555. }
  556. static void DEF(avg, pixels16_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
  557.     DEF(avg, pixels8_y2)(block  , pixels  , line_size, h);
  558.     DEF(avg, pixels8_y2)(block+8, pixels+8, line_size, h);
  559. }
  560. static void DEF(avg, pixels16_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
  561.     DEF(avg, pixels8_xy2)(block  , pixels  , line_size, h);
  562.     DEF(avg, pixels8_xy2)(block+8, pixels+8, line_size, h);
  563. }