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

Windows CE

开发平台:

C/C++

  1. /*
  2.  * DSP utils : average functions are compiled twice for 3dnow/mmx2
  3.  * Copyright (c) 2000, 2001 Fabrice Bellard.
  4.  * Copyright (c) 2002-2004 Michael Niedermayer
  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.  
  25. /* XXX: we use explicit registers to avoid a gcc 2.95.2 register asm
  26.    clobber bug - now it will work with 2.95.2 and also with -fPIC
  27.  */
  28. static void DEF(put_pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
  29. {
  30.     __asm __volatile(
  31. "lea (%3, %3), %%"REG_a" nt"
  32. "1: nt"
  33. "movq (%1), %%mm0 nt"
  34. "movq (%1, %3), %%mm1 nt"
  35. PAVGB" 1(%1), %%mm0 nt"
  36. PAVGB" 1(%1, %3), %%mm1 nt"
  37. "movq %%mm0, (%2) nt"
  38. "movq %%mm1, (%2, %3) nt"
  39. "add %%"REG_a", %1 nt"
  40. "add %%"REG_a", %2 nt"
  41. "movq (%1), %%mm0 nt"
  42. "movq (%1, %3), %%mm1 nt"
  43. PAVGB" 1(%1), %%mm0 nt"
  44. PAVGB" 1(%1, %3), %%mm1 nt"
  45. "add %%"REG_a", %1 nt"
  46. "movq %%mm0, (%2) nt"
  47. "movq %%mm1, (%2, %3) nt"
  48. "add %%"REG_a", %2 nt"
  49. "subl $4, %0 nt"
  50. "jnz 1b nt"
  51. :"+g"(h), "+S"(pixels), "+D"(block)
  52. :"r" ((long)line_size)
  53. :"%"REG_a, "memory");
  54. }
  55. static void DEF(put_pixels4_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
  56. {
  57.     __asm __volatile(
  58. "testl $1, %0 nt"
  59.     " jz 1f nt"
  60. "movd (%1), %%mm0 nt"
  61. "movd (%2), %%mm1 nt"
  62. "add %4, %1 nt"
  63. "add $4, %2 nt"
  64. PAVGB" %%mm1, %%mm0 nt"
  65. "movd %%mm0, (%3) nt"
  66. "add %5, %3 nt"
  67. "decl %0 nt"
  68. "1: nt"
  69. "movd (%1), %%mm0 nt"
  70. "add %4, %1 nt"
  71. "movd (%1), %%mm1 nt"
  72. "movd (%2), %%mm2 nt"
  73. "movd 4(%2), %%mm3 nt"
  74. "add %4, %1 nt"
  75. PAVGB" %%mm2, %%mm0 nt"
  76. PAVGB" %%mm3, %%mm1 nt"
  77. "movd %%mm0, (%3) nt"
  78. "add %5, %3 nt"
  79. "movd %%mm1, (%3) nt"
  80. "add %5, %3 nt"
  81. "movd (%1), %%mm0 nt"
  82. "add %4, %1 nt"
  83. "movd (%1), %%mm1 nt"
  84. "movd 8(%2), %%mm2 nt"
  85. "movd 12(%2), %%mm3 nt"
  86. "add %4, %1 nt"
  87. PAVGB" %%mm2, %%mm0 nt"
  88. PAVGB" %%mm3, %%mm1 nt"
  89. "movd %%mm0, (%3) nt"
  90. "add %5, %3 nt"
  91. "movd %%mm1, (%3) nt"
  92. "add %5, %3 nt"
  93. "add $16, %2 nt"
  94. "subl $4, %0 nt"
  95. "jnz 1b nt"
  96. #ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used
  97. :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst)
  98. #else
  99. :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst)
  100. #endif
  101. :"S"((long)src1Stride), "D"((long)dstStride)
  102. :"memory"); 
  103. }
  104. static void DEF(put_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
  105. {
  106.     __asm __volatile(
  107. "testl $1, %0 nt"
  108.     " jz 1f nt"
  109. "movq (%1), %%mm0 nt"
  110. "movq (%2), %%mm1 nt"
  111. "add %4, %1 nt"
  112. "add $8, %2 nt"
  113. PAVGB" %%mm1, %%mm0 nt"
  114. "movq %%mm0, (%3) nt"
  115. "add %5, %3 nt"
  116. "decl %0 nt"
  117. "1: nt"
  118. "movq (%1), %%mm0 nt"
  119. "add %4, %1 nt"
  120. "movq (%1), %%mm1 nt"
  121. "add %4, %1 nt"
  122. PAVGB" (%2), %%mm0 nt"
  123. PAVGB" 8(%2), %%mm1 nt"
  124. "movq %%mm0, (%3) nt"
  125. "add %5, %3 nt"
  126. "movq %%mm1, (%3) nt"
  127. "add %5, %3 nt"
  128. "movq (%1), %%mm0 nt"
  129. "add %4, %1 nt"
  130. "movq (%1), %%mm1 nt"
  131. "add %4, %1 nt"
  132. PAVGB" 16(%2), %%mm0 nt"
  133. PAVGB" 24(%2), %%mm1 nt"
  134. "movq %%mm0, (%3) nt"
  135. "add %5, %3 nt"
  136. "movq %%mm1, (%3) nt"
  137. "add %5, %3 nt"
  138. "add $32, %2 nt"
  139. "subl $4, %0 nt"
  140. "jnz 1b nt"
  141. #ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used
  142. :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst)
  143. #else
  144. :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst)
  145. #endif
  146. :"S"((long)src1Stride), "D"((long)dstStride)
  147. :"memory"); 
  148. //the following should be used, though better not with gcc ...
  149. /* :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst)
  150. :"r"(src1Stride), "r"(dstStride)
  151. :"memory");*/
  152. }
  153. static void DEF(put_no_rnd_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
  154. {
  155.     __asm __volatile(
  156. "pcmpeqb %%mm6, %%mm6 nt"
  157. "testl $1, %0 nt"
  158.     " jz 1f nt"
  159. "movq (%1), %%mm0 nt"
  160. "movq (%2), %%mm1 nt"
  161. "add %4, %1 nt"
  162. "add $8, %2 nt"
  163. "pxor %%mm6, %%mm0 nt"
  164. "pxor %%mm6, %%mm1 nt"
  165. PAVGB" %%mm1, %%mm0 nt"
  166. "pxor %%mm6, %%mm0 nt"
  167. "movq %%mm0, (%3) nt"
  168. "add %5, %3 nt"
  169. "decl %0 nt"
  170. "1: nt"
  171. "movq (%1), %%mm0 nt"
  172. "add %4, %1 nt"
  173. "movq (%1), %%mm1 nt"
  174. "add %4, %1 nt"
  175. "movq (%2), %%mm2 nt"
  176. "movq 8(%2), %%mm3 nt"
  177. "pxor %%mm6, %%mm0 nt"
  178. "pxor %%mm6, %%mm1 nt"
  179. "pxor %%mm6, %%mm2 nt"
  180. "pxor %%mm6, %%mm3 nt"
  181. PAVGB" %%mm2, %%mm0 nt"
  182. PAVGB" %%mm3, %%mm1 nt"
  183. "pxor %%mm6, %%mm0 nt"
  184. "pxor %%mm6, %%mm1 nt"
  185. "movq %%mm0, (%3) nt"
  186. "add %5, %3 nt"
  187. "movq %%mm1, (%3) nt"
  188. "add %5, %3 nt"
  189. "movq (%1), %%mm0 nt"
  190. "add %4, %1 nt"
  191. "movq (%1), %%mm1 nt"
  192. "add %4, %1 nt"
  193. "movq 16(%2), %%mm2 nt"
  194. "movq 24(%2), %%mm3 nt"
  195. "pxor %%mm6, %%mm0 nt"
  196. "pxor %%mm6, %%mm1 nt"
  197. "pxor %%mm6, %%mm2 nt"
  198. "pxor %%mm6, %%mm3 nt"
  199. PAVGB" %%mm2, %%mm0 nt"
  200. PAVGB" %%mm3, %%mm1 nt"
  201. "pxor %%mm6, %%mm0 nt"
  202. "pxor %%mm6, %%mm1 nt"
  203. "movq %%mm0, (%3) nt"
  204. "add %5, %3 nt"
  205. "movq %%mm1, (%3) nt"
  206. "add %5, %3 nt"
  207. "add $32, %2 nt"
  208. "subl $4, %0 nt"
  209. "jnz 1b nt"
  210. #ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used
  211. :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst)
  212. #else
  213. :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst)
  214. #endif
  215. :"S"((long)src1Stride), "D"((long)dstStride)
  216. :"memory"); 
  217. //the following should be used, though better not with gcc ...
  218. /* :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst)
  219. :"r"(src1Stride), "r"(dstStride)
  220. :"memory");*/
  221. }
  222. static void DEF(avg_pixels4_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
  223. {
  224.     __asm __volatile(
  225. "testl $1, %0 nt"
  226.     " jz 1f nt"
  227. "movd (%1), %%mm0 nt"
  228. "movd (%2), %%mm1 nt"
  229. "add %4, %1 nt"
  230. "add $4, %2 nt"
  231. PAVGB" %%mm1, %%mm0 nt"
  232. PAVGB" (%3), %%mm0 nt"
  233. "movd %%mm0, (%3) nt"
  234. "add %5, %3 nt"
  235. "decl %0 nt"
  236. "1: nt"
  237. "movd (%1), %%mm0 nt"
  238. "add %4, %1 nt"
  239. "movd (%1), %%mm1 nt"
  240. "add %4, %1 nt"
  241. PAVGB" (%2), %%mm0 nt"
  242. PAVGB" 4(%2), %%mm1 nt"
  243. PAVGB" (%3), %%mm0   nt"
  244. "movd %%mm0, (%3) nt"
  245. "add %5, %3 nt"
  246. PAVGB" (%3), %%mm1   nt"
  247. "movd %%mm1, (%3) nt"
  248. "add %5, %3 nt"
  249. "movd (%1), %%mm0 nt"
  250. "add %4, %1 nt"
  251. "movd (%1), %%mm1 nt"
  252. "add %4, %1 nt"
  253. PAVGB" 8(%2), %%mm0 nt"
  254. PAVGB" 12(%2), %%mm1 nt"
  255. PAVGB" (%3), %%mm0   nt"
  256. "movd %%mm0, (%3) nt"
  257. "add %5, %3 nt"
  258. PAVGB" (%3), %%mm1   nt"
  259. "movd %%mm1, (%3) nt"
  260. "add %5, %3 nt"
  261. "add $16, %2 nt"
  262. "subl $4, %0 nt"
  263. "jnz 1b nt"
  264. #ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used
  265. :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst)
  266. #else
  267. :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst)
  268. #endif
  269. :"S"((long)src1Stride), "D"((long)dstStride)
  270. :"memory"); 
  271. }
  272. static void DEF(avg_pixels8_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
  273. {
  274.     __asm __volatile(
  275. "testl $1, %0 nt"
  276.     " jz 1f nt"
  277. "movq (%1), %%mm0 nt"
  278. "movq (%2), %%mm1 nt"
  279. "add %4, %1 nt"
  280. "add $8, %2 nt"
  281. PAVGB" %%mm1, %%mm0 nt"
  282. PAVGB" (%3), %%mm0 nt"
  283. "movq %%mm0, (%3) nt"
  284. "add %5, %3 nt"
  285. "decl %0 nt"
  286. "1: nt"
  287. "movq (%1), %%mm0 nt"
  288. "add %4, %1 nt"
  289. "movq (%1), %%mm1 nt"
  290. "add %4, %1 nt"
  291. PAVGB" (%2), %%mm0 nt"
  292. PAVGB" 8(%2), %%mm1 nt"
  293. PAVGB" (%3), %%mm0   nt"
  294. "movq %%mm0, (%3) nt"
  295. "add %5, %3 nt"
  296. PAVGB" (%3), %%mm1   nt"
  297. "movq %%mm1, (%3) nt"
  298. "add %5, %3 nt"
  299. "movq (%1), %%mm0 nt"
  300. "add %4, %1 nt"
  301. "movq (%1), %%mm1 nt"
  302. "add %4, %1 nt"
  303. PAVGB" 16(%2), %%mm0 nt"
  304. PAVGB" 24(%2), %%mm1 nt"
  305. PAVGB" (%3), %%mm0   nt"
  306. "movq %%mm0, (%3) nt"
  307. "add %5, %3 nt"
  308. PAVGB" (%3), %%mm1   nt"
  309. "movq %%mm1, (%3) nt"
  310. "add %5, %3 nt"
  311. "add $32, %2 nt"
  312. "subl $4, %0 nt"
  313. "jnz 1b nt"
  314. #ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used
  315. :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst)
  316. #else
  317. :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst)
  318. #endif
  319. :"S"((long)src1Stride), "D"((long)dstStride)
  320. :"memory"); 
  321. //the following should be used, though better not with gcc ...
  322. /* :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst)
  323. :"r"(src1Stride), "r"(dstStride)
  324. :"memory");*/
  325. }
  326. static void DEF(put_pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
  327. {
  328.     __asm __volatile(
  329. "lea (%3, %3), %%"REG_a" nt"
  330. "1: nt"
  331. "movq (%1), %%mm0 nt"
  332. "movq (%1, %3), %%mm1 nt"
  333. "movq 8(%1), %%mm2 nt"
  334. "movq 8(%1, %3), %%mm3 nt"
  335. PAVGB" 1(%1), %%mm0 nt"
  336. PAVGB" 1(%1, %3), %%mm1 nt"
  337. PAVGB" 9(%1), %%mm2 nt"
  338. PAVGB" 9(%1, %3), %%mm3 nt"
  339. "movq %%mm0, (%2) nt"
  340. "movq %%mm1, (%2, %3) nt"
  341. "movq %%mm2, 8(%2) nt"
  342. "movq %%mm3, 8(%2, %3) nt"
  343. "add %%"REG_a", %1 nt"
  344. "add %%"REG_a", %2 nt"
  345. "movq (%1), %%mm0 nt"
  346. "movq (%1, %3), %%mm1 nt"
  347. "movq 8(%1), %%mm2 nt"
  348. "movq 8(%1, %3), %%mm3 nt"
  349. PAVGB" 1(%1), %%mm0 nt"
  350. PAVGB" 1(%1, %3), %%mm1 nt"
  351. PAVGB" 9(%1), %%mm2 nt"
  352. PAVGB" 9(%1, %3), %%mm3 nt"
  353. "add %%"REG_a", %1 nt"
  354. "movq %%mm0, (%2) nt"
  355. "movq %%mm1, (%2, %3) nt"
  356. "movq %%mm2, 8(%2) nt"
  357. "movq %%mm3, 8(%2, %3) nt"
  358. "add %%"REG_a", %2 nt"
  359. "subl $4, %0 nt"
  360. "jnz 1b nt"
  361. :"+g"(h), "+S"(pixels), "+D"(block)
  362. :"r" ((long)line_size)
  363. :"%"REG_a, "memory");
  364. }
  365. static void DEF(put_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
  366. {
  367.     __asm __volatile(
  368. "testl $1, %0 nt"
  369.     " jz 1f nt"
  370. "movq (%1), %%mm0 nt"
  371. "movq 8(%1), %%mm1 nt"
  372. PAVGB" (%2), %%mm0 nt"
  373. PAVGB" 8(%2), %%mm1 nt"
  374. "add %4, %1 nt"
  375. "add $16, %2 nt"
  376. "movq %%mm0, (%3) nt"
  377. "movq %%mm1, 8(%3) nt"
  378. "add %5, %3 nt"
  379. "decl %0 nt"
  380. "1: nt"
  381. "movq (%1), %%mm0 nt"
  382. "movq 8(%1), %%mm1 nt"
  383. "add %4, %1 nt"
  384. PAVGB" (%2), %%mm0 nt"
  385. PAVGB" 8(%2), %%mm1 nt"
  386. "movq %%mm0, (%3) nt"
  387. "movq %%mm1, 8(%3) nt"
  388. "add %5, %3 nt"
  389. "movq (%1), %%mm0 nt"
  390. "movq 8(%1), %%mm1 nt"
  391. "add %4, %1 nt"
  392. PAVGB" 16(%2), %%mm0 nt"
  393. PAVGB" 24(%2), %%mm1 nt"
  394. "movq %%mm0, (%3) nt"
  395. "movq %%mm1, 8(%3) nt"
  396. "add %5, %3 nt"
  397. "add $32, %2 nt"
  398. "subl $2, %0 nt"
  399. "jnz 1b nt"
  400. #ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used
  401. :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst)
  402. #else
  403. :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst)
  404. #endif
  405. :"S"((long)src1Stride), "D"((long)dstStride)
  406. :"memory"); 
  407. //the following should be used, though better not with gcc ...
  408. /* :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst)
  409. :"r"(src1Stride), "r"(dstStride)
  410. :"memory");*/
  411. }
  412. static void DEF(avg_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
  413. {
  414.     __asm __volatile(
  415. "testl $1, %0 nt"
  416.     " jz 1f nt"
  417. "movq (%1), %%mm0 nt"
  418. "movq 8(%1), %%mm1 nt"
  419. PAVGB" (%2), %%mm0 nt"
  420. PAVGB" 8(%2), %%mm1 nt"
  421. "add %4, %1 nt"
  422. "add $16, %2 nt"
  423. PAVGB" (%3), %%mm0 nt"
  424. PAVGB" 8(%3), %%mm1 nt"
  425. "movq %%mm0, (%3) nt"
  426. "movq %%mm1, 8(%3) nt"
  427. "add %5, %3 nt"
  428. "decl %0 nt"
  429. "1: nt"
  430. "movq (%1), %%mm0 nt"
  431. "movq 8(%1), %%mm1 nt"
  432. "add %4, %1 nt"
  433. PAVGB" (%2), %%mm0 nt"
  434. PAVGB" 8(%2), %%mm1 nt"
  435. PAVGB" (%3), %%mm0 nt"
  436. PAVGB" 8(%3), %%mm1 nt"
  437. "movq %%mm0, (%3) nt"
  438. "movq %%mm1, 8(%3) nt"
  439. "add %5, %3 nt"
  440. "movq (%1), %%mm0 nt"
  441. "movq 8(%1), %%mm1 nt"
  442. "add %4, %1 nt"
  443. PAVGB" 16(%2), %%mm0 nt"
  444. PAVGB" 24(%2), %%mm1 nt"
  445. PAVGB" (%3), %%mm0 nt"
  446. PAVGB" 8(%3), %%mm1 nt"
  447. "movq %%mm0, (%3) nt"
  448. "movq %%mm1, 8(%3) nt"
  449. "add %5, %3 nt"
  450. "add $32, %2 nt"
  451. "subl $2, %0 nt"
  452. "jnz 1b nt"
  453. #ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used
  454. :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst)
  455. #else
  456. :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst)
  457. #endif
  458. :"S"((long)src1Stride), "D"((long)dstStride)
  459. :"memory"); 
  460. //the following should be used, though better not with gcc ...
  461. /* :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst)
  462. :"r"(src1Stride), "r"(dstStride)
  463. :"memory");*/
  464. }
  465. static void DEF(put_no_rnd_pixels16_l2)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h)
  466. {
  467.     __asm __volatile(
  468. "pcmpeqb %%mm6, %%mm6nt"
  469. "testl $1, %0 nt"
  470.     " jz 1f nt"
  471. "movq (%1), %%mm0 nt"
  472. "movq 8(%1), %%mm1 nt"
  473. "movq (%2), %%mm2 nt"
  474. "movq 8(%2), %%mm3 nt"
  475. "pxor %%mm6, %%mm0 nt"
  476. "pxor %%mm6, %%mm1 nt"
  477. "pxor %%mm6, %%mm2 nt"
  478. "pxor %%mm6, %%mm3 nt"
  479. PAVGB" %%mm2, %%mm0 nt"
  480. PAVGB" %%mm3, %%mm1 nt"
  481. "pxor %%mm6, %%mm0 nt"
  482. "pxor %%mm6, %%mm1 nt"
  483. "add %4, %1 nt"
  484. "add $16, %2 nt"
  485. "movq %%mm0, (%3) nt"
  486. "movq %%mm1, 8(%3) nt"
  487. "add %5, %3 nt"
  488. "decl %0 nt"
  489. "1: nt"
  490. "movq (%1), %%mm0 nt"
  491. "movq 8(%1), %%mm1 nt"
  492. "add %4, %1 nt"
  493. "movq (%2), %%mm2 nt"
  494. "movq 8(%2), %%mm3 nt"
  495. "pxor %%mm6, %%mm0 nt"
  496. "pxor %%mm6, %%mm1 nt"
  497. "pxor %%mm6, %%mm2 nt"
  498. "pxor %%mm6, %%mm3 nt"
  499. PAVGB" %%mm2, %%mm0 nt"
  500. PAVGB" %%mm3, %%mm1 nt"
  501. "pxor %%mm6, %%mm0 nt"
  502. "pxor %%mm6, %%mm1 nt"
  503. "movq %%mm0, (%3) nt"
  504. "movq %%mm1, 8(%3) nt"
  505. "add %5, %3 nt"
  506. "movq (%1), %%mm0 nt"
  507. "movq 8(%1), %%mm1 nt"
  508. "add %4, %1 nt"
  509. "movq 16(%2), %%mm2 nt"
  510. "movq 24(%2), %%mm3 nt"
  511. "pxor %%mm6, %%mm0 nt"
  512. "pxor %%mm6, %%mm1 nt"
  513. "pxor %%mm6, %%mm2 nt"
  514. "pxor %%mm6, %%mm3 nt"
  515. PAVGB" %%mm2, %%mm0 nt"
  516. PAVGB" %%mm3, %%mm1 nt"
  517. "pxor %%mm6, %%mm0 nt"
  518. "pxor %%mm6, %%mm1 nt"
  519. "movq %%mm0, (%3) nt"
  520. "movq %%mm1, 8(%3) nt"
  521. "add %5, %3 nt"
  522. "add $32, %2 nt"
  523. "subl $2, %0 nt"
  524. "jnz 1b nt"
  525. #ifdef PIC //Note "+bm" and "+mb" are buggy too (with gcc 3.2.2 at least) and cant be used
  526. :"+m"(h), "+a"(src1), "+c"(src2), "+d"(dst)
  527. #else
  528. :"+b"(h), "+a"(src1), "+c"(src2), "+d"(dst)
  529. #endif
  530. :"S"((long)src1Stride), "D"((long)dstStride)
  531. :"memory"); 
  532. //the following should be used, though better not with gcc ...
  533. /* :"+g"(h), "+r"(src1), "+r"(src2), "+r"(dst)
  534. :"r"(src1Stride), "r"(dstStride)
  535. :"memory");*/
  536. }
  537.  
  538. /* GL: this function does incorrect rounding if overflow */
  539. static void DEF(put_no_rnd_pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
  540. {
  541.     MOVQ_BONE(mm6);
  542.     __asm __volatile(
  543. "lea (%3, %3), %%"REG_a" nt"
  544. "1: nt"
  545. "movq (%1), %%mm0 nt"
  546. "movq (%1, %3), %%mm2 nt"
  547. "movq 1(%1), %%mm1 nt"
  548. "movq 1(%1, %3), %%mm3 nt"
  549. "add %%"REG_a", %1 nt"
  550. "psubusb %%mm6, %%mm0 nt"
  551. "psubusb %%mm6, %%mm2 nt"
  552. PAVGB" %%mm1, %%mm0 nt"
  553. PAVGB" %%mm3, %%mm2 nt"
  554. "movq %%mm0, (%2) nt"
  555. "movq %%mm2, (%2, %3) nt"
  556. "movq (%1), %%mm0 nt"
  557. "movq 1(%1), %%mm1 nt"
  558. "movq (%1, %3), %%mm2 nt"
  559. "movq 1(%1, %3), %%mm3 nt"
  560. "add %%"REG_a", %2 nt"
  561. "add %%"REG_a", %1 nt"
  562. "psubusb %%mm6, %%mm0 nt"
  563. "psubusb %%mm6, %%mm2 nt"
  564. PAVGB" %%mm1, %%mm0 nt"
  565. PAVGB" %%mm3, %%mm2 nt"
  566. "movq %%mm0, (%2) nt"
  567. "movq %%mm2, (%2, %3) nt"
  568. "add %%"REG_a", %2 nt"
  569. "subl $4, %0 nt"
  570. "jnz 1b nt"
  571. :"+g"(h), "+S"(pixels), "+D"(block)
  572. :"r" ((long)line_size)
  573. :"%"REG_a, "memory");
  574. }
  575. static void DEF(put_pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
  576. {
  577.     __asm __volatile(
  578. "lea (%3, %3), %%"REG_a" nt"
  579. "movq (%1), %%mm0 nt"
  580. "sub %3, %2 nt"
  581. "1: nt"
  582. "movq (%1, %3), %%mm1 nt"
  583. "movq (%1, %%"REG_a"), %%mm2 nt"
  584. "add %%"REG_a", %1 nt"
  585. PAVGB" %%mm1, %%mm0 nt"
  586. PAVGB" %%mm2, %%mm1 nt"
  587. "movq %%mm0, (%2, %3) nt"
  588. "movq %%mm1, (%2, %%"REG_a") nt"
  589. "movq (%1, %3), %%mm1 nt"
  590. "movq (%1, %%"REG_a"), %%mm0 nt"
  591. "add %%"REG_a", %2 nt"
  592. "add %%"REG_a", %1 nt"
  593. PAVGB" %%mm1, %%mm2 nt"
  594. PAVGB" %%mm0, %%mm1 nt"
  595. "movq %%mm2, (%2, %3) nt"
  596. "movq %%mm1, (%2, %%"REG_a") nt"
  597. "add %%"REG_a", %2 nt"
  598. "subl $4, %0 nt"
  599. "jnz 1b nt"
  600. :"+g"(h), "+S"(pixels), "+D" (block)
  601. :"r" ((long)line_size)
  602. :"%"REG_a, "memory");
  603. }
  604. /* GL: this function does incorrect rounding if overflow */
  605. static void DEF(put_no_rnd_pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
  606. {
  607.     MOVQ_BONE(mm6);
  608.     __asm __volatile(
  609. "lea (%3, %3), %%"REG_a" nt"
  610. "movq (%1), %%mm0 nt"
  611. "sub %3, %2 nt"
  612. "1: nt"
  613. "movq (%1, %3), %%mm1 nt"
  614. "movq (%1, %%"REG_a"), %%mm2 nt"
  615. "add %%"REG_a", %1 nt"
  616. "psubusb %%mm6, %%mm1 nt"
  617. PAVGB" %%mm1, %%mm0 nt"
  618. PAVGB" %%mm2, %%mm1 nt"
  619. "movq %%mm0, (%2, %3) nt"
  620. "movq %%mm1, (%2, %%"REG_a") nt"
  621. "movq (%1, %3), %%mm1 nt"
  622. "movq (%1, %%"REG_a"), %%mm0 nt"
  623. "add %%"REG_a", %2 nt"
  624. "add %%"REG_a", %1 nt"
  625. "psubusb %%mm6, %%mm1 nt"
  626. PAVGB" %%mm1, %%mm2 nt"
  627. PAVGB" %%mm0, %%mm1 nt"
  628. "movq %%mm2, (%2, %3) nt"
  629. "movq %%mm1, (%2, %%"REG_a") nt"
  630. "add %%"REG_a", %2 nt"
  631. "subl $4, %0 nt"
  632. "jnz 1b nt"
  633. :"+g"(h), "+S"(pixels), "+D" (block)
  634. :"r" ((long)line_size)
  635. :"%"REG_a, "memory");
  636. }
  637. static void DEF(avg_pixels8)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
  638. {
  639.     __asm __volatile(
  640. "lea (%3, %3), %%"REG_a" nt"
  641. "1: nt"
  642. "movq (%2), %%mm0 nt"
  643. "movq (%2, %3), %%mm1 nt"
  644. PAVGB" (%1), %%mm0 nt"
  645. PAVGB" (%1, %3), %%mm1 nt"
  646. "movq %%mm0, (%2) nt"
  647. "movq %%mm1, (%2, %3) nt"
  648. "add %%"REG_a", %1 nt"
  649. "add %%"REG_a", %2 nt"
  650. "movq (%2), %%mm0 nt"
  651. "movq (%2, %3), %%mm1 nt"
  652. PAVGB" (%1), %%mm0 nt"
  653. PAVGB" (%1, %3), %%mm1 nt"
  654. "add %%"REG_a", %1 nt"
  655. "movq %%mm0, (%2) nt"
  656. "movq %%mm1, (%2, %3) nt"
  657. "add %%"REG_a", %2 nt"
  658. "subl $4, %0 nt"
  659. "jnz 1b nt"
  660. :"+g"(h), "+S"(pixels), "+D"(block)
  661. :"r" ((long)line_size)
  662. :"%"REG_a, "memory");
  663. }
  664. static void DEF(avg_pixels8_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
  665. {
  666.     __asm __volatile(
  667. "lea (%3, %3), %%"REG_a" nt"
  668. "1: nt"
  669. "movq (%1), %%mm0 nt"
  670. "movq (%1, %3), %%mm2 nt"
  671. PAVGB" 1(%1), %%mm0 nt"
  672. PAVGB" 1(%1, %3), %%mm2 nt"
  673. PAVGB" (%2), %%mm0 nt"
  674. PAVGB" (%2, %3), %%mm2 nt"
  675. "add %%"REG_a", %1 nt"
  676. "movq %%mm0, (%2) nt"
  677. "movq %%mm2, (%2, %3) nt"
  678. "movq (%1), %%mm0 nt"
  679. "movq (%1, %3), %%mm2 nt"
  680. PAVGB" 1(%1), %%mm0 nt"
  681. PAVGB" 1(%1, %3), %%mm2 nt"
  682. "add %%"REG_a", %2 nt"
  683. "add %%"REG_a", %1 nt"
  684. PAVGB" (%2), %%mm0 nt"
  685. PAVGB" (%2, %3), %%mm2 nt"
  686. "movq %%mm0, (%2) nt"
  687. "movq %%mm2, (%2, %3) nt"
  688. "add %%"REG_a", %2 nt"
  689. "subl $4, %0 nt"
  690. "jnz 1b nt"
  691. :"+g"(h), "+S"(pixels), "+D"(block)
  692. :"r" ((long)line_size)
  693. :"%"REG_a, "memory");
  694. }
  695. static void DEF(avg_pixels8_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
  696. {
  697.     __asm __volatile(
  698. "lea (%3, %3), %%"REG_a" nt"
  699. "movq (%1), %%mm0 nt"
  700. "sub %3, %2 nt"
  701. "1: nt"
  702. "movq (%1, %3), %%mm1 nt"
  703. "movq (%1, %%"REG_a"), %%mm2 nt"
  704. "add %%"REG_a", %1 nt"
  705. PAVGB" %%mm1, %%mm0 nt"
  706. PAVGB" %%mm2, %%mm1 nt"
  707. "movq (%2, %3), %%mm3 nt"
  708. "movq (%2, %%"REG_a"), %%mm4 nt"
  709. PAVGB" %%mm3, %%mm0 nt"
  710. PAVGB" %%mm4, %%mm1 nt"
  711. "movq %%mm0, (%2, %3) nt"
  712. "movq %%mm1, (%2, %%"REG_a") nt"
  713. "movq (%1, %3), %%mm1 nt"
  714. "movq (%1, %%"REG_a"), %%mm0 nt"
  715. PAVGB" %%mm1, %%mm2 nt"
  716. PAVGB" %%mm0, %%mm1 nt"
  717. "add %%"REG_a", %2 nt"
  718. "add %%"REG_a", %1 nt"
  719. "movq (%2, %3), %%mm3 nt"
  720. "movq (%2, %%"REG_a"), %%mm4 nt"
  721. PAVGB" %%mm3, %%mm2 nt"
  722. PAVGB" %%mm4, %%mm1 nt"
  723. "movq %%mm2, (%2, %3) nt"
  724. "movq %%mm1, (%2, %%"REG_a") nt"
  725. "add %%"REG_a", %2 nt"
  726. "subl $4, %0 nt"
  727. "jnz 1b nt"
  728. :"+g"(h), "+S"(pixels), "+D"(block)
  729. :"r" ((long)line_size)
  730. :"%"REG_a, "memory");
  731. }
  732. // Note this is not correctly rounded, but this function is only used for b frames so it doesnt matter 
  733. static void DEF(avg_pixels8_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h)
  734. {
  735.     MOVQ_BONE(mm6);
  736.     __asm __volatile(
  737. "lea (%3, %3), %%"REG_a" nt"
  738. "movq (%1), %%mm0 nt"
  739. PAVGB" 1(%1), %%mm0 nt"
  740. ".balign 8 nt"
  741. "1: nt"
  742. "movq (%1, %%"REG_a"), %%mm2 nt"
  743. "movq (%1, %3), %%mm1 nt"
  744. "psubusb %%mm6, %%mm2 nt"
  745. PAVGB" 1(%1, %3), %%mm1 nt"
  746. PAVGB" 1(%1, %%"REG_a"), %%mm2 nt"
  747. "add %%"REG_a", %1 nt"
  748. PAVGB" %%mm1, %%mm0 nt"
  749. PAVGB" %%mm2, %%mm1 nt"
  750. PAVGB" (%2), %%mm0 nt"
  751. PAVGB" (%2, %3), %%mm1 nt"
  752. "movq %%mm0, (%2) nt"
  753. "movq %%mm1, (%2, %3) nt"
  754. "movq (%1, %3), %%mm1 nt"
  755. "movq (%1, %%"REG_a"), %%mm0 nt"
  756. PAVGB" 1(%1, %3), %%mm1 nt"
  757. PAVGB" 1(%1, %%"REG_a"), %%mm0 nt"
  758. "add %%"REG_a", %2 nt"
  759. "add %%"REG_a", %1 nt"
  760. PAVGB" %%mm1, %%mm2 nt"
  761. PAVGB" %%mm0, %%mm1 nt"
  762. PAVGB" (%2), %%mm2 nt"
  763. PAVGB" (%2, %3), %%mm1 nt"
  764. "movq %%mm2, (%2) nt"
  765. "movq %%mm1, (%2, %3) nt"
  766. "add %%"REG_a", %2 nt"
  767. "subl $4, %0 nt"
  768. "jnz 1b nt"
  769. :"+g"(h), "+S"(pixels), "+D"(block)
  770. :"r" ((long)line_size)
  771. :"%"REG_a,  "memory");
  772. }
  773. //FIXME the following could be optimized too ...
  774. static void DEF(put_no_rnd_pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
  775.     DEF(put_no_rnd_pixels8_x2)(block  , pixels  , line_size, h);
  776.     DEF(put_no_rnd_pixels8_x2)(block+8, pixels+8, line_size, h);
  777. }
  778. static void DEF(put_pixels16_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
  779.     DEF(put_pixels8_y2)(block  , pixels  , line_size, h);
  780.     DEF(put_pixels8_y2)(block+8, pixels+8, line_size, h);
  781. }
  782. static void DEF(put_no_rnd_pixels16_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
  783.     DEF(put_no_rnd_pixels8_y2)(block  , pixels  , line_size, h);
  784.     DEF(put_no_rnd_pixels8_y2)(block+8, pixels+8, line_size, h);
  785. }
  786. static void DEF(avg_pixels16)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
  787.     DEF(avg_pixels8)(block  , pixels  , line_size, h);
  788.     DEF(avg_pixels8)(block+8, pixels+8, line_size, h);
  789. }
  790. static void DEF(avg_pixels16_x2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
  791.     DEF(avg_pixels8_x2)(block  , pixels  , line_size, h);
  792.     DEF(avg_pixels8_x2)(block+8, pixels+8, line_size, h);
  793. }
  794. static void DEF(avg_pixels16_y2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
  795.     DEF(avg_pixels8_y2)(block  , pixels  , line_size, h);
  796.     DEF(avg_pixels8_y2)(block+8, pixels+8, line_size, h);
  797. }
  798. static void DEF(avg_pixels16_xy2)(uint8_t *block, const uint8_t *pixels, int line_size, int h){
  799.     DEF(avg_pixels8_xy2)(block  , pixels  , line_size, h);
  800.     DEF(avg_pixels8_xy2)(block+8, pixels+8, line_size, h);
  801. }