sad_mmx.asm
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:20k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. ;/**************************************************************************
  2. ; *
  3. ; * XVID MPEG-4 VIDEO CODEC
  4. ; * mmx/xmm sum of absolute difference
  5. ; *
  6. ; * This program is an implementation of a part of one or more MPEG-4
  7. ; * Video tools as specified in ISO/IEC 14496-2 standard.  Those intending
  8. ; * to use this software module in hardware or software products are
  9. ; * advised that its use may infringe existing patents or copyrights, and
  10. ; * any such use would be at such party's own risk.  The original
  11. ; * developer of this software module and his/her company, and subsequent
  12. ; * editors and their companies, will have no liability for use of this
  13. ; * software or modifications or derivatives thereof.
  14. ; *
  15. ; * This program is free software; you can redistribute it and/or modify
  16. ; * it under the terms of the GNU General Public License as published by
  17. ; * the Free Software Foundation; either version 2 of the License, or
  18. ; * (at your option) any later version.
  19. ; *
  20. ; * This program is distributed in the hope that it will be useful,
  21. ; * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23. ; * GNU General Public License for more details.
  24. ; *
  25. ; * You should have received a copy of the GNU General Public License
  26. ; * along with this program; if not, write to the Free Software
  27. ; * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  28. ; *
  29. ; *************************************************************************/
  30. ;/**************************************************************************
  31. ; *
  32. ; * History:
  33. ; *
  34. ; * 17.11.2001  bugfix and small improvement for dev16_xmm,
  35. ; *             removed terminate early in sad16_xmm 
  36. ; * 12.11.2001 inital version; (c)2001 peter ross <pross@cs.rmit.edu.au>
  37. ; *
  38. ; *************************************************************************/
  39. bits 32
  40. %macro cglobal 1 
  41. %ifdef PREFIX
  42. global _%1 
  43. %define %1 _%1
  44. %else
  45. global %1
  46. %endif
  47. %endmacro
  48. section .data
  49. align 16
  50. mmx_one times 4 dw 1
  51. section .text
  52. ;===========================================================================
  53. ;
  54. ; uint32_t sad16_mmx(const uint8_t * const cur,
  55. ; const uint8_t * const ref,
  56. ; const uint32_t stride,
  57. ; const uint32_t best_sad);
  58. ;
  59. ; (early termination ignore; slows this down)
  60. ;
  61. ;===========================================================================
  62. align 16
  63. cglobal sad16_mmx
  64. sad16_mmx
  65. push esi
  66. push edi
  67. mov esi, [esp + 8 + 4] ; ref
  68. mov edi, [esp + 8 + 8] ; cur
  69. mov ecx, [esp + 8 + 12] ; stride
  70. mov edx, 16
  71. pxor mm6, mm6 ; mm6 = sum = 0
  72. pxor mm7, mm7 ; mm7 = 0
  73. .loop
  74. movq mm0, [esi] ; ref
  75. movq mm1, [edi] ; cur
  76. movq mm2, [esi+8] ; ref2
  77. movq mm3, [edi+8] ; cur2
  78. movq mm4, mm0 
  79. movq mm5, mm2
  80. psubusb mm0, mm1
  81. psubusb mm2, mm3
  82. psubusb mm1, mm4
  83. psubusb mm3, mm5
  84. por mm0, mm1 ; mm0 = |ref - cur|
  85. por mm2, mm3 ; mm2 = |ref2 - cur2|
  86. movq mm1,mm0
  87. movq mm3,mm2
  88. punpcklbw mm0,mm7
  89. punpcklbw mm2,mm7
  90. punpckhbw mm1,mm7
  91. punpckhbw mm3,mm7
  92. paddusw mm0,mm1
  93. paddusw mm2,mm3
  94. paddusw mm6,mm0 ; sum += mm01
  95. paddusw mm6,mm2 ; sum += mm23
  96. add esi, ecx
  97. add edi, ecx
  98. dec edx
  99. jnz .loop
  100. pmaddwd mm6, [mmx_one] ; merge sum
  101. movq mm7, mm6
  102. psrlq mm7, 32 
  103. paddd mm6, mm7
  104. movd eax, mm6
  105. pop  edi
  106. pop  esi
  107. ret
  108. ;===========================================================================
  109. ;
  110. ; uint32_t sad16_xmm(const uint8_t * const cur,
  111. ; const uint8_t * const ref,
  112. ; const uint32_t stride,
  113. ; const uint32_t best_sad);
  114. ;
  115. ; experimental!
  116. ;
  117. ;===========================================================================
  118. align 16
  119. cglobal sad16_xmm
  120. sad16_xmm
  121. push esi
  122. push edi
  123. push ebx
  124. mov esi, [esp + 12 + 4] ; ref
  125. mov edi, [esp + 12 + 8] ; cur
  126. mov ecx, [esp + 12 + 12] ; stride
  127. mov ebx, [esp + 12 + 16] ; best_sad
  128. ; mov edx, 16
  129. pxor mm6, mm6 ; mm6 = sum = 0
  130. ;.loop
  131. movq mm0, [esi] ; ref
  132. movq mm2, [esi+8] ; ref2
  133. psadbw mm0, [edi] ; mm0 = |ref - cur|
  134. psadbw mm2, [edi+8] ; mm0 = |ref2 - cur2|
  135. paddusw mm6,mm0 ; sum += mm01
  136. paddusw mm6,mm2 ; sum += mm23
  137. add esi, ecx
  138. add edi, ecx
  139. ; dec edx
  140. ; jnz .loop
  141. movq mm0, [esi]
  142. movq mm2, [esi+8]
  143. psadbw mm0, [edi]
  144. psadbw mm2, [edi+8]
  145. paddusw mm6,mm0
  146. paddusw mm6,mm2
  147. add esi, ecx
  148. add edi, ecx
  149. movq mm0, [esi]
  150. movq mm2, [esi+8]
  151. psadbw mm0, [edi]
  152. psadbw mm2, [edi+8]
  153. paddusw mm6,mm0
  154. paddusw mm6,mm2
  155. add esi, ecx
  156. add edi, ecx
  157. movq mm0, [esi]
  158. movq mm2, [esi+8]
  159. psadbw mm0, [edi]
  160. psadbw mm2, [edi+8]
  161. paddusw mm6,mm0
  162. paddusw mm6,mm2
  163. add esi, ecx
  164. add edi, ecx
  165. movq mm0, [esi]
  166. movq mm2, [esi+8]
  167. psadbw mm0, [edi]
  168. psadbw mm2, [edi+8]
  169. paddusw mm6,mm0
  170. paddusw mm6,mm2
  171. add esi, ecx
  172. add edi, ecx
  173. movq mm0, [esi]
  174. movq mm2, [esi+8]
  175. psadbw mm0, [edi]
  176. psadbw mm2, [edi+8]
  177. paddusw mm6,mm0
  178. paddusw mm6,mm2
  179. add esi, ecx
  180. add edi, ecx
  181. movq mm0, [esi]
  182. movq mm2, [esi+8]
  183. psadbw mm0, [edi]
  184. psadbw mm2, [edi+8]
  185. paddusw mm6,mm0
  186. paddusw mm6,mm2
  187. add esi, ecx
  188. add edi, ecx
  189. movq mm0, [esi]
  190. movq mm2, [esi+8]
  191. psadbw mm0, [edi]
  192. psadbw mm2, [edi+8]
  193. paddusw mm6,mm0
  194. paddusw mm6,mm2
  195. add esi, ecx
  196. add edi, ecx
  197. movq mm0, [esi]
  198. movq mm2, [esi+8]
  199. psadbw mm0, [edi]
  200. psadbw mm2, [edi+8]
  201. paddusw mm6,mm0
  202. paddusw mm6,mm2
  203. add esi, ecx
  204. add edi, ecx
  205. movq mm0, [esi]
  206. movq mm2, [esi+8]
  207. psadbw mm0, [edi]
  208. psadbw mm2, [edi+8]
  209. paddusw mm6,mm0
  210. paddusw mm6,mm2
  211. add esi, ecx
  212. add edi, ecx
  213. movq mm0, [esi]
  214. movq mm2, [esi+8]
  215. psadbw mm0, [edi]
  216. psadbw mm2, [edi+8]
  217. paddusw mm6,mm0
  218. paddusw mm6,mm2
  219. add esi, ecx
  220. add edi, ecx
  221. movq mm0, [esi]
  222. movq mm2, [esi+8]
  223. psadbw mm0, [edi]
  224. psadbw mm2, [edi+8]
  225. paddusw mm6,mm0
  226. paddusw mm6,mm2
  227. add esi, ecx
  228. add edi, ecx
  229. movq mm0, [esi]
  230. movq mm2, [esi+8]
  231. psadbw mm0, [edi]
  232. psadbw mm2, [edi+8]
  233. paddusw mm6,mm0
  234. paddusw mm6,mm2
  235. add esi, ecx
  236. add edi, ecx
  237. movq mm0, [esi]
  238. movq mm2, [esi+8]
  239. psadbw mm0, [edi]
  240. psadbw mm2, [edi+8]
  241. paddusw mm6,mm0
  242. paddusw mm6,mm2
  243. add esi, ecx
  244. add edi, ecx
  245. movq mm0, [esi]
  246. movq mm2, [esi+8]
  247. psadbw mm0, [edi]
  248. psadbw mm2, [edi+8]
  249. paddusw mm6,mm0
  250. paddusw mm6,mm2
  251. add esi, ecx
  252. add edi, ecx
  253. movq mm0, [esi]
  254. movq mm2, [esi+8]
  255. psadbw mm0, [edi]
  256. psadbw mm2, [edi+8]
  257. paddusw mm6,mm0
  258. paddusw mm6,mm2
  259. movd eax, mm6
  260. .ret pop ebx
  261. pop  edi
  262. pop  esi
  263. ret
  264. ;===========================================================================
  265. ;
  266. ; uint32_t sad16_sse2(const uint8_t * const cur,
  267. ; const uint8_t * const ref,
  268. ; const uint32_t stride,
  269. ; const uint32_t best_sad);
  270. ;
  271. ;===========================================================================
  272. align 16
  273. cglobal sad16_sse2
  274. sad16_sse2
  275. push esi
  276. push edi
  277. push ebx
  278. mov esi, [esp + 12 + 4] ; ref
  279. mov edi, [esp + 12 + 8] ; cur
  280. mov ecx, [esp + 12 + 12] ; stride
  281. mov ebx, [esp + 12 + 16] ; best_sad
  282. mov edx, 16
  283. pxor xmm2, xmm2 ; xmm2 = sum = 0
  284. ; 0
  285. movdqu xmm0, [esi] ; ref
  286. movdqu xmm1, [edi] ; cur
  287. psadbw xmm0, xmm1 ; xmm0 = |ref - cur|
  288. paddusw xmm2,xmm0 ; sum += xmm0
  289. add esi, ecx
  290. add edi, ecx
  291. ; 1
  292. movdqu xmm0, [esi] ; ref
  293. movdqu xmm1, [edi] ; cur
  294. psadbw xmm0, xmm1 ; xmm0 = |ref - cur|
  295. paddusw xmm2,xmm0 ; sum += xmm0
  296. add esi, ecx
  297. add edi, ecx
  298. ; 2
  299. movdqu xmm0, [esi] ; ref
  300. movdqu xmm1, [edi] ; cur
  301. psadbw xmm0, xmm1 ; xmm0 = |ref - cur|
  302. paddusw xmm2,xmm0 ; sum += xmm0
  303. add esi, ecx
  304. add edi, ecx
  305. ; 3
  306. movdqu xmm0, [esi] ; ref
  307. movdqu xmm1, [edi] ; cur
  308. psadbw xmm0, xmm1 ; xmm0 = |ref - cur|
  309. paddusw xmm2,xmm0 ; sum += xmm0
  310. add esi, ecx
  311. add edi, ecx
  312. ; 4
  313. movdqu xmm0, [esi] ; ref
  314. movdqu xmm1, [edi] ; cur
  315. psadbw xmm0, xmm1 ; xmm0 = |ref - cur|
  316. paddusw xmm2,xmm0 ; sum += xmm0
  317. add esi, ecx
  318. add edi, ecx
  319. ; 5
  320. movdqu xmm0, [esi] ; ref
  321. movdqu xmm1, [edi] ; cur
  322. psadbw xmm0, xmm1 ; xmm0 = |ref - cur|
  323. paddusw xmm2,xmm0 ; sum += xmm0
  324. add esi, ecx
  325. add edi, ecx
  326. ; 6
  327. movdqu xmm0, [esi] ; ref
  328. movdqu xmm1, [edi] ; cur
  329. psadbw xmm0, xmm1 ; xmm0 = |ref - cur|
  330. paddusw xmm2,xmm0 ; sum += xmm0
  331. add esi, ecx
  332. add edi, ecx
  333. ; 7
  334. movdqu xmm0, [esi] ; ref
  335. movdqu xmm1, [edi] ; cur
  336. psadbw xmm0, xmm1 ; xmm0 = |ref - cur|
  337. paddusw xmm2,xmm0 ; sum += xmm0
  338. add esi, ecx
  339. add edi, ecx
  340. ; 8
  341. movdqu xmm0, [esi] ; ref
  342. movdqu xmm1, [edi] ; cur
  343. psadbw xmm0, xmm1 ; xmm0 = |ref - cur|
  344. paddusw xmm2,xmm0 ; sum += xmm0
  345. add esi, ecx
  346. add edi, ecx
  347. ; 9
  348. movdqu xmm0, [esi] ; ref
  349. movdqu xmm1, [edi] ; cur
  350. psadbw xmm0, xmm1 ; xmm0 = |ref - cur|
  351. paddusw xmm2,xmm0 ; sum += xmm0
  352. add esi, ecx
  353. add edi, ecx
  354. ; 10
  355. movdqu xmm0, [esi] ; ref
  356. movdqu xmm1, [edi] ; cur
  357. psadbw xmm0, xmm1 ; xmm0 = |ref - cur|
  358. paddusw xmm2,xmm0 ; sum += xmm0
  359. add esi, ecx
  360. add edi, ecx
  361. ; 11
  362. movdqu xmm0, [esi] ; ref
  363. movdqu xmm1, [edi] ; cur
  364. psadbw xmm0, xmm1 ; xmm0 = |ref - cur|
  365. paddusw xmm2,xmm0 ; sum += xmm0
  366. add esi, ecx
  367. add edi, ecx
  368. ; 12
  369. movdqu xmm0, [esi] ; ref
  370. movdqu xmm1, [edi] ; cur
  371. psadbw xmm0, xmm1 ; xmm0 = |ref - cur|
  372. paddusw xmm2,xmm0 ; sum += xmm0
  373. add esi, ecx
  374. add edi, ecx
  375. ; 13
  376. movdqu xmm0, [esi] ; ref
  377. movdqu xmm1, [edi] ; cur
  378. psadbw xmm0, xmm1 ; xmm0 = |ref - cur|
  379. paddusw xmm2,xmm0 ; sum += xmm0
  380. add esi, ecx
  381. add edi, ecx
  382. ; 14
  383. movdqu xmm0, [esi] ; ref
  384. movdqu xmm1, [edi] ; cur
  385. psadbw xmm0, xmm1 ; xmm0 = |ref - cur|
  386. paddusw xmm2,xmm0 ; sum += xmm0
  387. add esi, ecx
  388. add edi, ecx
  389. ; 15
  390. movdqu xmm0, [esi] ; ref
  391. movdqu xmm1, [edi] ; cur
  392. psadbw xmm0, xmm1 ; xmm0 = |ref - cur|
  393. paddusw xmm2,xmm0 ; sum += xmm0
  394. movd eax, xmm2
  395. psrldq xmm2, 8
  396. movd ecx, xmm2
  397. add eax, ecx
  398. .ret pop ebx
  399. pop  edi
  400. pop  esi
  401. ret
  402. ;===========================================================================
  403. ;
  404. ; uint32_t sad8_mmx(const uint8_t * const cur,
  405. ; const uint8_t * const ref,
  406. ; const uint32_t stride);
  407. ;
  408. ;===========================================================================
  409. align 16
  410. cglobal sad8_mmx
  411. sad8_mmx
  412. push  esi
  413. push  edi
  414. mov  esi, [esp + 8 + 4] ; ref
  415. mov  edi, [esp + 8 + 8] ; cur
  416. mov  ecx, [esp + 8 + 12] ; stride
  417. mov eax, 4
  418. pxor mm6, mm6 ; mm6 = sum = 0
  419. pxor mm7, mm7 ; mm7 = 0
  420. .loop
  421. movq mm0, [esi] ; ref
  422. movq mm1, [edi] ; cur
  423. movq mm2, [esi+ecx] ; ref2
  424. movq mm3, [edi+ecx] ; cur2
  425. movq mm4, mm0 
  426. movq mm5, mm2
  427. psubusb mm0, mm1
  428. psubusb mm2, mm3
  429. psubusb mm1, mm4
  430. psubusb mm3, mm5
  431. por mm0, mm1 ; mm0 = |ref - cur|
  432. por mm2, mm3 ; mm2 = |ref2 - cur2|
  433. movq mm1,mm0
  434. movq mm3,mm2
  435. punpcklbw mm0,mm7
  436. punpcklbw mm2,mm7
  437. punpckhbw mm1,mm7
  438. punpckhbw mm3,mm7
  439. paddusw mm0,mm1
  440. paddusw mm2,mm3
  441. paddusw mm6,mm0 ; sum += mm01
  442. paddusw mm6,mm2 ; sum += mm23
  443. add esi, ecx
  444. add edi, ecx
  445. add esi, ecx
  446. add edi, ecx
  447. dec eax
  448. jnz .loop
  449. pmaddwd mm6, [mmx_one] ; merge sum
  450. movq mm7, mm6
  451. psrlq mm7, 32 
  452. paddd mm6, mm7
  453. movd eax, mm6
  454. pop  edi
  455. pop  esi
  456. ret
  457. ;===========================================================================
  458. ;
  459. ; uint32_t sad8_xmm(const uint8_t * const cur,
  460. ; const uint8_t * const ref,
  461. ; const uint32_t stride);
  462. ;
  463. ; experimental!
  464. ;
  465. ;===========================================================================
  466. align 16
  467. cglobal sad8_xmm
  468. sad8_xmm
  469. push  esi
  470. push  edi
  471. mov  esi, [esp + 8 + 4] ; ref
  472. mov  edi, [esp + 8 + 8] ; cur
  473. mov  ecx, [esp + 8 + 12] ; stride
  474. mov     edx, ecx
  475. shl     edx, 1
  476. ; mov eax, 4
  477. pxor mm6, mm6 ; mm6 = sum = 0
  478. ;.loop
  479. movq mm0, [esi] ; ref
  480. movq mm2, [esi+ecx] ; ref2
  481. psadbw mm0, [edi] ; mm0 = |ref - cur|
  482. psadbw mm2, [edi+ecx] ; mm0 = |ref2 - cur2|
  483. paddusw mm6,mm0 ; sum += mm01
  484. paddusw mm6,mm2 ; sum += mm23
  485. add esi, edx
  486. add edi, edx
  487. ; dec eax
  488. ; jnz .loop
  489. movq mm0, [esi]
  490. movq mm2, [esi+ecx]
  491. psadbw mm0, [edi]
  492. psadbw mm2, [edi+ecx]
  493. paddusw mm6,mm0
  494. paddusw mm6,mm2
  495. add esi, edx
  496. add edi, edx
  497. movq mm0, [esi]
  498. movq mm2, [esi+ecx]
  499. psadbw mm0, [edi]
  500. psadbw mm2, [edi+ecx]
  501. paddusw mm6,mm0
  502. paddusw mm6,mm2
  503. add esi, edx
  504. add edi, edx
  505. movq mm0, [esi]
  506. movq mm2, [esi+ecx]
  507. psadbw mm0, [edi]
  508. psadbw mm2, [edi+ecx]
  509. paddusw mm6,mm0
  510. paddusw mm6,mm2
  511. movd eax, mm6
  512. pop  edi
  513. pop  esi
  514. ret
  515. ;===========================================================================
  516. ;
  517. ; uint32_t dev16_mmx(const uint8_t * const cur,
  518. ; const uint32_t stride);
  519. ;
  520. ;===========================================================================
  521. align 16
  522. cglobal dev16_mmx
  523. dev16_mmx
  524. push  esi
  525. push  edi
  526. pxor mm4, mm4 ; mm23 = sum = 0
  527. pxor mm5, mm5
  528. mov  esi, [esp + 8 + 4] ; cur
  529. mov  ecx, [esp + 8 + 8] ; stride
  530. mov     edi, esi
  531. mov eax, 16
  532. pxor mm7, mm7 ; mm7 = 0
  533. .loop1
  534. movq mm0, [esi]
  535. movq mm2, [esi + 8]
  536. movq mm1, mm0
  537. movq mm3, mm2
  538. punpcklbw mm0, mm7
  539. punpcklbw mm2, mm7
  540. punpckhbw mm1, mm7
  541. punpckhbw mm3, mm7
  542. paddw mm0, mm1
  543. paddw mm2, mm3
  544. paddw mm4, mm0
  545. paddw mm5, mm2
  546. add esi, ecx
  547. dec eax
  548. jnz .loop1
  549. paddusw mm4, mm5
  550. pmaddwd mm4, [mmx_one] ; merge sum
  551. movq mm5, mm4
  552. psrlq mm5, 32 
  553. paddd mm4, mm5
  554. psllq mm4, 32 ; blank upper dword
  555. psrlq mm4, 32 + 8 ; mm4 /= (16*16)
  556. punpckldq mm4, mm4
  557. packssdw mm4, mm4 ; mm4 = mean
  558. pxor mm6, mm6 ; mm6 = dev = 0
  559. mov eax, 16
  560. .loop2
  561. movq mm0, [edi]
  562. movq mm2, [edi + 8]
  563. movq mm1, mm0
  564. movq mm3, mm2
  565. punpcklbw mm0, mm7
  566. punpcklbw mm2, mm7
  567. punpckhbw mm1, mm7 ; mm01 = cur
  568. punpckhbw mm3, mm7 ; mm23 = cur2
  569. movq mm5, mm4 ;
  570. psubusw mm5, mm0 ;
  571. psubusw mm0, mm4 ;
  572. por mm0, mm5 ;
  573. movq mm5, mm4 ;
  574. psubusw mm5, mm1 ;
  575. psubusw mm1, mm4 ;
  576. por mm1, mm5 ; mm01 = |mm01 - mm4|
  577. movq mm5, mm4 ;
  578. psubusw mm5, mm2 ;
  579. psubusw mm2, mm4 ;
  580. por mm2, mm5 ;
  581. movq mm5, mm4 ;
  582. psubusw mm5, mm3 ;
  583. psubusw mm3, mm4 ;
  584. por mm3, mm5 ; mm23 = |mm23 - mm4|
  585. paddw mm0, mm1
  586. paddw mm2, mm3
  587. paddw mm6, mm0
  588. paddw mm6, mm2 ; dev += mm01 + mm23
  589. add edi, ecx
  590. dec eax
  591. jnz .loop2
  592. pmaddwd mm6, [mmx_one] ; merge dev
  593. movq mm7, mm6
  594. psrlq mm7, 32 
  595. paddd mm6, mm7
  596. movd eax, mm6
  597. pop  edi
  598. pop  esi
  599. ret
  600. ;===========================================================================
  601. ;
  602. ; uint32_t dev16_xmm(const uint8_t * const cur,
  603. ; const uint32_t stride);
  604. ;
  605. ; experimental!
  606. ;
  607. ;===========================================================================
  608. align 16
  609. cglobal dev16_xmm
  610. dev16_xmm
  611. push  esi
  612. push  edi
  613. pxor mm4, mm4 ; mm23 = sum = 0
  614. mov  esi, [esp + 8 + 4] ; cur
  615. mov  ecx, [esp + 8 + 8] ; stride
  616. mov     edi, esi
  617. ; mov eax, 16
  618. pxor mm7, mm7 ; mm7 = 0
  619. ;.loop1
  620. movq mm0, [esi]
  621. movq mm2, [esi + 8]
  622. psadbw mm0, mm7 ; abs(cur0 - 0) + abs(cur1 - 0) + ... + abs(cur7 - 0) -> mm0
  623. psadbw mm2, mm7 ; abs(cur8 - 0) + abs(cur9 - 0) + ... + abs(cur15 - 0) -> mm2
  624. paddw mm4,mm0 ; mean += mm0
  625. paddw mm4,mm2 ; mean += mm2
  626. add esi, ecx
  627. ; dec eax
  628. ; jnz .loop1
  629. movq mm0, [esi]
  630. movq mm2, [esi + 8]
  631. psadbw mm0, mm7
  632. psadbw mm2, mm7
  633. paddw mm4,mm0
  634. paddw mm4,mm2
  635. add esi, ecx
  636. movq mm0, [esi]
  637. movq mm2, [esi + 8]
  638. psadbw mm0, mm7
  639. psadbw mm2, mm7
  640. paddw mm4,mm0
  641. paddw mm4,mm2
  642. add esi, ecx
  643. movq mm0, [esi]
  644. movq mm2, [esi + 8]
  645. psadbw mm0, mm7
  646. psadbw mm2, mm7
  647. paddw mm4,mm0
  648. paddw mm4,mm2
  649. add esi, ecx
  650. movq mm0, [esi]
  651. movq mm2, [esi + 8]
  652. psadbw mm0, mm7
  653. psadbw mm2, mm7
  654. paddw mm4,mm0
  655. paddw mm4,mm2
  656. add esi, ecx
  657. movq mm0, [esi]
  658. movq mm2, [esi + 8]
  659. psadbw mm0, mm7
  660. psadbw mm2, mm7
  661. paddw mm4,mm0
  662. paddw mm4,mm2
  663. add esi, ecx
  664. movq mm0, [esi]
  665. movq mm2, [esi + 8]
  666. psadbw mm0, mm7
  667. psadbw mm2, mm7
  668. paddw mm4,mm0
  669. paddw mm4,mm2
  670. add esi, ecx
  671. movq mm0, [esi]
  672. movq mm2, [esi + 8]
  673. psadbw mm0, mm7
  674. psadbw mm2, mm7
  675. paddw mm4,mm0
  676. paddw mm4,mm2
  677. add esi, ecx
  678. movq mm0, [esi]
  679. movq mm2, [esi + 8]
  680. psadbw mm0, mm7
  681. psadbw mm2, mm7
  682. paddw mm4,mm0
  683. paddw mm4,mm2
  684. add esi, ecx
  685. movq mm0, [esi]
  686. movq mm2, [esi + 8]
  687. psadbw mm0, mm7
  688. psadbw mm2, mm7
  689. paddw mm4,mm0
  690. paddw mm4,mm2
  691. add esi, ecx
  692. movq mm0, [esi]
  693. movq mm2, [esi + 8]
  694. psadbw mm0, mm7
  695. psadbw mm2, mm7
  696. paddw mm4,mm0
  697. paddw mm4,mm2
  698. add esi, ecx
  699. movq mm0, [esi]
  700. movq mm2, [esi + 8]
  701. psadbw mm0, mm7
  702. psadbw mm2, mm7
  703. paddw mm4,mm0
  704. paddw mm4,mm2
  705. add esi, ecx
  706. movq mm0, [esi]
  707. movq mm2, [esi + 8]
  708. psadbw mm0, mm7
  709. psadbw mm2, mm7
  710. paddw mm4,mm0
  711. paddw mm4,mm2
  712. add esi, ecx
  713. movq mm0, [esi]
  714. movq mm2, [esi + 8]
  715. psadbw mm0, mm7
  716. psadbw mm2, mm7
  717. paddw mm4,mm0
  718. paddw mm4,mm2
  719. add esi, ecx
  720. movq mm0, [esi]
  721. movq mm2, [esi + 8]
  722. psadbw mm0, mm7
  723. psadbw mm2, mm7
  724. paddw mm4,mm0
  725. paddw mm4,mm2
  726. add esi, ecx
  727. movq mm0, [esi]
  728. movq mm2, [esi + 8]
  729. psadbw mm0, mm7
  730. psadbw mm2, mm7
  731. paddw mm4,mm0
  732. paddw mm4,mm2
  733. movq mm5, mm4
  734. psllq mm5, 32 
  735. paddd mm4, mm5
  736. psrld mm4, 8
  737. packssdw mm4, mm4
  738. packuswb mm4, mm4
  739. pxor mm6, mm6 ; mm6 = dev = 0
  740. ; mov eax, 16
  741. ;.loop2
  742. movq mm0, [edi]
  743. movq mm2, [edi + 8]
  744. psadbw mm0, mm4 ; mm0 = |cur - mean|
  745. psadbw mm2, mm4 ; mm0 = |cur2 - mean|
  746. paddw mm6,mm0 ; dev += mm01
  747. paddw mm6,mm2 ; dev += mm23
  748. add edi, ecx
  749. ; dec eax
  750. ; jnz .loop2
  751. movq mm0, [edi]
  752. movq mm2, [edi + 8]
  753. psadbw mm0, mm4
  754. psadbw mm2, mm4
  755. paddw mm6,mm0
  756. paddw mm6,mm2
  757. add edi, ecx
  758. movq mm0, [edi]
  759. movq mm2, [edi + 8]
  760. psadbw mm0, mm4
  761. psadbw mm2, mm4
  762. paddw mm6,mm0
  763. paddw mm6,mm2
  764. add edi, ecx
  765. movq mm0, [edi]
  766. movq mm2, [edi + 8]
  767. psadbw mm0, mm4
  768. psadbw mm2, mm4
  769. paddw mm6,mm0
  770. paddw mm6,mm2
  771. add edi, ecx
  772. movq mm0, [edi]
  773. movq mm2, [edi + 8]
  774. psadbw mm0, mm4
  775. psadbw mm2, mm4
  776. paddw mm6,mm0
  777. paddw mm6,mm2
  778. add edi, ecx
  779. movq mm0, [edi]
  780. movq mm2, [edi + 8]
  781. psadbw mm0, mm4
  782. psadbw mm2, mm4
  783. paddw mm6,mm0
  784. paddw mm6,mm2
  785. add edi, ecx
  786. movq mm0, [edi]
  787. movq mm2, [edi + 8]
  788. psadbw mm0, mm4
  789. psadbw mm2, mm4
  790. paddw mm6,mm0
  791. paddw mm6,mm2
  792. add edi, ecx
  793. movq mm0, [edi]
  794. movq mm2, [edi + 8]
  795. psadbw mm0, mm4
  796. psadbw mm2, mm4
  797. paddw mm6,mm0
  798. paddw mm6,mm2
  799. add edi, ecx
  800. movq mm0, [edi]
  801. movq mm2, [edi + 8]
  802. psadbw mm0, mm4
  803. psadbw mm2, mm4
  804. paddw mm6,mm0
  805. paddw mm6,mm2
  806. add edi, ecx
  807. movq mm0, [edi]
  808. movq mm2, [edi + 8]
  809. psadbw mm0, mm4
  810. psadbw mm2, mm4
  811. paddw mm6,mm0
  812. paddw mm6,mm2
  813. add edi, ecx
  814. movq mm0, [edi]
  815. movq mm2, [edi + 8]
  816. psadbw mm0, mm4
  817. psadbw mm2, mm4
  818. paddw mm6,mm0
  819. paddw mm6,mm2
  820. add edi, ecx
  821. movq mm0, [edi]
  822. movq mm2, [edi + 8]
  823. psadbw mm0, mm4
  824. psadbw mm2, mm4
  825. paddw mm6,mm0
  826. paddw mm6,mm2
  827. add edi, ecx
  828. movq mm0, [edi]
  829. movq mm2, [edi + 8]
  830. psadbw mm0, mm4
  831. psadbw mm2, mm4
  832. paddw mm6,mm0
  833. paddw mm6,mm2
  834. add edi, ecx
  835. movq mm0, [edi]
  836. movq mm2, [edi + 8]
  837. psadbw mm0, mm4
  838. psadbw mm2, mm4
  839. paddw mm6,mm0
  840. paddw mm6,mm2
  841. add edi, ecx
  842. movq mm0, [edi]
  843. movq mm2, [edi + 8]
  844. psadbw mm0, mm4
  845. psadbw mm2, mm4
  846. paddw mm6,mm0
  847. paddw mm6,mm2
  848. add edi, ecx
  849. movq mm0, [edi]
  850. movq mm2, [edi + 8]
  851. psadbw mm0, mm4
  852. psadbw mm2, mm4
  853. paddw mm6,mm0
  854. paddw mm6,mm2
  855. movq mm7, mm6
  856. psllq mm7, 32 
  857. paddd mm6, mm7
  858. movd eax, mm6
  859. pop  edi
  860. pop  esi
  861. ret