pixel-a.asm
上传用户:lctgjx
上传日期:2022-06-04
资源大小:8887k
文件大小:58k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. ;*****************************************************************************
  2. ;* pixel.asm: h264 encoder library
  3. ;*****************************************************************************
  4. ;* Copyright (C) 2003-2008 x264 project
  5. ;*
  6. ;* Authors: Loren Merritt <lorenm@u.washington.edu>
  7. ;*          Holger Lubitz <holger@lubitz.org>
  8. ;*          Laurent Aimar <fenrir@via.ecp.fr>
  9. ;*          Alex Izvorski <aizvorksi@gmail.com>
  10. ;*          Jason Garrett-Glaser <darkshikari@gmail.com>
  11. ;*
  12. ;* This program is free software; you can redistribute it and/or modify
  13. ;* it under the terms of the GNU General Public License as published by
  14. ;* the Free Software Foundation; either version 2 of the License, or
  15. ;* (at your option) any later version.
  16. ;*
  17. ;* This program 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
  20. ;* GNU General Public License for more details.
  21. ;*
  22. ;* You should have received a copy of the GNU General Public License
  23. ;* along with this program; if not, write to the Free Software
  24. ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
  25. ;*****************************************************************************
  26. %include "x86inc.asm"
  27. %include "x86util.asm"
  28. SECTION_RODATA
  29. pw_1:      times 8 dw 1
  30. pw_00ff:   times 8 dw 0xff
  31. ssim_c1:   times 4 dd 416    ; .01*.01*255*255*64
  32. ssim_c2:   times 4 dd 235963 ; .03*.03*255*255*64*63
  33. mask_ff:   times 16 db 0xff
  34.            times 16 db 0
  35. mask_ac4:  dw 0, -1, -1, -1, 0, -1, -1, -1
  36. mask_ac4b: dw 0, -1, 0, -1, -1, -1, -1, -1
  37. mask_ac8:  dw 0, -1, -1, -1, -1, -1, -1, -1
  38. hsub_mul:  times 8 db 1, -1
  39. hmul_4p:   times 2 db 1, 1, 1, 1, 1, -1, 1, -1
  40. hmul_8p:   times 8 db 1
  41.            times 4 db 1, -1
  42. mask_10:   times 4 dw 0, -1
  43. mask_1100: times 2 dd 0, -1
  44. SECTION .text
  45. %macro HADDD 2 ; sum junk
  46. %if mmsize == 16
  47.     movhlps %2, %1
  48.     paddd   %1, %2
  49.     pshuflw %2, %1, 0xE
  50.     paddd   %1, %2
  51. %else
  52.     pshufw  %2, %1, 0xE
  53.     paddd   %1, %2
  54. %endif
  55. %endmacro
  56. %macro HADDW 2
  57.     pmaddwd %1, [pw_1 GLOBAL]
  58.     HADDD   %1, %2
  59. %endmacro
  60. %macro HADDUW 2
  61.     mova  %2, %1
  62.     pslld %1, 16
  63.     psrld %2, 16
  64.     psrld %1, 16
  65.     paddd %1, %2
  66.     HADDD %1, %2
  67. %endmacro
  68. ;=============================================================================
  69. ; SSD
  70. ;=============================================================================
  71. %macro SSD_LOAD_FULL 5
  72.     mova      m1, [r0+%1]
  73.     mova      m2, [r2+%2]
  74.     mova      m3, [r0+%3]
  75.     mova      m4, [r2+%4]
  76. %if %5
  77.     lea       r0, [r0+2*r1]
  78.     lea       r2, [r2+2*r3]
  79. %endif
  80. %endmacro
  81. %macro LOAD 5
  82.     movh      m%1, %3
  83.     movh      m%2, %4
  84. %if %5
  85.     lea       r0, [r0+2*r1]
  86. %endif
  87. %endmacro
  88. %macro JOIN 7
  89.     movh      m%3, %5
  90.     movh      m%4, %6
  91. %if %7
  92.     lea       r2, [r2+2*r3]
  93. %endif
  94.     punpcklbw m%1, m7
  95.     punpcklbw m%3, m7
  96.     psubw     m%1, m%3
  97.     punpcklbw m%2, m7
  98.     punpcklbw m%4, m7
  99.     psubw     m%2, m%4
  100. %endmacro
  101. %macro JOIN_SSE2 7
  102.     movh      m%3, %5
  103.     movh      m%4, %6
  104. %if %7
  105.     lea       r2, [r2+2*r3]
  106. %endif
  107.     punpcklqdq m%1, m%2
  108.     punpcklqdq m%3, m%4
  109.     DEINTB %2, %1, %4, %3, 7
  110.     psubw m%2, m%4
  111.     psubw m%1, m%3
  112. %endmacro
  113. %macro JOIN_SSSE3 7
  114.     movh      m%3, %5
  115.     movh      m%4, %6
  116. %if %7
  117.     lea       r2, [r2+2*r3]
  118. %endif
  119.     punpcklbw m%1, m%3
  120.     punpcklbw m%2, m%4
  121. %endmacro
  122. %macro SSD_LOAD_HALF 5
  123.     LOAD      1, 2, [r0+%1], [r0+%3], 1
  124.     JOIN      1, 2, 3, 4, [r2+%2], [r2+%4], 1
  125.     LOAD      3, 4, [r0+%1], [r0+%3], %5
  126.     JOIN      3, 4, 5, 6, [r2+%2], [r2+%4], %5
  127. %endmacro
  128. %macro SSD_CORE 7-8
  129. %ifidn %8, FULL
  130.     mova      m%6, m%2
  131.     mova      m%7, m%4
  132.     psubusb   m%2, m%1
  133.     psubusb   m%4, m%3
  134.     psubusb   m%1, m%6
  135.     psubusb   m%3, m%7
  136.     por       m%1, m%2
  137.     por       m%3, m%4
  138.     mova      m%2, m%1
  139.     mova      m%4, m%3
  140.     punpckhbw m%1, m%5
  141.     punpckhbw m%3, m%5
  142.     punpcklbw m%2, m%5
  143.     punpcklbw m%4, m%5
  144. %endif
  145.     pmaddwd   m%1, m%1
  146.     pmaddwd   m%2, m%2
  147.     pmaddwd   m%3, m%3
  148.     pmaddwd   m%4, m%4
  149. %endmacro
  150. %macro SSD_CORE_SSE2 7-8
  151. %ifidn %8, FULL
  152.     DEINTB %6, %1, %7, %2, %5
  153.     psubw m%6, m%7
  154.     psubw m%1, m%2
  155.     SWAP %2, %6
  156.     DEINTB %6, %3, %7, %4, %5
  157.     psubw m%6, m%7
  158.     psubw m%3, m%4
  159.     SWAP %4, %6
  160. %endif
  161.     pmaddwd   m%1, m%1
  162.     pmaddwd   m%2, m%2
  163.     pmaddwd   m%3, m%3
  164.     pmaddwd   m%4, m%4
  165. %endmacro
  166. %macro SSD_CORE_SSSE3 7-8
  167. %ifidn %8, FULL
  168.     mova      m%6, m%1
  169.     mova      m%7, m%3
  170.     punpcklbw m%1, m%2
  171.     punpcklbw m%3, m%4
  172.     punpckhbw m%6, m%2
  173.     punpckhbw m%7, m%4
  174.     SWAP %6, %2
  175.     SWAP %7, %4
  176. %endif
  177.     pmaddubsw m%1, m%5
  178.     pmaddubsw m%2, m%5
  179.     pmaddubsw m%3, m%5
  180.     pmaddubsw m%4, m%5
  181.     pmaddwd   m%1, m%1
  182.     pmaddwd   m%2, m%2
  183.     pmaddwd   m%3, m%3
  184.     pmaddwd   m%4, m%4
  185. %endmacro
  186. %macro SSD_END 1
  187.     paddd     m1, m2
  188.     paddd     m3, m4
  189. %if %1
  190.     paddd     m0, m1
  191. %else
  192.     SWAP      0, 1
  193. %endif
  194.     paddd     m0, m3
  195. %endmacro
  196. %macro SSD_ITER 7
  197.     SSD_LOAD_%1 %2,%3,%4,%5,%7
  198.     SSD_CORE  1, 2, 3, 4, 7, 5, 6, %1
  199.     SSD_END  %6
  200. %endmacro
  201. ;-----------------------------------------------------------------------------
  202. ; int x264_pixel_ssd_16x16_mmx( uint8_t *, int, uint8_t *, int )
  203. ;-----------------------------------------------------------------------------
  204. %macro SSD 3-4 0
  205. cglobal x264_pixel_ssd_%1x%2_%3, 4,4,%4
  206. %ifidn %3, ssse3
  207.     mova    m7, [hsub_mul GLOBAL]
  208. %elifidn %3, sse2
  209.     mova    m7, [pw_00ff GLOBAL]
  210. %elif %1 >= mmsize
  211.     pxor    m7, m7
  212. %endif
  213. %assign i 0
  214. %rep %2/4
  215. %if %1 > mmsize
  216.     SSD_ITER FULL, 0,  0,     mmsize,    mmsize, i, 0
  217.     SSD_ITER FULL, r1, r3, r1+mmsize, r3+mmsize, 1, 1
  218.     SSD_ITER FULL, 0,  0,     mmsize,    mmsize, 1, 0
  219.     SSD_ITER FULL, r1, r3, r1+mmsize, r3+mmsize, 1, i<%2/4-1
  220. %elif %1 == mmsize
  221.     SSD_ITER FULL, 0, 0, r1, r3, i, 1
  222.     SSD_ITER FULL, 0, 0, r1, r3, 1, i<%2/4-1
  223. %else
  224.     SSD_ITER HALF, 0, 0, r1, r3, i, i<%2/4-1
  225. %endif
  226. %assign i i+1
  227. %endrep
  228.     HADDD   m0, m1
  229.     movd   eax, m0
  230.     RET
  231. %endmacro
  232. INIT_MMX
  233. SSD 16, 16, mmx
  234. SSD 16,  8, mmx
  235. SSD  8, 16, mmx
  236. SSD  8,  8, mmx
  237. SSD  8,  4, mmx
  238. SSD  4,  8, mmx
  239. SSD  4,  4, mmx
  240. INIT_XMM
  241. SSD 16, 16, sse2slow, 8
  242. SSD 16,  8, sse2slow, 8
  243. SSD  8, 16, sse2slow, 8
  244. SSD  8,  8, sse2slow, 8
  245. SSD  8,  4, sse2slow, 8
  246. %define SSD_CORE SSD_CORE_SSE2
  247. %define JOIN JOIN_SSE2
  248. SSD 16, 16, sse2, 8
  249. SSD 16,  8, sse2, 8
  250. SSD  8, 16, sse2, 8
  251. SSD  8,  8, sse2, 8
  252. SSD  8,  4, sse2, 8
  253. %define SSD_CORE SSD_CORE_SSSE3
  254. %define JOIN JOIN_SSSE3
  255. SSD 16, 16, ssse3, 8
  256. SSD 16,  8, ssse3, 8
  257. SSD  8, 16, ssse3, 8
  258. SSD  8,  8, ssse3, 8
  259. SSD  8,  4, ssse3, 8
  260. INIT_MMX
  261. SSD  4,  8, ssse3
  262. SSD  4,  4, ssse3
  263. ;=============================================================================
  264. ; variance
  265. ;=============================================================================
  266. %macro VAR_START 1
  267.     pxor  m5, m5    ; sum
  268.     pxor  m6, m6    ; sum squared
  269. %if %1
  270.     mova  m7, [pw_00ff GLOBAL]
  271. %else
  272.     pxor  m7, m7    ; zero
  273. %endif
  274. %endmacro
  275. %macro VAR_END 1
  276.     HADDW   m5, m7
  277.     movd   r1d, m5
  278.     imul   r1d, r1d
  279.     HADDD   m6, m1
  280.     shr    r1d, %1
  281.     movd   eax, m6
  282.     sub    eax, r1d  ; sqr - (sum * sum >> shift)
  283.     RET
  284. %endmacro
  285. %macro VAR_CORE 0
  286.     paddw     m5, m0
  287.     paddw     m5, m3
  288.     paddw     m5, m1
  289.     paddw     m5, m4
  290.     pmaddwd   m0, m0
  291.     pmaddwd   m3, m3
  292.     pmaddwd   m1, m1
  293.     pmaddwd   m4, m4
  294.     paddd     m6, m0
  295.     paddd     m6, m3
  296.     paddd     m6, m1
  297.     paddd     m6, m4
  298. %endmacro
  299. %macro VAR_2ROW 2
  300.     mov      r2d, %2
  301. .loop:
  302.     mova      m0, [r0]
  303.     mova      m1, m0
  304.     mova      m3, [r0+%1]
  305.     mova      m4, m3
  306.     punpcklbw m0, m7
  307.     punpckhbw m1, m7
  308. %ifidn %1, r1
  309.     lea       r0, [r0+%1*2]
  310. %else
  311.     add       r0, r1
  312. %endif
  313.     punpcklbw m3, m7
  314.     punpckhbw m4, m7
  315.     dec r2d
  316.     VAR_CORE
  317.     jg .loop
  318. %endmacro
  319. ;-----------------------------------------------------------------------------
  320. ; int x264_pixel_var_wxh_mmxext( uint8_t *, int )
  321. ;-----------------------------------------------------------------------------
  322. INIT_MMX
  323. cglobal x264_pixel_var_16x16_mmxext, 2,3
  324.     VAR_START 0
  325.     VAR_2ROW 8, 16
  326.     VAR_END 8
  327. cglobal x264_pixel_var_8x8_mmxext, 2,3
  328.     VAR_START 0
  329.     VAR_2ROW r1, 4
  330.     VAR_END 6
  331. INIT_XMM
  332. cglobal x264_pixel_var_16x16_sse2, 2,3,8
  333.     VAR_START 1
  334.     mov      r2d, 8
  335. .loop:
  336.     mova      m0, [r0]
  337.     mova      m3, [r0+r1]
  338.     DEINTB    1, 0, 4, 3, 7
  339.     lea       r0, [r0+r1*2]
  340.     VAR_CORE
  341.     dec r2d
  342.     jg .loop
  343.     VAR_END 8
  344. cglobal x264_pixel_var_8x8_sse2, 2,4,8
  345.     VAR_START 1
  346.     mov      r2d, 2
  347.     lea       r3, [r1*3]
  348. .loop:
  349.     movh      m0, [r0]
  350.     movh      m3, [r0+r1]
  351.     movhps    m0, [r0+r1*2]
  352.     movhps    m3, [r0+r3]
  353.     DEINTB    1, 0, 4, 3, 7
  354.     lea       r0, [r0+r1*4]
  355.     VAR_CORE
  356.     dec r2d
  357.     jg .loop
  358.     VAR_END 6
  359. %macro VAR2_END 0
  360.     HADDW   m5, m7
  361.     movd   r1d, m5
  362.     imul   r1d, r1d
  363.     HADDD   m6, m1
  364.     shr    r1d, 6
  365.     movd   eax, m6
  366.     mov   [r4], eax
  367.     sub    eax, r1d  ; sqr - (sum * sum >> shift)
  368.     RET
  369. %endmacro
  370. ;-----------------------------------------------------------------------------
  371. ; int x264_pixel_var2_8x8_mmxext( uint8_t *, int, uint8_t *, int, int * )
  372. ;-----------------------------------------------------------------------------
  373. %ifndef ARCH_X86_64
  374. INIT_MMX
  375. cglobal x264_pixel_var2_8x8_mmxext, 5,6
  376.     VAR_START 0
  377.     mov      r5d, 8
  378. .loop:
  379.     movq      m0, [r0]
  380.     movq      m1, m0
  381.     movq      m4, m0
  382.     movq      m2, [r2]
  383.     movq      m3, m2
  384.     punpcklbw m0, m7
  385.     punpckhbw m1, m7
  386.     punpcklbw m2, m7
  387.     punpckhbw m3, m7
  388.     psubw     m0, m2
  389.     psubw     m1, m3
  390.     paddw     m5, m0
  391.     paddw     m5, m1
  392.     pmaddwd   m0, m0
  393.     pmaddwd   m1, m1
  394.     paddd     m6, m0
  395.     paddd     m6, m1
  396.     add       r0, r1
  397.     add       r2, r3
  398.     dec       r5d
  399.     jg .loop
  400.     VAR2_END
  401.     RET
  402. %endif
  403. INIT_XMM
  404. cglobal x264_pixel_var2_8x8_sse2, 5,6,8
  405.     VAR_START 1
  406.     mov      r5d, 4
  407. .loop:
  408.     movq      m1, [r0]
  409.     movhps    m1, [r0+r1]
  410.     movq      m3, [r2]
  411.     movhps    m3, [r2+r3]
  412.     DEINTB    0, 1, 2, 3, 7
  413.     psubw     m0, m2
  414.     psubw     m1, m3
  415.     paddw     m5, m0
  416.     paddw     m5, m1
  417.     pmaddwd   m0, m0
  418.     pmaddwd   m1, m1
  419.     paddd     m6, m0
  420.     paddd     m6, m1
  421.     lea       r0, [r0+r1*2]
  422.     lea       r2, [r2+r3*2]
  423.     dec      r5d
  424.     jg .loop
  425.     VAR2_END
  426.     RET
  427. cglobal x264_pixel_var2_8x8_ssse3, 5,6,8
  428.     pxor      m5, m5    ; sum
  429.     pxor      m6, m6    ; sum squared
  430.     mova      m7, [hsub_mul GLOBAL]
  431.     mov      r5d, 2
  432. .loop:
  433.     movq      m0, [r0]
  434.     movq      m2, [r2]
  435.     movq      m1, [r0+r1]
  436.     movq      m3, [r2+r3]
  437.     lea       r0, [r0+r1*2]
  438.     lea       r2, [r2+r3*2]
  439.     punpcklbw m0, m2
  440.     punpcklbw m1, m3
  441.     movq      m2, [r0]
  442.     movq      m3, [r2]
  443.     punpcklbw m2, m3
  444.     movq      m3, [r0+r1]
  445.     movq      m4, [r2+r3]
  446.     punpcklbw m3, m4
  447.     pmaddubsw m0, m7
  448.     pmaddubsw m1, m7
  449.     pmaddubsw m2, m7
  450.     pmaddubsw m3, m7
  451.     paddw     m5, m0
  452.     paddw     m5, m1
  453.     paddw     m5, m2
  454.     paddw     m5, m3
  455.     pmaddwd   m0, m0
  456.     pmaddwd   m1, m1
  457.     pmaddwd   m2, m2
  458.     pmaddwd   m3, m3
  459.     paddd     m6, m0
  460.     paddd     m6, m1
  461.     paddd     m6, m2
  462.     paddd     m6, m3
  463.     lea       r0, [r0+r1*2]
  464.     lea       r2, [r2+r3*2]
  465.     dec      r5d
  466.     jg .loop
  467.     VAR2_END
  468.     RET
  469. ;=============================================================================
  470. ; SATD
  471. ;=============================================================================
  472. %define TRANS TRANS_SSE2
  473. %macro JDUP_SSE2 2
  474.     punpckldq %1, %2
  475.     ; doesn't need to dup. sse2 does things by zero extending to words and full h_2d
  476. %endmacro
  477. %macro JDUP_CONROE 2
  478.     ; join 2x 32 bit and duplicate them
  479.     ; emulating shufps is faster on conroe
  480.     punpcklqdq %1, %2
  481.     movsldup %1, %1
  482. %endmacro
  483. %macro JDUP_PENRYN 2
  484.     ; just use shufps on anything post conroe
  485.     shufps %1, %2, 0
  486. %endmacro
  487. %macro HSUMSUB 5
  488.     pmaddubsw m%2, m%5
  489.     pmaddubsw m%1, m%5
  490.     pmaddubsw m%4, m%5
  491.     pmaddubsw m%3, m%5
  492. %endmacro
  493. %macro DIFF_UNPACK_SSE2 5
  494.     punpcklbw m%1, m%5
  495.     punpcklbw m%2, m%5
  496.     punpcklbw m%3, m%5
  497.     punpcklbw m%4, m%5
  498.     psubw m%1, m%2
  499.     psubw m%3, m%4
  500. %endmacro
  501. %macro DIFF_SUMSUB_SSSE3 5
  502.     HSUMSUB %1, %2, %3, %4, %5
  503.     psubw m%1, m%2
  504.     psubw m%3, m%4
  505. %endmacro
  506. %macro LOAD_DUP_2x4P 4 ; dst, tmp, 2* pointer
  507.     movd %1, %3
  508.     movd %2, %4
  509.     JDUP %1, %2
  510. %endmacro
  511. %macro LOAD_DUP_4x8P_CONROE 8 ; 4*dst, 4*pointer
  512.     movddup m%3, %6
  513.     movddup m%4, %8
  514.     movddup m%1, %5
  515.     movddup m%2, %7
  516. %endmacro
  517. %macro LOAD_DUP_4x8P_PENRYN 8
  518.     ; penryn and nehalem run punpcklqdq and movddup in different units
  519.     movh m%3, %6
  520.     movh m%4, %8
  521.     punpcklqdq m%3, m%3
  522.     movddup m%1, %5
  523.     punpcklqdq m%4, m%4
  524.     movddup m%2, %7
  525. %endmacro
  526. %macro LOAD_SUMSUB_8x2P 9
  527.     LOAD_DUP_4x8P %1, %2, %3, %4, %6, %7, %8, %9
  528.     DIFF_SUMSUB_SSSE3 %1, %3, %2, %4, %5
  529. %endmacro
  530. %macro LOAD_SUMSUB_8x4P_SSSE3 7-10 r0, r2, 0
  531. ; 4x dest, 2x tmp, 1x mul, [2* ptr], [increment?]
  532.     LOAD_SUMSUB_8x2P %1, %2, %5, %6, %7, [%8], [%9], [%8+r1], [%9+r3]
  533.     LOAD_SUMSUB_8x2P %3, %4, %5, %6, %7, [%8+2*r1], [%9+2*r3], [%8+r4], [%9+r5]
  534. %if %10
  535.     lea %8, [%8+4*r1]
  536.     lea %9, [%9+4*r3]
  537. %endif
  538. %endmacro
  539. %macro LOAD_SUMSUB_16P_SSSE3 7 ; 2*dst, 2*tmp, mul, 2*ptr
  540.     movddup m%1, [%7]
  541.     movddup m%2, [%7+8]
  542.     mova m%4, [%6]
  543.     movddup m%3, m%4
  544.     punpckhqdq m%4, m%4
  545.     DIFF_SUMSUB_SSSE3 %1, %3, %2, %4, %5
  546. %endmacro
  547. %macro LOAD_SUMSUB_16P_SSE2 7 ; 2*dst, 2*tmp, mask, 2*ptr
  548.     movu  m%4, [%7]
  549.     mova  m%2, [%6]
  550.     DEINTB %1, %2, %3, %4, %5
  551.     psubw m%1, m%3
  552.     psubw m%2, m%4
  553.     SUMSUB_BA m%1, m%2, m%3
  554. %endmacro
  555. %macro LOAD_SUMSUB_16x4P 10-13 r0, r2, none
  556. ; 8x dest, 1x tmp, 1x mul, [2* ptr] [2nd tmp]
  557.     LOAD_SUMSUB_16P %1, %5, %2, %3, %10, %11, %12
  558.     LOAD_SUMSUB_16P %2, %6, %3, %4, %10, %11+r1, %12+r3
  559.     LOAD_SUMSUB_16P %3, %7, %4, %9, %10, %11+2*r1, %12+2*r3
  560.     LOAD_SUMSUB_16P %4, %8, %13, %9, %10, %11+r4, %12+r5
  561. %endmacro
  562. ; in: r4=3*stride1, r5=3*stride2
  563. ; in: %2 = horizontal offset
  564. ; in: %3 = whether we need to increment pix1 and pix2
  565. ; clobber: m3..m7
  566. ; out: %1 = satd
  567. %macro SATD_4x4_MMX 3
  568.     %xdefine %%n n%1
  569.     LOAD_DIFF m4, m3, none, [r0+%2],      [r2+%2]
  570.     LOAD_DIFF m5, m3, none, [r0+r1+%2],   [r2+r3+%2]
  571.     LOAD_DIFF m6, m3, none, [r0+2*r1+%2], [r2+2*r3+%2]
  572.     LOAD_DIFF m7, m3, none, [r0+r4+%2],   [r2+r5+%2]
  573. %if %3
  574.     lea  r0, [r0+4*r1]
  575.     lea  r2, [r2+4*r3]
  576. %endif
  577.     HADAMARD4_2D 4, 5, 6, 7, 3, %%n
  578.     paddw m4, m6
  579.     SWAP %%n, 4
  580. %endmacro
  581. %macro SATD_8x4_SSE 8-9
  582. %ifidn %1, sse2
  583.     HADAMARD4_2D_SSE %2, %3, %4, %5, %6, amax
  584. %else
  585.     HADAMARD4_V m%2, m%3, m%4, m%5, m%6
  586.     ; doing the abs first is a slight advantage
  587.     ABS4 m%2, m%4, m%3, m%5, m%6, m%7
  588.     HADAMARD 1, max, %2, %4, %6, %7
  589. %endif
  590. %ifnidn %9, swap
  591.     paddw m%8, m%2
  592. %else
  593.     SWAP %8, %2
  594. %endif
  595. %ifidn %1, sse2
  596.     paddw m%8, m%4
  597. %else
  598.     HADAMARD 1, max, %3, %5, %6, %7
  599.     paddw m%8, m%3
  600. %endif
  601. %endmacro
  602. %macro SATD_START_MMX 0
  603.     lea  r4, [3*r1] ; 3*stride1
  604.     lea  r5, [3*r3] ; 3*stride2
  605. %endmacro
  606. %macro SATD_END_MMX 0
  607.     pshufw      m1, m0, 01001110b
  608.     paddw       m0, m1
  609.     pshufw      m1, m0, 10110001b
  610.     paddw       m0, m1
  611.     movd       eax, m0
  612.     and        eax, 0xffff
  613.     RET
  614. %endmacro
  615. ; FIXME avoid the spilling of regs to hold 3*stride.
  616. ; for small blocks on x86_32, modify pixel pointer instead.
  617. ;-----------------------------------------------------------------------------
  618. ; int x264_pixel_satd_16x16_mmxext (uint8_t *, int, uint8_t *, int )
  619. ;-----------------------------------------------------------------------------
  620. INIT_MMX
  621. cglobal x264_pixel_satd_16x4_internal_mmxext
  622.     SATD_4x4_MMX m2,  0, 0
  623.     SATD_4x4_MMX m1,  4, 0
  624.     paddw        m0, m2
  625.     SATD_4x4_MMX m2,  8, 0
  626.     paddw        m0, m1
  627.     SATD_4x4_MMX m1, 12, 0
  628.     paddw        m0, m2
  629.     paddw        m0, m1
  630.     ret
  631. cglobal x264_pixel_satd_8x8_internal_mmxext
  632.     SATD_4x4_MMX m2,  0, 0
  633.     SATD_4x4_MMX m1,  4, 1
  634.     paddw        m0, m2
  635.     paddw        m0, m1
  636. x264_pixel_satd_8x4_internal_mmxext:
  637.     SATD_4x4_MMX m2,  0, 0
  638.     SATD_4x4_MMX m1,  4, 0
  639.     paddw        m0, m2
  640.     paddw        m0, m1
  641.     ret
  642. cglobal x264_pixel_satd_16x16_mmxext, 4,6
  643.     SATD_START_MMX
  644.     pxor   m0, m0
  645. %rep 3
  646.     call x264_pixel_satd_16x4_internal_mmxext
  647.     lea  r0, [r0+4*r1]
  648.     lea  r2, [r2+4*r3]
  649. %endrep
  650.     call x264_pixel_satd_16x4_internal_mmxext
  651.     HADDUW m0, m1
  652.     movd  eax, m0
  653.     RET
  654. cglobal x264_pixel_satd_16x8_mmxext, 4,6
  655.     SATD_START_MMX
  656.     pxor   m0, m0
  657.     call x264_pixel_satd_16x4_internal_mmxext
  658.     lea  r0, [r0+4*r1]
  659.     lea  r2, [r2+4*r3]
  660.     call x264_pixel_satd_16x4_internal_mmxext
  661.     SATD_END_MMX
  662. cglobal x264_pixel_satd_8x16_mmxext, 4,6
  663.     SATD_START_MMX
  664.     pxor   m0, m0
  665.     call x264_pixel_satd_8x8_internal_mmxext
  666.     lea  r0, [r0+4*r1]
  667.     lea  r2, [r2+4*r3]
  668.     call x264_pixel_satd_8x8_internal_mmxext
  669.     SATD_END_MMX
  670. cglobal x264_pixel_satd_8x8_mmxext, 4,6
  671.     SATD_START_MMX
  672.     pxor   m0, m0
  673.     call x264_pixel_satd_8x8_internal_mmxext
  674.     SATD_END_MMX
  675. cglobal x264_pixel_satd_8x4_mmxext, 4,6
  676.     SATD_START_MMX
  677.     pxor   m0, m0
  678.     call x264_pixel_satd_8x4_internal_mmxext
  679.     SATD_END_MMX
  680. cglobal x264_pixel_satd_4x8_mmxext, 4,6
  681.     SATD_START_MMX
  682.     SATD_4x4_MMX m0, 0, 1
  683.     SATD_4x4_MMX m1, 0, 0
  684.     paddw  m0, m1
  685.     SATD_END_MMX
  686. cglobal x264_pixel_satd_4x4_mmxext, 4,6
  687.     SATD_START_MMX
  688.     SATD_4x4_MMX m0, 0, 0
  689.     SATD_END_MMX
  690. %macro SATD_START_SSE2 3
  691. %ifnidn %1, sse2
  692.     mova    %3, [hmul_8p GLOBAL]
  693. %endif
  694.     lea     r4, [3*r1]
  695.     lea     r5, [3*r3]
  696.     pxor    %2, %2
  697. %endmacro
  698. %macro SATD_END_SSE2 2
  699.     HADDW   %2, m7
  700.     movd   eax, %2
  701.     RET
  702. %endmacro
  703. %macro BACKUP_POINTERS 0
  704. %ifdef ARCH_X86_64
  705.     mov    r10, r0
  706.     mov    r11, r2
  707. %endif
  708. %endmacro
  709. %macro RESTORE_AND_INC_POINTERS 0
  710. %ifdef ARCH_X86_64
  711.     lea     r0, [r10+8]
  712.     lea     r2, [r11+8]
  713. %else
  714.     mov     r0, r0mp
  715.     mov     r2, r2mp
  716.     add     r0, 8
  717.     add     r2, 8
  718. %endif
  719. %endmacro
  720. ;-----------------------------------------------------------------------------
  721. ; int x264_pixel_satd_8x4_sse2 (uint8_t *, int, uint8_t *, int )
  722. ;-----------------------------------------------------------------------------
  723. %macro SATDS_SSE2 1
  724. INIT_XMM
  725. %ifnidn %1, sse2
  726. cglobal x264_pixel_satd_4x4_%1, 4, 6, 6
  727.     SATD_START_MMX
  728.     mova m4, [hmul_4p GLOBAL]
  729.     LOAD_DUP_2x4P m2, m5, [r2], [r2+r3]
  730.     LOAD_DUP_2x4P m3, m5, [r2+2*r3], [r2+r5]
  731.     LOAD_DUP_2x4P m0, m5, [r0], [r0+r1]
  732.     LOAD_DUP_2x4P m1, m5, [r0+2*r1], [r0+r4]
  733.     DIFF_SUMSUB_SSSE3 0, 2, 1, 3, 4
  734.     HADAMARD 0, sumsub, 0, 1, 2, 3
  735.     HADAMARD 4, sumsub, 0, 1, 2, 3
  736.     HADAMARD 1, amax, 0, 1, 2, 3
  737.     HADDW m0, m1
  738.     movd eax, m0
  739.     RET
  740. %endif
  741. cglobal x264_pixel_satd_4x8_%1, 4, 6, 8
  742.     SATD_START_MMX
  743. %ifnidn %1, sse2
  744.     mova m7, [hmul_4p GLOBAL]
  745. %endif
  746.     movd m4, [r2]
  747.     movd m5, [r2+r3]
  748.     movd m6, [r2+2*r3]
  749.     add r2, r5
  750.     movd m0, [r0]
  751.     movd m1, [r0+r1]
  752.     movd m2, [r0+2*r1]
  753.     add r0, r4
  754.     movd m3, [r2+r3]
  755.     JDUP m4, m3
  756.     movd m3, [r0+r1]
  757.     JDUP m0, m3
  758.     movd m3, [r2+2*r3]
  759.     JDUP m5, m3
  760.     movd m3, [r0+2*r1]
  761.     JDUP m1, m3
  762.     DIFFOP 0, 4, 1, 5, 7
  763.     movd m5, [r2]
  764.     add r2, r5
  765.     movd m3, [r0]
  766.     add r0, r4
  767.     movd m4, [r2]
  768.     JDUP m6, m4
  769.     movd m4, [r0]
  770.     JDUP m2, m4
  771.     movd m4, [r2+r3]
  772.     JDUP m5, m4
  773.     movd m4, [r0+r1]
  774.     JDUP m3, m4
  775.     DIFFOP 2, 6, 3, 5, 7
  776.     SATD_8x4_SSE %1, 0, 1, 2, 3, 4, 5, 6, swap
  777.     HADDW m6, m1
  778.     movd eax, m6
  779.     RET
  780. cglobal x264_pixel_satd_8x8_internal_%1
  781.     LOAD_SUMSUB_8x4P 0, 1, 2, 3, 4, 5, 7, r0, r2, 1
  782.     SATD_8x4_SSE %1, 0, 1, 2, 3, 4, 5, 6
  783. x264_pixel_satd_8x4_internal_%1:
  784.     LOAD_SUMSUB_8x4P 0, 1, 2, 3, 4, 5, 7, r0, r2, 1
  785.     SATD_8x4_SSE %1, 0, 1, 2, 3, 4, 5, 6
  786.     ret
  787. %ifdef UNIX64 ; 16x8 regresses on phenom win64, 16x16 is almost the same
  788. cglobal x264_pixel_satd_16x4_internal_%1
  789.     LOAD_SUMSUB_16x4P 0, 1, 2, 3, 4, 8, 5, 9, 6, 7, r0, r2, 11
  790.     lea  r2, [r2+4*r3]
  791.     lea  r0, [r0+4*r1]
  792.     SATD_8x4_SSE ssse3, 0, 1, 2, 3, 6, 11, 10
  793.     SATD_8x4_SSE ssse3, 4, 8, 5, 9, 6, 3, 10
  794.     ret
  795. cglobal x264_pixel_satd_16x8_%1, 4,6,12
  796.     SATD_START_SSE2 %1, m10, m7
  797. %ifidn %1, sse2
  798.     mova m7, [pw_00ff GLOBAL]
  799. %endif
  800.     jmp x264_pixel_satd_16x8_internal_%1
  801. cglobal x264_pixel_satd_16x16_%1, 4,6,12
  802.     SATD_START_SSE2 %1, m10, m7
  803. %ifidn %1, sse2
  804.     mova m7, [pw_00ff GLOBAL]
  805. %endif
  806.     call x264_pixel_satd_16x4_internal_%1
  807.     call x264_pixel_satd_16x4_internal_%1
  808. x264_pixel_satd_16x8_internal_%1:
  809.     call x264_pixel_satd_16x4_internal_%1
  810.     call x264_pixel_satd_16x4_internal_%1
  811.     SATD_END_SSE2 %1, m10
  812. %else
  813. cglobal x264_pixel_satd_16x8_%1, 4,6,8
  814.     SATD_START_SSE2 %1, m6, m7
  815.     BACKUP_POINTERS
  816.     call x264_pixel_satd_8x8_internal_%1
  817.     RESTORE_AND_INC_POINTERS
  818.     call x264_pixel_satd_8x8_internal_%1
  819.     SATD_END_SSE2 %1, m6
  820. cglobal x264_pixel_satd_16x16_%1, 4,6,8
  821.     SATD_START_SSE2 %1, m6, m7
  822.     BACKUP_POINTERS
  823.     call x264_pixel_satd_8x8_internal_%1
  824.     call x264_pixel_satd_8x8_internal_%1
  825.     RESTORE_AND_INC_POINTERS
  826.     call x264_pixel_satd_8x8_internal_%1
  827.     call x264_pixel_satd_8x8_internal_%1
  828.     SATD_END_SSE2 %1, m6
  829. %endif
  830. cglobal x264_pixel_satd_8x16_%1, 4,6,8
  831.     SATD_START_SSE2 %1, m6, m7
  832.     call x264_pixel_satd_8x8_internal_%1
  833.     call x264_pixel_satd_8x8_internal_%1
  834.     SATD_END_SSE2 %1, m6
  835. cglobal x264_pixel_satd_8x8_%1, 4,6,8
  836.     SATD_START_SSE2 %1, m6, m7
  837.     call x264_pixel_satd_8x8_internal_%1
  838.     SATD_END_SSE2 %1, m6
  839. cglobal x264_pixel_satd_8x4_%1, 4,6,8
  840.     SATD_START_SSE2 %1, m6, m7
  841.     call x264_pixel_satd_8x4_internal_%1
  842.     SATD_END_SSE2 %1, m6
  843. %endmacro ; SATDS_SSE2
  844. %macro SA8D 1
  845. %ifdef ARCH_X86_64
  846. ;-----------------------------------------------------------------------------
  847. ; int x264_pixel_sa8d_8x8_sse2( uint8_t *, int, uint8_t *, int )
  848. ;-----------------------------------------------------------------------------
  849. cglobal x264_pixel_sa8d_8x8_internal_%1
  850.     lea  r10, [r0+4*r1]
  851.     lea  r11, [r2+4*r3]
  852.     LOAD_SUMSUB_8x4P 0, 1, 2, 8, 5, 6, 7, r0, r2
  853.     LOAD_SUMSUB_8x4P 4, 5, 3, 9, 11, 6, 7, r10, r11
  854. %ifidn %1, sse2 ; sse2 doesn't seem to like the horizontal way of doing things
  855.     HADAMARD8_2D 0, 1, 2, 8, 4, 5, 3, 9, 6, amax
  856. %else ; non-sse2
  857.     HADAMARD4_V m0, m1, m2, m8, m6
  858.     HADAMARD4_V m4, m5, m3, m9, m6
  859.     SUMSUB_BADC m0, m4, m1, m5, m6
  860.     HADAMARD 2, sumsub, 0, 4, 6, 11
  861.     HADAMARD 2, sumsub, 1, 5, 6, 11
  862.     SUMSUB_BADC m2, m3, m8, m9, m6
  863.     HADAMARD 2, sumsub, 2, 3, 6, 11
  864.     HADAMARD 2, sumsub, 8, 9, 6, 11
  865.     HADAMARD 1, amax, 0, 4, 6, 11
  866.     HADAMARD 1, amax, 1, 5, 6, 4
  867.     HADAMARD 1, amax, 2, 3, 6, 4
  868.     HADAMARD 1, amax, 8, 9, 6, 4
  869. %endif
  870.     paddw m0, m1
  871.     paddw m0, m2
  872.     paddw m0, m8
  873.     SAVE_MM_PERMUTATION x264_pixel_sa8d_8x8_internal_%1
  874.     ret
  875. cglobal x264_pixel_sa8d_8x8_%1, 4,6,12
  876.     lea  r4, [3*r1]
  877.     lea  r5, [3*r3]
  878. %ifnidn %1, sse2
  879.     mova m7, [hmul_8p GLOBAL]
  880. %endif
  881.     call x264_pixel_sa8d_8x8_internal_%1
  882.     HADDW m0, m1
  883.     movd eax, m0
  884.     add eax, 1
  885.     shr eax, 1
  886.     RET
  887. cglobal x264_pixel_sa8d_16x16_%1, 4,6,12
  888.     lea  r4, [3*r1]
  889.     lea  r5, [3*r3]
  890. %ifnidn %1, sse2
  891.     mova m7, [hmul_8p GLOBAL]
  892. %endif
  893.     call x264_pixel_sa8d_8x8_internal_%1 ; pix[0]
  894.     add  r2, 8
  895.     add  r0, 8
  896.     mova m10, m0
  897.     call x264_pixel_sa8d_8x8_internal_%1 ; pix[8]
  898.     lea  r2, [r2+8*r3]
  899.     lea  r0, [r0+8*r1]
  900.     paddusw m10, m0
  901.     call x264_pixel_sa8d_8x8_internal_%1 ; pix[8*stride+8]
  902.     sub  r2, 8
  903.     sub  r0, 8
  904.     paddusw m10, m0
  905.     call x264_pixel_sa8d_8x8_internal_%1 ; pix[8*stride]
  906.     paddusw m0, m10
  907.     HADDUW m0, m1
  908.     movd eax, m0
  909.     add  eax, 1
  910.     shr  eax, 1
  911.     RET
  912. %else ; ARCH_X86_32
  913. %ifnidn %1, mmxext
  914. cglobal x264_pixel_sa8d_8x8_internal_%1
  915.     %define spill0 [esp+4]
  916.     %define spill1 [esp+20]
  917.     %define spill2 [esp+36]
  918. %ifidn %1, sse2
  919.     LOAD_DIFF_8x4P 0, 1, 2, 3, 4, 5, 6, r0, r2, 1
  920.     HADAMARD4_2D 0, 1, 2, 3, 4
  921.     movdqa spill0, m3
  922.     LOAD_DIFF_8x4P 4, 5, 6, 7, 3, 3, 2, r0, r2, 1
  923.     HADAMARD4_2D 4, 5, 6, 7, 3
  924.     HADAMARD2_2D 0, 4, 1, 5, 3, qdq, amax
  925.     movdqa m3, spill0
  926.     paddw m0, m1
  927.     HADAMARD2_2D 2, 6, 3, 7, 5, qdq, amax
  928. %else ; non-sse2
  929.     mova m7, [hmul_8p GLOBAL]
  930.     LOAD_SUMSUB_8x4P 0, 1, 2, 3, 5, 6, 7, r0, r2, 1
  931.     ; could do first HADAMARD4_V here to save spilling later
  932.     ; surprisingly, not a win on conroe or even p4
  933.     mova spill0, m2
  934.     mova spill1, m3
  935.     mova spill2, m1
  936.     SWAP 1, 7
  937.     LOAD_SUMSUB_8x4P 4, 5, 6, 7, 2, 3, 1, r0, r2, 1
  938.     HADAMARD4_V m4, m5, m6, m7, m3
  939.     mova m1, spill2
  940.     mova m2, spill0
  941.     mova m3, spill1
  942.     mova spill0, m6
  943.     mova spill1, m7
  944.     HADAMARD4_V m0, m1, m2, m3, m7
  945.     SUMSUB_BADC m0, m4, m1, m5, m7
  946.     HADAMARD 2, sumsub, 0, 4, 7, 6
  947.     HADAMARD 2, sumsub, 1, 5, 7, 6
  948.     HADAMARD 1, amax, 0, 4, 7, 6
  949.     HADAMARD 1, amax, 1, 5, 7, 6
  950.     mova m6, spill0
  951.     mova m7, spill1
  952.     paddw m0, m1
  953.     SUMSUB_BADC m2, m6, m3, m7, m4
  954.     HADAMARD 2, sumsub, 2, 6, 4, 5
  955.     HADAMARD 2, sumsub, 3, 7, 4, 5
  956.     HADAMARD 1, amax, 2, 6, 4, 5
  957.     HADAMARD 1, amax, 3, 7, 4, 5
  958. %endif ; sse2/non-sse2
  959.     paddw m0, m2
  960.     paddw m0, m3
  961.     ret
  962. %endif ; ifndef mmxext
  963. cglobal x264_pixel_sa8d_8x8_%1, 4,7
  964.     mov  r6, esp
  965.     and  esp, ~15
  966.     sub  esp, 48
  967.     lea  r4, [3*r1]
  968.     lea  r5, [3*r3]
  969.     call x264_pixel_sa8d_8x8_internal_%1
  970.     HADDW m0, m1
  971.     movd eax, m0
  972.     add  eax, 1
  973.     shr  eax, 1
  974.     mov  esp, r6
  975.     RET
  976. cglobal x264_pixel_sa8d_16x16_%1, 4,7
  977.     mov  r6, esp
  978.     and  esp, ~15
  979.     sub  esp, 64
  980.     lea  r4, [3*r1]
  981.     lea  r5, [3*r3]
  982.     call x264_pixel_sa8d_8x8_internal_%1
  983. %ifidn %1, mmxext
  984.     lea  r0, [r0+4*r1]
  985.     lea  r2, [r2+4*r3]
  986. %endif
  987.     mova [esp+48], m0
  988.     call x264_pixel_sa8d_8x8_internal_%1
  989.     mov  r0, [r6+20]
  990.     mov  r2, [r6+28]
  991.     add  r0, 8
  992.     add  r2, 8
  993.     paddusw m0, [esp+48]
  994.     mova [esp+48], m0
  995.     call x264_pixel_sa8d_8x8_internal_%1
  996. %ifidn %1, mmxext
  997.     lea  r0, [r0+4*r1]
  998.     lea  r2, [r2+4*r3]
  999. %endif
  1000. %if mmsize == 16
  1001.     paddusw m0, [esp+48]
  1002. %endif
  1003.     mova [esp+64-mmsize], m0
  1004.     call x264_pixel_sa8d_8x8_internal_%1
  1005.     paddusw m0, [esp+64-mmsize]
  1006. %if mmsize == 16
  1007.     HADDUW m0, m1
  1008. %else
  1009.     mova m2, [esp+48]
  1010.     pxor m7, m7
  1011.     mova m1, m0
  1012.     mova m3, m2
  1013.     punpcklwd m0, m7
  1014.     punpckhwd m1, m7
  1015.     punpcklwd m2, m7
  1016.     punpckhwd m3, m7
  1017.     paddd m0, m1
  1018.     paddd m2, m3
  1019.     paddd m0, m2
  1020.     HADDD m0, m1
  1021. %endif
  1022.     movd eax, m0
  1023.     add  eax, 1
  1024.     shr  eax, 1
  1025.     mov  esp, r6
  1026.     RET
  1027. %endif ; !ARCH_X86_64
  1028. %endmacro ; SA8D
  1029. ;=============================================================================
  1030. ; INTRA SATD
  1031. ;=============================================================================
  1032. %macro INTRA_SA8D_SSE2 1
  1033. %ifdef ARCH_X86_64
  1034. INIT_XMM
  1035. ;-----------------------------------------------------------------------------
  1036. ; void x264_intra_sa8d_x3_8x8_core_sse2( uint8_t *fenc, int16_t edges[2][8], int *res )
  1037. ;-----------------------------------------------------------------------------
  1038. cglobal x264_intra_sa8d_x3_8x8_core_%1, 3,3,16
  1039.     ; 8x8 hadamard
  1040.     pxor        m8, m8
  1041.     movq        m0, [r0+0*FENC_STRIDE]
  1042.     movq        m1, [r0+1*FENC_STRIDE]
  1043.     movq        m2, [r0+2*FENC_STRIDE]
  1044.     movq        m3, [r0+3*FENC_STRIDE]
  1045.     movq        m4, [r0+4*FENC_STRIDE]
  1046.     movq        m5, [r0+5*FENC_STRIDE]
  1047.     movq        m6, [r0+6*FENC_STRIDE]
  1048.     movq        m7, [r0+7*FENC_STRIDE]
  1049.     punpcklbw   m0, m8
  1050.     punpcklbw   m1, m8
  1051.     punpcklbw   m2, m8
  1052.     punpcklbw   m3, m8
  1053.     punpcklbw   m4, m8
  1054.     punpcklbw   m5, m8
  1055.     punpcklbw   m6, m8
  1056.     punpcklbw   m7, m8
  1057.     HADAMARD8_2D 0,  1,  2,  3,  4,  5,  6,  7,  8
  1058.     ; dc
  1059.     movzx       r0d, word [r1+0]
  1060.     add         r0w, word [r1+16]
  1061.     add         r0d, 8
  1062.     and         r0d, -16
  1063.     shl         r0d, 2
  1064.     pxor        m15, m15
  1065.     movdqa      m8,  m2
  1066.     movdqa      m9,  m3
  1067.     movdqa      m10, m4
  1068.     movdqa      m11, m5
  1069.     ABS4        m8, m9, m10, m11, m12, m13
  1070.     paddusw     m8,  m10
  1071.     paddusw     m9,  m11
  1072. %ifidn %1, ssse3
  1073.     pabsw       m10, m6
  1074.     pabsw       m11, m7
  1075.     pabsw       m15, m1
  1076. %else
  1077.     movdqa      m10, m6
  1078.     movdqa      m11, m7
  1079.     movdqa      m15, m1
  1080.     ABS2        m10, m11, m13, m14
  1081.     ABS1        m15, m13
  1082. %endif
  1083.     paddusw     m10, m11
  1084.     paddusw     m8,  m9
  1085.     paddusw     m15, m10
  1086.     paddusw     m15, m8
  1087.     movdqa      m14, m15 ; 7x8 sum
  1088.     movdqa      m8,  [r1+0] ; left edge
  1089.     movd        m9,  r0d
  1090.     psllw       m8,  3
  1091.     psubw       m8,  m0
  1092.     psubw       m9,  m0
  1093.     ABS1        m8,  m10
  1094.     ABS1        m9,  m11 ; 1x8 sum
  1095.     paddusw     m14, m8
  1096.     paddusw     m15, m9
  1097.     punpcklwd   m0,  m1
  1098.     punpcklwd   m2,  m3
  1099.     punpcklwd   m4,  m5
  1100.     punpcklwd   m6,  m7
  1101.     punpckldq   m0,  m2
  1102.     punpckldq   m4,  m6
  1103.     punpcklqdq  m0,  m4 ; transpose
  1104.     movdqa      m1,  [r1+16] ; top edge
  1105.     movdqa      m2,  m15
  1106.     psllw       m1,  3
  1107.     psrldq      m2,  2     ; 8x7 sum
  1108.     psubw       m0,  m1  ; 8x1 sum
  1109.     ABS1        m0,  m1
  1110.     paddusw     m2,  m0
  1111.     ; 3x HADDW
  1112.     movdqa      m7,  [pw_1 GLOBAL]
  1113.     pmaddwd     m2,  m7
  1114.     pmaddwd     m14, m7
  1115.     pmaddwd     m15, m7
  1116.     movdqa      m3,  m2
  1117.     punpckldq   m2,  m14
  1118.     punpckhdq   m3,  m14
  1119.     pshufd      m5,  m15, 0xf5
  1120.     paddd       m2,  m3
  1121.     paddd       m5,  m15
  1122.     movdqa      m3,  m2
  1123.     punpcklqdq  m2,  m5
  1124.     punpckhqdq  m3,  m5
  1125.     pavgw       m3,  m2
  1126.     pxor        m0,  m0
  1127.     pavgw       m3,  m0
  1128.     movq      [r2],  m3 ; i8x8_v, i8x8_h
  1129.     psrldq      m3,  8
  1130.     movd    [r2+8],  m3 ; i8x8_dc
  1131.     RET
  1132. %endif ; ARCH_X86_64
  1133. %endmacro ; INTRA_SA8D_SSE2
  1134. ; in: r0 = fenc
  1135. ; out: m0..m3 = hadamard coefs
  1136. INIT_MMX
  1137. ALIGN 16
  1138. load_hadamard:
  1139.     pxor        m7, m7
  1140.     movd        m0, [r0+0*FENC_STRIDE]
  1141.     movd        m1, [r0+1*FENC_STRIDE]
  1142.     movd        m2, [r0+2*FENC_STRIDE]
  1143.     movd        m3, [r0+3*FENC_STRIDE]
  1144.     punpcklbw   m0, m7
  1145.     punpcklbw   m1, m7
  1146.     punpcklbw   m2, m7
  1147.     punpcklbw   m3, m7
  1148.     HADAMARD4_2D 0, 1, 2, 3, 4
  1149.     SAVE_MM_PERMUTATION load_hadamard
  1150.     ret
  1151. %macro SCALAR_SUMSUB 4
  1152.     add %1, %2
  1153.     add %3, %4
  1154.     add %2, %2
  1155.     add %4, %4
  1156.     sub %2, %1
  1157.     sub %4, %3
  1158. %endmacro
  1159. %macro SCALAR_HADAMARD_LEFT 5 ; y, 4x tmp
  1160. %ifnidn %1, 0
  1161.     shl         %1d, 5 ; log(FDEC_STRIDE)
  1162. %endif
  1163.     movzx       %2d, byte [r1+%1-1+0*FDEC_STRIDE]
  1164.     movzx       %3d, byte [r1+%1-1+1*FDEC_STRIDE]
  1165.     movzx       %4d, byte [r1+%1-1+2*FDEC_STRIDE]
  1166.     movzx       %5d, byte [r1+%1-1+3*FDEC_STRIDE]
  1167. %ifnidn %1, 0
  1168.     shr         %1d, 5
  1169. %endif
  1170.     SCALAR_SUMSUB %2d, %3d, %4d, %5d
  1171.     SCALAR_SUMSUB %2d, %4d, %3d, %5d
  1172.     mov         [left_1d+2*%1+0], %2w
  1173.     mov         [left_1d+2*%1+2], %3w
  1174.     mov         [left_1d+2*%1+4], %4w
  1175.     mov         [left_1d+2*%1+6], %5w
  1176. %endmacro
  1177. %macro SCALAR_HADAMARD_TOP 5 ; x, 4x tmp
  1178.     movzx       %2d, byte [r1+%1-FDEC_STRIDE+0]
  1179.     movzx       %3d, byte [r1+%1-FDEC_STRIDE+1]
  1180.     movzx       %4d, byte [r1+%1-FDEC_STRIDE+2]
  1181.     movzx       %5d, byte [r1+%1-FDEC_STRIDE+3]
  1182.     SCALAR_SUMSUB %2d, %3d, %4d, %5d
  1183.     SCALAR_SUMSUB %2d, %4d, %3d, %5d
  1184.     mov         [top_1d+2*%1+0], %2w
  1185.     mov         [top_1d+2*%1+2], %3w
  1186.     mov         [top_1d+2*%1+4], %4w
  1187.     mov         [top_1d+2*%1+6], %5w
  1188. %endmacro
  1189. %macro SUM_MM_X3 8 ; 3x sum, 4x tmp, op
  1190.     pxor        %7, %7
  1191.     pshufw      %4, %1, 01001110b
  1192.     pshufw      %5, %2, 01001110b
  1193.     pshufw      %6, %3, 01001110b
  1194.     paddw       %1, %4
  1195.     paddw       %2, %5
  1196.     paddw       %3, %6
  1197.     punpcklwd   %1, %7
  1198.     punpcklwd   %2, %7
  1199.     punpcklwd   %3, %7
  1200.     pshufw      %4, %1, 01001110b
  1201.     pshufw      %5, %2, 01001110b
  1202.     pshufw      %6, %3, 01001110b
  1203.     %8          %1, %4
  1204.     %8          %2, %5
  1205.     %8          %3, %6
  1206. %endmacro
  1207. %macro CLEAR_SUMS 0
  1208. %ifdef ARCH_X86_64
  1209.     mov   qword [sums+0], 0
  1210.     mov   qword [sums+8], 0
  1211.     mov   qword [sums+16], 0
  1212. %else
  1213.     pxor  m7, m7
  1214.     movq  [sums+0], m7
  1215.     movq  [sums+8], m7
  1216.     movq  [sums+16], m7
  1217. %endif
  1218. %endmacro
  1219. ; in: m1..m3
  1220. ; out: m7
  1221. ; clobber: m4..m6
  1222. %macro SUM3x4 1
  1223. %ifidn %1, ssse3
  1224.     pabsw       m4, m1
  1225.     pabsw       m5, m2
  1226.     pabsw       m7, m3
  1227.     paddw       m4, m5
  1228. %else
  1229.     movq        m4, m1
  1230.     movq        m5, m2
  1231.     ABS2        m4, m5, m6, m7
  1232.     movq        m7, m3
  1233.     paddw       m4, m5
  1234.     ABS1        m7, m6
  1235. %endif
  1236.     paddw       m7, m4
  1237. %endmacro
  1238. ; in: m0..m3 (4x4), m7 (3x4)
  1239. ; out: m0 v, m4 h, m5 dc
  1240. ; clobber: m6
  1241. %macro SUM4x3 3 ; dc, left, top
  1242.     movq        m4, %2
  1243.     movd        m5, %1
  1244.     psllw       m4, 2
  1245.     psubw       m4, m0
  1246.     psubw       m5, m0
  1247.     punpcklwd   m0, m1
  1248.     punpcklwd   m2, m3
  1249.     punpckldq   m0, m2 ; transpose
  1250.     movq        m1, %3
  1251.     psllw       m1, 2
  1252.     psubw       m0, m1
  1253.     ABS2        m4, m5, m2, m3 ; 1x4 sum
  1254.     ABS1        m0, m1 ; 4x1 sum
  1255. %endmacro
  1256. %macro INTRA_SATDS_MMX 1
  1257. INIT_MMX
  1258. ;-----------------------------------------------------------------------------
  1259. ; void x264_intra_satd_x3_4x4_mmxext( uint8_t *fenc, uint8_t *fdec, int *res )
  1260. ;-----------------------------------------------------------------------------
  1261. cglobal x264_intra_satd_x3_4x4_%1, 2,6
  1262. %ifdef ARCH_X86_64
  1263.     ; stack is 16 byte aligned because abi says so
  1264.     %define  top_1d  rsp-8  ; size 8
  1265.     %define  left_1d rsp-16 ; size 8
  1266.     %define  t0 r10
  1267. %else
  1268.     ; stack is 16 byte aligned at least in gcc, and we've pushed 3 regs + return address, so it's still aligned
  1269.     SUB         esp, 16
  1270.     %define  top_1d  esp+8
  1271.     %define  left_1d esp
  1272.     %define  t0 r2
  1273. %endif
  1274.     call load_hadamard
  1275.     SCALAR_HADAMARD_LEFT 0, r0, r3, r4, r5
  1276.     mov         t0d, r0d
  1277.     SCALAR_HADAMARD_TOP  0, r0, r3, r4, r5
  1278.     lea         t0d, [t0d + r0d + 4]
  1279.     and         t0d, -8
  1280.     shl         t0d, 1 ; dc
  1281.     SUM3x4 %1
  1282.     SUM4x3 t0d, [left_1d], [top_1d]
  1283.     paddw       m4, m7
  1284.     paddw       m5, m7
  1285.     movq        m1, m5
  1286.     psrlq       m1, 16  ; 4x3 sum
  1287.     paddw       m0, m1
  1288.     SUM_MM_X3   m0, m4, m5, m1, m2, m3, m6, pavgw
  1289. %ifndef ARCH_X86_64
  1290.     mov         r2,  r2mp
  1291. %endif
  1292.     movd        [r2+0], m0 ; i4x4_v satd
  1293.     movd        [r2+4], m4 ; i4x4_h satd
  1294.     movd        [r2+8], m5 ; i4x4_dc satd
  1295. %ifndef ARCH_X86_64
  1296.     ADD         esp, 16
  1297. %endif
  1298.     RET
  1299. %ifdef ARCH_X86_64
  1300.     %define  t0 r10
  1301.     %define  t2 r11
  1302. %else
  1303.     %define  t0 r0
  1304.     %define  t2 r2
  1305. %endif
  1306. ;-----------------------------------------------------------------------------
  1307. ; void x264_intra_satd_x3_16x16_mmxext( uint8_t *fenc, uint8_t *fdec, int *res )
  1308. ;-----------------------------------------------------------------------------
  1309. cglobal x264_intra_satd_x3_16x16_%1, 0,7
  1310. %ifdef ARCH_X86_64
  1311.     %assign  stack_pad  88
  1312. %else
  1313.     %assign  stack_pad  88 + ((stack_offset+88+4)&15)
  1314. %endif
  1315.     ; not really needed on x86_64, just shuts up valgrind about storing data below the stack across a function call
  1316.     SUB         rsp, stack_pad
  1317. %define sums    rsp+64 ; size 24
  1318. %define top_1d  rsp+32 ; size 32
  1319. %define left_1d rsp    ; size 32
  1320.     movifnidn   r1,  r1mp
  1321.     CLEAR_SUMS
  1322.     ; 1D hadamards
  1323.     xor         t2d, t2d
  1324.     mov         t0d, 12
  1325. .loop_edge:
  1326.     SCALAR_HADAMARD_LEFT t0, r3, r4, r5, r6
  1327.     add         t2d, r3d
  1328.     SCALAR_HADAMARD_TOP  t0, r3, r4, r5, r6
  1329.     add         t2d, r3d
  1330.     sub         t0d, 4
  1331.     jge .loop_edge
  1332.     shr         t2d, 1
  1333.     add         t2d, 8
  1334.     and         t2d, -16 ; dc
  1335.     ; 2D hadamards
  1336.     movifnidn   r0,  r0mp
  1337.     xor         r3d, r3d
  1338. .loop_y:
  1339.     xor         r4d, r4d
  1340. .loop_x:
  1341.     call load_hadamard
  1342.     SUM3x4 %1
  1343.     SUM4x3 t2d, [left_1d+8*r3], [top_1d+8*r4]
  1344.     pavgw       m4, m7
  1345.     pavgw       m5, m7
  1346.     paddw       m0, [sums+0]  ; i16x16_v satd
  1347.     paddw       m4, [sums+8]  ; i16x16_h satd
  1348.     paddw       m5, [sums+16] ; i16x16_dc satd
  1349.     movq        [sums+0], m0
  1350.     movq        [sums+8], m4
  1351.     movq        [sums+16], m5
  1352.     add         r0, 4
  1353.     inc         r4d
  1354.     cmp         r4d, 4
  1355.     jl  .loop_x
  1356.     add         r0, 4*FENC_STRIDE-16
  1357.     inc         r3d
  1358.     cmp         r3d, 4
  1359.     jl  .loop_y
  1360. ; horizontal sum
  1361.     movifnidn   r2, r2mp
  1362.     movq        m2, [sums+16]
  1363.     movq        m1, [sums+8]
  1364.     movq        m0, [sums+0]
  1365.     movq        m7, m2
  1366.     SUM_MM_X3   m0, m1, m2, m3, m4, m5, m6, paddd
  1367.     psrld       m0, 1
  1368.     pslld       m7, 16
  1369.     psrld       m7, 16
  1370.     paddd       m0, m2
  1371.     psubd       m0, m7
  1372.     movd        [r2+8], m2 ; i16x16_dc satd
  1373.     movd        [r2+4], m1 ; i16x16_h satd
  1374.     movd        [r2+0], m0 ; i16x16_v satd
  1375.     ADD         rsp, stack_pad
  1376.     RET
  1377. ;-----------------------------------------------------------------------------
  1378. ; void x264_intra_satd_x3_8x8c_mmxext( uint8_t *fenc, uint8_t *fdec, int *res )
  1379. ;-----------------------------------------------------------------------------
  1380. cglobal x264_intra_satd_x3_8x8c_%1, 0,6
  1381.     ; not really needed on x86_64, just shuts up valgrind about storing data below the stack across a function call
  1382.     SUB          rsp, 72
  1383. %define  sums    rsp+48 ; size 24
  1384. %define  dc_1d   rsp+32 ; size 16
  1385. %define  top_1d  rsp+16 ; size 16
  1386. %define  left_1d rsp    ; size 16
  1387.     movifnidn   r1,  r1mp
  1388.     CLEAR_SUMS
  1389.     ; 1D hadamards
  1390.     mov         t0d, 4
  1391. .loop_edge:
  1392.     SCALAR_HADAMARD_LEFT t0, t2, r3, r4, r5
  1393.     SCALAR_HADAMARD_TOP  t0, t2, r3, r4, r5
  1394.     sub         t0d, 4
  1395.     jge .loop_edge
  1396.     ; dc
  1397.     movzx       t2d, word [left_1d+0]
  1398.     movzx       r3d, word [top_1d+0]
  1399.     movzx       r4d, word [left_1d+8]
  1400.     movzx       r5d, word [top_1d+8]
  1401.     add         t2d, r3d
  1402.     lea         r3, [r4 + r5]
  1403.     lea         t2, [2*t2 + 8]
  1404.     lea         r3, [2*r3 + 8]
  1405.     lea         r4, [4*r4 + 8]
  1406.     lea         r5, [4*r5 + 8]
  1407.     and         t2d, -16 ; tl
  1408.     and         r3d, -16 ; br
  1409.     and         r4d, -16 ; bl
  1410.     and         r5d, -16 ; tr
  1411.     mov         [dc_1d+ 0], t2d ; tl
  1412.     mov         [dc_1d+ 4], r5d ; tr
  1413.     mov         [dc_1d+ 8], r4d ; bl
  1414.     mov         [dc_1d+12], r3d ; br
  1415.     lea         r5, [dc_1d]
  1416.     ; 2D hadamards
  1417.     movifnidn   r0,  r0mp
  1418.     movifnidn   r2,  r2mp
  1419.     xor         r3d, r3d
  1420. .loop_y:
  1421.     xor         r4d, r4d
  1422. .loop_x:
  1423.     call load_hadamard
  1424.     SUM3x4 %1
  1425.     SUM4x3 [r5+4*r4], [left_1d+8*r3], [top_1d+8*r4]
  1426.     pavgw       m4, m7
  1427.     pavgw       m5, m7
  1428.     paddw       m0, [sums+16] ; i4x4_v satd
  1429.     paddw       m4, [sums+8]  ; i4x4_h satd
  1430.     paddw       m5, [sums+0]  ; i4x4_dc satd
  1431.     movq        [sums+16], m0
  1432.     movq        [sums+8], m4
  1433.     movq        [sums+0], m5
  1434.     add         r0, 4
  1435.     inc         r4d
  1436.     cmp         r4d, 2
  1437.     jl  .loop_x
  1438.     add         r0, 4*FENC_STRIDE-8
  1439.     add         r5, 8
  1440.     inc         r3d
  1441.     cmp         r3d, 2
  1442.     jl  .loop_y
  1443. ; horizontal sum
  1444.     movq        m0, [sums+0]
  1445.     movq        m1, [sums+8]
  1446.     movq        m2, [sums+16]
  1447.     movq        m7, m0
  1448.     psrlq       m7, 15
  1449.     paddw       m2, m7
  1450.     SUM_MM_X3   m0, m1, m2, m3, m4, m5, m6, paddd
  1451.     psrld       m2, 1
  1452.     movd        [r2+0], m0 ; i8x8c_dc satd
  1453.     movd        [r2+4], m1 ; i8x8c_h satd
  1454.     movd        [r2+8], m2 ; i8x8c_v satd
  1455.     ADD         rsp, 72
  1456.     RET
  1457. %endmacro ; INTRA_SATDS_MMX
  1458. %macro ABS_MOV_SSSE3 2
  1459.     pabsw   %1, %2
  1460. %endmacro
  1461. %macro ABS_MOV_MMX 2
  1462.     pxor    %1, %1
  1463.     psubw   %1, %2
  1464.     pmaxsw  %1, %2
  1465. %endmacro
  1466. %define ABS_MOV ABS_MOV_MMX
  1467. ; in:  r0=pix, r1=stride, r2=stride*3, r3=tmp, m6=mask_ac4, m7=0
  1468. ; out: [tmp]=hadamard4, m0=satd
  1469. cglobal x264_hadamard_ac_4x4_mmxext
  1470.     movh      m0, [r0]
  1471.     movh      m1, [r0+r1]
  1472.     movh      m2, [r0+r1*2]
  1473.     movh      m3, [r0+r2]
  1474.     punpcklbw m0, m7
  1475.     punpcklbw m1, m7
  1476.     punpcklbw m2, m7
  1477.     punpcklbw m3, m7
  1478.     HADAMARD4_2D 0, 1, 2, 3, 4
  1479.     mova [r3],    m0
  1480.     mova [r3+8],  m1
  1481.     mova [r3+16], m2
  1482.     mova [r3+24], m3
  1483.     ABS1      m0, m4
  1484.     ABS1      m1, m4
  1485.     pand      m0, m6
  1486.     ABS1      m2, m4
  1487.     ABS1      m3, m4
  1488.     paddw     m0, m1
  1489.     paddw     m2, m3
  1490.     paddw     m0, m2
  1491.     SAVE_MM_PERMUTATION x264_hadamard_ac_4x4_mmxext
  1492.     ret
  1493. cglobal x264_hadamard_ac_2x2max_mmxext
  1494.     mova      m0, [r3+0x00]
  1495.     mova      m1, [r3+0x20]
  1496.     mova      m2, [r3+0x40]
  1497.     mova      m3, [r3+0x60]
  1498.     sub       r3, 8
  1499.     SUMSUB_BADC m0, m1, m2, m3, m4
  1500.     ABS4 m0, m2, m1, m3, m4, m5
  1501.     HADAMARD 0, max, 0, 2, 4, 5
  1502.     HADAMARD 0, max, 1, 3, 4, 5
  1503.     paddw     m7, m0
  1504.     paddw     m7, m1
  1505.     SAVE_MM_PERMUTATION x264_hadamard_ac_2x2max_mmxext
  1506.     ret
  1507. cglobal x264_hadamard_ac_8x8_mmxext
  1508.     mova      m6, [mask_ac4 GLOBAL]
  1509.     pxor      m7, m7
  1510.     call x264_hadamard_ac_4x4_mmxext
  1511.     add       r0, 4
  1512.     add       r3, 32
  1513.     mova      m5, m0
  1514.     call x264_hadamard_ac_4x4_mmxext
  1515.     lea       r0, [r0+4*r1]
  1516.     add       r3, 64
  1517.     paddw     m5, m0
  1518.     call x264_hadamard_ac_4x4_mmxext
  1519.     sub       r0, 4
  1520.     sub       r3, 32
  1521.     paddw     m5, m0
  1522.     call x264_hadamard_ac_4x4_mmxext
  1523.     paddw     m5, m0
  1524.     sub       r3, 40
  1525.     mova [rsp+gprsize+8], m5 ; save satd
  1526. %rep 3
  1527.     call x264_hadamard_ac_2x2max_mmxext
  1528. %endrep
  1529.     mova      m0, [r3+0x00]
  1530.     mova      m1, [r3+0x20]
  1531.     mova      m2, [r3+0x40]
  1532.     mova      m3, [r3+0x60]
  1533.     SUMSUB_BADC m0, m1, m2, m3, m4
  1534.     HADAMARD 0, sumsub, 0, 2, 4, 5
  1535.     ABS4 m1, m3, m0, m2, m4, m5
  1536.     HADAMARD 0, max, 1, 3, 4, 5
  1537.     pand      m6, m0
  1538.     paddw     m7, m1
  1539.     paddw     m6, m2
  1540.     paddw     m7, m7
  1541.     paddw     m6, m7
  1542.     mova [rsp+gprsize], m6 ; save sa8d
  1543.     SWAP      m0, m6
  1544.     SAVE_MM_PERMUTATION x264_hadamard_ac_8x8_mmxext
  1545.     ret
  1546. %macro HADAMARD_AC_WXH_MMX 2
  1547. cglobal x264_pixel_hadamard_ac_%1x%2_mmxext, 2,4
  1548.     %assign pad 16-gprsize-(stack_offset&15)
  1549.     %define ysub r1
  1550.     sub  rsp, 16+128+pad
  1551.     lea  r2, [r1*3]
  1552.     lea  r3, [rsp+16]
  1553.     call x264_hadamard_ac_8x8_mmxext
  1554. %if %2==16
  1555.     %define ysub r2
  1556.     lea  r0, [r0+r1*4]
  1557.     sub  rsp, 16
  1558.     call x264_hadamard_ac_8x8_mmxext
  1559. %endif
  1560. %if %1==16
  1561.     neg  ysub
  1562.     sub  rsp, 16
  1563.     lea  r0, [r0+ysub*4+8]
  1564.     neg  ysub
  1565.     call x264_hadamard_ac_8x8_mmxext
  1566. %if %2==16
  1567.     lea  r0, [r0+r1*4]
  1568.     sub  rsp, 16
  1569.     call x264_hadamard_ac_8x8_mmxext
  1570. %endif
  1571. %endif
  1572.     mova    m1, [rsp+0x08]
  1573. %if %1*%2 >= 128
  1574.     paddusw m0, [rsp+0x10]
  1575.     paddusw m1, [rsp+0x18]
  1576. %endif
  1577. %if %1*%2 == 256
  1578.     mova    m2, [rsp+0x20]
  1579.     paddusw m1, [rsp+0x28]
  1580.     paddusw m2, [rsp+0x30]
  1581.     mova    m3, m0
  1582.     paddusw m1, [rsp+0x38]
  1583.     pxor    m3, m2
  1584.     pand    m3, [pw_1 GLOBAL]
  1585.     pavgw   m0, m2
  1586.     psubusw m0, m3
  1587.     HADDUW  m0, m2
  1588. %else
  1589.     psrlw m0, 1
  1590.     HADDW m0, m2
  1591. %endif
  1592.     psrlw m1, 1
  1593.     HADDW m1, m3
  1594.     movd edx, m0
  1595.     movd eax, m1
  1596.     shr  edx, 1
  1597. %ifdef ARCH_X86_64
  1598.     shl  rdx, 32
  1599.     add  rax, rdx
  1600. %endif
  1601.     add  rsp, 128+%1*%2/4+pad
  1602.     RET
  1603. %endmacro ; HADAMARD_AC_WXH_MMX
  1604. HADAMARD_AC_WXH_MMX 16, 16
  1605. HADAMARD_AC_WXH_MMX  8, 16
  1606. HADAMARD_AC_WXH_MMX 16,  8
  1607. HADAMARD_AC_WXH_MMX  8,  8
  1608. %macro LOAD_INC_8x4W_SSE2 5
  1609.     movh      m%1, [r0]
  1610.     movh      m%2, [r0+r1]
  1611.     movh      m%3, [r0+r1*2]
  1612.     movh      m%4, [r0+r2]
  1613. %ifidn %1, 0
  1614.     lea       r0, [r0+r1*4]
  1615. %endif
  1616.     punpcklbw m%1, m%5
  1617.     punpcklbw m%2, m%5
  1618.     punpcklbw m%3, m%5
  1619.     punpcklbw m%4, m%5
  1620. %endmacro
  1621. %macro LOAD_INC_8x4W_SSSE3 5
  1622.     LOAD_DUP_4x8P %3, %4, %1, %2, [r0+r1*2], [r0+r2], [r0], [r0+r1]
  1623. %ifidn %1, 0
  1624.     lea       r0, [r0+r1*4]
  1625. %endif
  1626.     HSUMSUB %1, %2, %3, %4, %5
  1627. %endmacro
  1628. %macro HADAMARD_AC_SSE2 1
  1629. INIT_XMM
  1630. ; in:  r0=pix, r1=stride, r2=stride*3
  1631. ; out: [esp+16]=sa8d, [esp+32]=satd, r0+=stride*4
  1632. cglobal x264_hadamard_ac_8x8_%1
  1633. %ifdef ARCH_X86_64
  1634.     %define spill0 m8
  1635.     %define spill1 m9
  1636.     %define spill2 m10
  1637. %else
  1638.     %define spill0 [rsp+gprsize]
  1639.     %define spill1 [rsp+gprsize+16]
  1640.     %define spill2 [rsp+gprsize+32]
  1641. %endif
  1642. %ifnidn %1, sse2
  1643.     ;LOAD_INC loads sumsubs
  1644.     mova      m7, [hmul_8p GLOBAL]
  1645. %else
  1646.     ;LOAD_INC only unpacks to words
  1647.     pxor      m7, m7
  1648. %endif
  1649.     LOAD_INC_8x4W 0, 1, 2, 3, 7
  1650. %ifidn %1, sse2
  1651.     HADAMARD4_2D_SSE 0, 1, 2, 3, 4
  1652. %else
  1653.     HADAMARD4_V m0, m1, m2, m3, m4
  1654. %endif
  1655.     mova  spill0, m1
  1656.     SWAP 1, 7
  1657.     LOAD_INC_8x4W 4, 5, 6, 7, 1
  1658. %ifidn %1, sse2
  1659.     HADAMARD4_2D_SSE 4, 5, 6, 7, 1
  1660. %else
  1661.     HADAMARD4_V m4, m5, m6, m7, m1
  1662. %endif
  1663. %ifnidn %1, sse2
  1664.     mova      m1, spill0
  1665.     mova      spill0, m6
  1666.     mova      spill1, m7
  1667.     HADAMARD 1, sumsub, 0, 1, 6, 7
  1668.     HADAMARD 1, sumsub, 2, 3, 6, 7
  1669.     mova      m6, spill0
  1670.     mova      m7, spill1
  1671.     mova      spill0, m1
  1672.     mova      spill1, m0
  1673.     HADAMARD 1, sumsub, 4, 5, 1, 0
  1674.     HADAMARD 1, sumsub, 6, 7, 1, 0
  1675.     mova      m0, spill1
  1676. %endif
  1677.     mova  spill1, m2
  1678.     mova  spill2, m3
  1679.     ABS_MOV   m1, m0
  1680.     ABS_MOV   m2, m4
  1681.     ABS_MOV   m3, m5
  1682.     paddw     m1, m2
  1683.     SUMSUB_BA m0, m4; m2
  1684. %ifnidn %1, sse2
  1685.     pand      m1, [mask_ac4b GLOBAL]
  1686. %else
  1687.     pand      m1, [mask_ac4 GLOBAL]
  1688. %endif
  1689.     ABS_MOV   m2, spill0
  1690.     paddw     m1, m3
  1691.     ABS_MOV   m3, spill1
  1692.     paddw     m1, m2
  1693.     ABS_MOV   m2, spill2
  1694.     paddw     m1, m3
  1695.     ABS_MOV   m3, m6
  1696.     paddw     m1, m2
  1697.     ABS_MOV   m2, m7
  1698.     paddw     m1, m3
  1699.     mova      m3, m7
  1700.     paddw     m1, m2
  1701.     mova      m2, m6
  1702.     psubw     m7, spill2
  1703.     paddw     m3, spill2
  1704.     mova  [rsp+gprsize+32], m1 ; save satd
  1705.     mova      m1, m5
  1706.     psubw     m6, spill1
  1707.     paddw     m2, spill1
  1708.     psubw     m5, spill0
  1709.     paddw     m1, spill0
  1710. %ifnidn %1, sse2
  1711.     mova  spill1, m4
  1712.     HADAMARD 2, amax, 3, 7, 4
  1713.     HADAMARD 2, amax, 2, 6, 7, 4
  1714.     mova m4, spill1
  1715.     HADAMARD 2, amax, 1, 5, 6, 7
  1716.     HADAMARD 2, sumsub, 0, 4, 5, 6
  1717. %else
  1718.     mova  spill1, m4
  1719.     HADAMARD 4, amax, 3, 7, 4
  1720.     HADAMARD 4, amax, 2, 6, 7, 4
  1721.     mova m4, spill1
  1722.     HADAMARD 4, amax, 1, 5, 6, 7
  1723.     HADAMARD 4, sumsub, 0, 4, 5, 6
  1724. %endif
  1725.     paddw m2, m3
  1726.     paddw m2, m1
  1727.     paddw m2, m2
  1728.     ABS1      m4, m7
  1729.     pand      m0, [mask_ac8 GLOBAL]
  1730.     ABS1      m0, m7
  1731.     paddw m2, m4
  1732.     paddw m0, m2
  1733.     mova  [rsp+gprsize+16], m0 ; save sa8d
  1734.     SAVE_MM_PERMUTATION x264_hadamard_ac_8x8_%1
  1735.     ret
  1736. HADAMARD_AC_WXH_SSE2 16, 16, %1
  1737. HADAMARD_AC_WXH_SSE2  8, 16, %1
  1738. HADAMARD_AC_WXH_SSE2 16,  8, %1
  1739. HADAMARD_AC_WXH_SSE2  8,  8, %1
  1740. %endmacro ; HADAMARD_AC_SSE2
  1741. ; struct { int satd, int sa8d; } x264_pixel_hadamard_ac_16x16( uint8_t *pix, int stride )
  1742. %macro HADAMARD_AC_WXH_SSE2 3
  1743. cglobal x264_pixel_hadamard_ac_%1x%2_%3, 2,3,11
  1744.     %assign pad 16-gprsize-(stack_offset&15)
  1745.     %define ysub r1
  1746.     sub  rsp, 48+pad
  1747.     lea  r2, [r1*3]
  1748.     call x264_hadamard_ac_8x8_%3
  1749. %if %2==16
  1750.     %define ysub r2
  1751.     lea  r0, [r0+r1*4]
  1752.     sub  rsp, 32
  1753.     call x264_hadamard_ac_8x8_%3
  1754. %endif
  1755. %if %1==16
  1756.     neg  ysub
  1757.     sub  rsp, 32
  1758.     lea  r0, [r0+ysub*4+8]
  1759.     neg  ysub
  1760.     call x264_hadamard_ac_8x8_%3
  1761. %if %2==16
  1762.     lea  r0, [r0+r1*4]
  1763.     sub  rsp, 32
  1764.     call x264_hadamard_ac_8x8_%3
  1765. %endif
  1766. %endif
  1767.     mova    m1, [rsp+0x20]
  1768. %if %1*%2 >= 128
  1769.     paddusw m0, [rsp+0x30]
  1770.     paddusw m1, [rsp+0x40]
  1771. %endif
  1772. %if %1*%2 == 256
  1773.     paddusw m0, [rsp+0x50]
  1774.     paddusw m1, [rsp+0x60]
  1775.     paddusw m0, [rsp+0x70]
  1776.     paddusw m1, [rsp+0x80]
  1777.     psrlw m0, 1
  1778. %endif
  1779.     HADDW m0, m2
  1780.     HADDW m1, m3
  1781.     movd edx, m0
  1782.     movd eax, m1
  1783.     shr  edx, 2 - (%1*%2 >> 8)
  1784.     shr  eax, 1
  1785. %ifdef ARCH_X86_64
  1786.     shl  rdx, 32
  1787.     add  rax, rdx
  1788. %endif
  1789.     add  rsp, 16+%1*%2/2+pad
  1790.     RET
  1791. %endmacro ; HADAMARD_AC_WXH_SSE2
  1792. ; instantiate satds
  1793. %ifndef ARCH_X86_64
  1794. cextern x264_pixel_sa8d_8x8_internal_mmxext
  1795. SA8D mmxext
  1796. %endif
  1797. %define TRANS TRANS_SSE2
  1798. %define ABS1 ABS1_MMX
  1799. %define ABS2 ABS2_MMX
  1800. %define DIFFOP DIFF_UNPACK_SSE2
  1801. %define JDUP JDUP_SSE2
  1802. %define LOAD_INC_8x4W LOAD_INC_8x4W_SSE2
  1803. %define LOAD_SUMSUB_8x4P LOAD_DIFF_8x4P
  1804. %define LOAD_SUMSUB_16P  LOAD_SUMSUB_16P_SSE2
  1805. %define movdqa movaps ; doesn't hurt pre-nehalem, might as well save size
  1806. %define movdqu movups
  1807. %define punpcklqdq movlhps
  1808. INIT_XMM
  1809. SA8D sse2
  1810. SATDS_SSE2 sse2
  1811. INTRA_SA8D_SSE2 sse2
  1812. INTRA_SATDS_MMX mmxext
  1813. HADAMARD_AC_SSE2 sse2
  1814. %define ABS1 ABS1_SSSE3
  1815. %define ABS2 ABS2_SSSE3
  1816. %define ABS_MOV ABS_MOV_SSSE3
  1817. %define DIFFOP DIFF_SUMSUB_SSSE3
  1818. %define JDUP JDUP_CONROE
  1819. %define LOAD_DUP_4x8P LOAD_DUP_4x8P_CONROE
  1820. %define LOAD_INC_8x4W LOAD_INC_8x4W_SSSE3
  1821. %define LOAD_SUMSUB_8x4P LOAD_SUMSUB_8x4P_SSSE3
  1822. %define LOAD_SUMSUB_16P  LOAD_SUMSUB_16P_SSSE3
  1823. SATDS_SSE2 ssse3
  1824. SA8D ssse3
  1825. HADAMARD_AC_SSE2 ssse3
  1826. %undef movdqa ; nehalem doesn't like movaps
  1827. %undef movdqu ; movups
  1828. %undef punpcklqdq ; or movlhps
  1829. INTRA_SA8D_SSE2 ssse3
  1830. INTRA_SATDS_MMX ssse3
  1831. %define TRANS TRANS_SSE4
  1832. %define JDUP JDUP_PENRYN
  1833. %define LOAD_DUP_4x8P LOAD_DUP_4x8P_PENRYN
  1834. SATDS_SSE2 sse4
  1835. SA8D sse4
  1836. HADAMARD_AC_SSE2 sse4
  1837. ;=============================================================================
  1838. ; SSIM
  1839. ;=============================================================================
  1840. ;-----------------------------------------------------------------------------
  1841. ; void x264_pixel_ssim_4x4x2_core_sse2( const uint8_t *pix1, int stride1,
  1842. ;                                       const uint8_t *pix2, int stride2, int sums[2][4] )
  1843. ;-----------------------------------------------------------------------------
  1844. %macro SSIM_ITER 1
  1845.     movq      m5, [r0+(%1&1)*r1]
  1846.     movq      m6, [r2+(%1&1)*r3]
  1847.     punpcklbw m5, m0
  1848.     punpcklbw m6, m0
  1849. %if %1==1
  1850.     lea       r0, [r0+r1*2]
  1851.     lea       r2, [r2+r3*2]
  1852. %endif
  1853. %if %1==0
  1854.     movdqa    m1, m5
  1855.     movdqa    m2, m6
  1856. %else
  1857.     paddw     m1, m5
  1858.     paddw     m2, m6
  1859. %endif
  1860.     movdqa    m7, m5
  1861.     pmaddwd   m5, m5
  1862.     pmaddwd   m7, m6
  1863.     pmaddwd   m6, m6
  1864. %if %1==0
  1865.     SWAP      m3, m5
  1866.     SWAP      m4, m7
  1867. %else
  1868.     paddd     m3, m5
  1869.     paddd     m4, m7
  1870. %endif
  1871.     paddd     m3, m6
  1872. %endmacro
  1873. cglobal x264_pixel_ssim_4x4x2_core_sse2, 4,4,8
  1874.     pxor      m0, m0
  1875.     SSIM_ITER 0
  1876.     SSIM_ITER 1
  1877.     SSIM_ITER 2
  1878.     SSIM_ITER 3
  1879.     ; PHADDW m1, m2
  1880.     ; PHADDD m3, m4
  1881.     movdqa    m7, [pw_1 GLOBAL]
  1882.     pshufd    m5, m3, 0xb1
  1883.     pmaddwd   m1, m7
  1884.     pmaddwd   m2, m7
  1885.     pshufd    m6, m4, 0xb1
  1886.     packssdw  m1, m2
  1887.     paddd     m3, m5
  1888.     pshufd    m1, m1, 0xd8
  1889.     paddd     m4, m6
  1890.     pmaddwd   m1, m7
  1891.     movdqa    m5, m3
  1892.     punpckldq m3, m4
  1893.     punpckhdq m5, m4
  1894. %ifdef UNIX64
  1895.     %define t0 r4
  1896. %else
  1897.     %define t0 rax
  1898.     mov t0, r4mp
  1899. %endif
  1900.     movq      [t0+ 0], m1
  1901.     movq      [t0+ 8], m3
  1902.     movhps    [t0+16], m1
  1903.     movq      [t0+24], m5
  1904.     RET
  1905. ;-----------------------------------------------------------------------------
  1906. ; float x264_pixel_ssim_end_sse2( int sum0[5][4], int sum1[5][4], int width )
  1907. ;-----------------------------------------------------------------------------
  1908. cglobal x264_pixel_ssim_end4_sse2, 3,3,7
  1909.     movdqa    m0, [r0+ 0]
  1910.     movdqa    m1, [r0+16]
  1911.     movdqa    m2, [r0+32]
  1912.     movdqa    m3, [r0+48]
  1913.     movdqa    m4, [r0+64]
  1914.     paddd     m0, [r1+ 0]
  1915.     paddd     m1, [r1+16]
  1916.     paddd     m2, [r1+32]
  1917.     paddd     m3, [r1+48]
  1918.     paddd     m4, [r1+64]
  1919.     paddd     m0, m1
  1920.     paddd     m1, m2
  1921.     paddd     m2, m3
  1922.     paddd     m3, m4
  1923.     movdqa    m5, [ssim_c1 GLOBAL]
  1924.     movdqa    m6, [ssim_c2 GLOBAL]
  1925.     TRANSPOSE4x4D  0, 1, 2, 3, 4
  1926. ;   s1=m0, s2=m1, ss=m2, s12=m3
  1927.     movdqa    m4, m1
  1928.     pslld     m1, 16
  1929.     pmaddwd   m4, m0  ; s1*s2
  1930.     por       m0, m1
  1931.     pmaddwd   m0, m0  ; s1*s1 + s2*s2
  1932.     pslld     m4, 1
  1933.     pslld     m3, 7
  1934.     pslld     m2, 6
  1935.     psubd     m3, m4  ; covar*2
  1936.     psubd     m2, m0  ; vars
  1937.     paddd     m0, m5
  1938.     paddd     m4, m5
  1939.     paddd     m3, m6
  1940.     paddd     m2, m6
  1941.     cvtdq2ps  m0, m0  ; (float)(s1*s1 + s2*s2 + ssim_c1)
  1942.     cvtdq2ps  m4, m4  ; (float)(s1*s2*2 + ssim_c1)
  1943.     cvtdq2ps  m3, m3  ; (float)(covar*2 + ssim_c2)
  1944.     cvtdq2ps  m2, m2  ; (float)(vars + ssim_c2)
  1945.     mulps     m4, m3
  1946.     mulps     m0, m2
  1947.     divps     m4, m0  ; ssim
  1948.     cmp       r2d, 4
  1949.     je .skip ; faster only if this is the common case; remove branch if we use ssim on a macroblock level
  1950.     neg       r2
  1951. %ifdef PIC
  1952.     lea       r3, [mask_ff + 16 GLOBAL]
  1953.     movdqu    m1, [r3 + r2*4]
  1954. %else
  1955.     movdqu    m1, [mask_ff + r2*4 + 16 GLOBAL]
  1956. %endif
  1957.     pand      m4, m1
  1958. .skip:
  1959.     movhlps   m0, m4
  1960.     addps     m0, m4
  1961.     pshuflw   m4, m0, 0xE
  1962.     addss     m0, m4
  1963. %ifndef ARCH_X86_64
  1964.     movd     r0m, m0
  1965.     fld     dword r0m
  1966. %endif
  1967.     RET
  1968. ;=============================================================================
  1969. ; Successive Elimination ADS
  1970. ;=============================================================================
  1971. %macro ADS_START 1 ; unroll_size
  1972. %ifdef ARCH_X86_64
  1973.     %define t0 r6
  1974. %ifdef WIN64
  1975.     mov     r4,  r4mp
  1976.     movsxd  r5,  dword r5m
  1977. %endif
  1978.     mov     r10, rsp
  1979. %else
  1980.     %define t0 r4
  1981.     mov     rbp, rsp
  1982. %endif
  1983.     mov     r0d, r5m
  1984.     sub     rsp, r0
  1985.     sub     rsp, %1*4-1
  1986.     and     rsp, ~15
  1987.     mov     t0,  rsp
  1988.     shl     r2d,  1
  1989. %endmacro
  1990. %macro ADS_END 1
  1991.     add     r1, 8*%1
  1992.     add     r3, 8*%1
  1993.     add     t0, 4*%1
  1994.     sub     r0d, 4*%1
  1995.     jg .loop
  1996. %ifdef WIN64
  1997.     RESTORE_XMM r10
  1998. %endif
  1999.     jmp ads_mvs
  2000. %endmacro
  2001. %define ABS1 ABS1_MMX
  2002. ;-----------------------------------------------------------------------------
  2003. ; int x264_pixel_ads4_mmxext( int enc_dc[4], uint16_t *sums, int delta,
  2004. ;                             uint16_t *cost_mvx, int16_t *mvs, int width, int thresh )
  2005. ;-----------------------------------------------------------------------------
  2006. cglobal x264_pixel_ads4_mmxext, 4,7
  2007.     movq    mm6, [r0]
  2008.     movq    mm4, [r0+8]
  2009.     pshufw  mm7, mm6, 0
  2010.     pshufw  mm6, mm6, 0xAA
  2011.     pshufw  mm5, mm4, 0
  2012.     pshufw  mm4, mm4, 0xAA
  2013.     ADS_START 1
  2014. .loop:
  2015.     movq    mm0, [r1]
  2016.     movq    mm1, [r1+16]
  2017.     psubw   mm0, mm7
  2018.     psubw   mm1, mm6
  2019.     ABS1    mm0, mm2
  2020.     ABS1    mm1, mm3
  2021.     movq    mm2, [r1+r2]
  2022.     movq    mm3, [r1+r2+16]
  2023.     psubw   mm2, mm5
  2024.     psubw   mm3, mm4
  2025.     paddw   mm0, mm1
  2026.     ABS1    mm2, mm1
  2027.     ABS1    mm3, mm1
  2028.     paddw   mm0, mm2
  2029.     paddw   mm0, mm3
  2030. %ifdef WIN64
  2031.     pshufw  mm1, [r10+stack_offset+56], 0
  2032. %elifdef ARCH_X86_64
  2033.     pshufw  mm1, [r10+8], 0
  2034. %else
  2035.     pshufw  mm1, [ebp+stack_offset+28], 0
  2036. %endif
  2037.     paddusw mm0, [r3]
  2038.     psubusw mm1, mm0
  2039.     packsswb mm1, mm1
  2040.     movd    [t0], mm1
  2041.     ADS_END 1
  2042. cglobal x264_pixel_ads2_mmxext, 4,7
  2043.     movq    mm6, [r0]
  2044.     pshufw  mm5, r6m, 0
  2045.     pshufw  mm7, mm6, 0
  2046.     pshufw  mm6, mm6, 0xAA
  2047.     ADS_START 1
  2048. .loop:
  2049.     movq    mm0, [r1]
  2050.     movq    mm1, [r1+r2]
  2051.     psubw   mm0, mm7
  2052.     psubw   mm1, mm6
  2053.     ABS1    mm0, mm2
  2054.     ABS1    mm1, mm3
  2055.     paddw   mm0, mm1
  2056.     paddusw mm0, [r3]
  2057.     movq    mm4, mm5
  2058.     psubusw mm4, mm0
  2059.     packsswb mm4, mm4
  2060.     movd    [t0], mm4
  2061.     ADS_END 1
  2062. cglobal x264_pixel_ads1_mmxext, 4,7
  2063.     pshufw  mm7, [r0], 0
  2064.     pshufw  mm6, r6m, 0
  2065.     ADS_START 2
  2066. .loop:
  2067.     movq    mm0, [r1]
  2068.     movq    mm1, [r1+8]
  2069.     psubw   mm0, mm7
  2070.     psubw   mm1, mm7
  2071.     ABS1    mm0, mm2
  2072.     ABS1    mm1, mm3
  2073.     paddusw mm0, [r3]
  2074.     paddusw mm1, [r3+8]
  2075.     movq    mm4, mm6
  2076.     movq    mm5, mm6
  2077.     psubusw mm4, mm0
  2078.     psubusw mm5, mm1
  2079.     packsswb mm4, mm5
  2080.     movq    [t0], mm4
  2081.     ADS_END 2
  2082. %macro ADS_SSE2 1
  2083. cglobal x264_pixel_ads4_%1, 4,7,12
  2084.     movdqa  xmm4, [r0]
  2085.     pshuflw xmm7, xmm4, 0
  2086.     pshuflw xmm6, xmm4, 0xAA
  2087.     pshufhw xmm5, xmm4, 0
  2088.     pshufhw xmm4, xmm4, 0xAA
  2089.     punpcklqdq xmm7, xmm7
  2090.     punpcklqdq xmm6, xmm6
  2091.     punpckhqdq xmm5, xmm5
  2092.     punpckhqdq xmm4, xmm4
  2093. %ifdef ARCH_X86_64
  2094.     pshuflw xmm8, r6m, 0
  2095.     punpcklqdq xmm8, xmm8
  2096.     ADS_START 2
  2097.     movdqu  xmm10, [r1]
  2098.     movdqu  xmm11, [r1+r2]
  2099. .loop:
  2100.     movdqa  xmm0, xmm10
  2101.     movdqu  xmm1, [r1+16]
  2102.     movdqa  xmm10, xmm1
  2103.     psubw   xmm0, xmm7
  2104.     psubw   xmm1, xmm6
  2105.     ABS1    xmm0, xmm2
  2106.     ABS1    xmm1, xmm3
  2107.     movdqa  xmm2, xmm11
  2108.     movdqu  xmm3, [r1+r2+16]
  2109.     movdqa  xmm11, xmm3
  2110.     psubw   xmm2, xmm5
  2111.     psubw   xmm3, xmm4
  2112.     paddw   xmm0, xmm1
  2113.     movdqu  xmm9, [r3]
  2114.     ABS1    xmm2, xmm1
  2115.     ABS1    xmm3, xmm1
  2116.     paddw   xmm0, xmm2
  2117.     paddw   xmm0, xmm3
  2118.     paddusw xmm0, xmm9
  2119.     movdqa  xmm1, xmm8
  2120.     psubusw xmm1, xmm0
  2121.     packsswb xmm1, xmm1
  2122.     movq    [t0], xmm1
  2123. %else
  2124.     ADS_START 2
  2125. .loop:
  2126.     movdqu  xmm0, [r1]
  2127.     movdqu  xmm1, [r1+16]
  2128.     psubw   xmm0, xmm7
  2129.     psubw   xmm1, xmm6
  2130.     ABS1    xmm0, xmm2
  2131.     ABS1    xmm1, xmm3
  2132.     movdqu  xmm2, [r1+r2]
  2133.     movdqu  xmm3, [r1+r2+16]
  2134.     psubw   xmm2, xmm5
  2135.     psubw   xmm3, xmm4
  2136.     paddw   xmm0, xmm1
  2137.     ABS1    xmm2, xmm1
  2138.     ABS1    xmm3, xmm1
  2139.     paddw   xmm0, xmm2
  2140.     paddw   xmm0, xmm3
  2141.     movd    xmm1, [ebp+stack_offset+28]
  2142.     movdqu  xmm2, [r3]
  2143.     pshuflw xmm1, xmm1, 0
  2144.     punpcklqdq xmm1, xmm1
  2145.     paddusw xmm0, xmm2
  2146.     psubusw xmm1, xmm0
  2147.     packsswb xmm1, xmm1
  2148.     movq    [t0], xmm1
  2149. %endif ; ARCH
  2150.     ADS_END 2
  2151. cglobal x264_pixel_ads2_%1, 4,7,8
  2152.     movq    xmm6, [r0]
  2153.     movd    xmm5, r6m
  2154.     pshuflw xmm7, xmm6, 0
  2155.     pshuflw xmm6, xmm6, 0xAA
  2156.     pshuflw xmm5, xmm5, 0
  2157.     punpcklqdq xmm7, xmm7
  2158.     punpcklqdq xmm6, xmm6
  2159.     punpcklqdq xmm5, xmm5
  2160.     ADS_START 2
  2161. .loop:
  2162.     movdqu  xmm0, [r1]
  2163.     movdqu  xmm1, [r1+r2]
  2164.     psubw   xmm0, xmm7
  2165.     psubw   xmm1, xmm6
  2166.     movdqu  xmm4, [r3]
  2167.     ABS1    xmm0, xmm2
  2168.     ABS1    xmm1, xmm3
  2169.     paddw   xmm0, xmm1
  2170.     paddusw xmm0, xmm4
  2171.     movdqa  xmm1, xmm5
  2172.     psubusw xmm1, xmm0
  2173.     packsswb xmm1, xmm1
  2174.     movq    [t0], xmm1
  2175.     ADS_END 2
  2176. cglobal x264_pixel_ads1_%1, 4,7,8
  2177.     movd    xmm7, [r0]
  2178.     movd    xmm6, r6m
  2179.     pshuflw xmm7, xmm7, 0
  2180.     pshuflw xmm6, xmm6, 0
  2181.     punpcklqdq xmm7, xmm7
  2182.     punpcklqdq xmm6, xmm6
  2183.     ADS_START 4
  2184. .loop:
  2185.     movdqu  xmm0, [r1]
  2186.     movdqu  xmm1, [r1+16]
  2187.     psubw   xmm0, xmm7
  2188.     psubw   xmm1, xmm7
  2189.     movdqu  xmm2, [r3]
  2190.     movdqu  xmm3, [r3+16]
  2191.     ABS1    xmm0, xmm4
  2192.     ABS1    xmm1, xmm5
  2193.     paddusw xmm0, xmm2
  2194.     paddusw xmm1, xmm3
  2195.     movdqa  xmm4, xmm6
  2196.     movdqa  xmm5, xmm6
  2197.     psubusw xmm4, xmm0
  2198.     psubusw xmm5, xmm1
  2199.     packsswb xmm4, xmm5
  2200.     movdqa  [t0], xmm4
  2201.     ADS_END 4
  2202. %endmacro
  2203. ADS_SSE2 sse2
  2204. %define ABS1 ABS1_SSSE3
  2205. ADS_SSE2 ssse3
  2206. ; int x264_pixel_ads_mvs( int16_t *mvs, uint8_t *masks, int width )
  2207. ; {
  2208. ;     int nmv=0, i, j;
  2209. ;     *(uint32_t*)(masks+width) = 0;
  2210. ;     for( i=0; i<width; i+=8 )
  2211. ;     {
  2212. ;         uint64_t mask = *(uint64_t*)(masks+i);
  2213. ;         if( !mask ) continue;
  2214. ;         for( j=0; j<8; j++ )
  2215. ;             if( mask & (255<<j*8) )
  2216. ;                 mvs[nmv++] = i+j;
  2217. ;     }
  2218. ;     return nmv;
  2219. ; }
  2220. cglobal x264_pixel_ads_mvs, 0,7,0
  2221. ads_mvs:
  2222. %ifdef ARCH_X86_64
  2223.     ; mvs = r4
  2224.     ; masks = rsp
  2225.     ; width = r5
  2226.     ; clear last block in case width isn't divisible by 8. (assume divisible by 4, so clearing 4 bytes is enough.)
  2227. %ifdef WIN64
  2228.     mov     r8, r4
  2229.     mov     r9, r5
  2230. %endif
  2231.     xor     eax, eax
  2232.     xor     esi, esi
  2233.     mov     dword [rsp+r9], 0
  2234.     jmp .loopi
  2235. .loopi0:
  2236.     add     esi, 8
  2237.     cmp     esi, r9d
  2238.     jge .end
  2239. .loopi:
  2240.     mov     rdi, [rsp+rsi]
  2241.     test    rdi, rdi
  2242.     jz .loopi0
  2243.     xor     ecx, ecx
  2244. %macro TEST 1
  2245.     mov     [r8+rax*2], si
  2246.     test    edi, 0xff<<(%1*8)
  2247.     setne   cl
  2248.     add     eax, ecx
  2249.     inc     esi
  2250. %endmacro
  2251.     TEST 0
  2252.     TEST 1
  2253.     TEST 2
  2254.     TEST 3
  2255.     shr     rdi, 32
  2256.     TEST 0
  2257.     TEST 1
  2258.     TEST 2
  2259.     TEST 3
  2260.     cmp     esi, r9d
  2261.     jl .loopi
  2262. .end:
  2263.     mov     rsp, r10
  2264.     RET
  2265. %else
  2266.     xor     eax, eax
  2267.     xor     esi, esi
  2268.     mov     ebx, [ebp+stack_offset+20] ; mvs
  2269.     mov     edi, [ebp+stack_offset+24] ; width
  2270.     mov     dword [esp+edi], 0
  2271.     push    ebp
  2272.     jmp .loopi
  2273. .loopi0:
  2274.     add     esi, 8
  2275.     cmp     esi, edi
  2276.     jge .end
  2277. .loopi:
  2278.     mov     ebp, [esp+esi+4]
  2279.     mov     edx, [esp+esi+8]
  2280.     mov     ecx, ebp
  2281.     or      ecx, edx
  2282.     jz .loopi0
  2283.     xor     ecx, ecx
  2284. %macro TEST 2
  2285.     mov     [ebx+eax*2], si
  2286.     test    %2, 0xff<<(%1*8)
  2287.     setne   cl
  2288.     add     eax, ecx
  2289.     inc     esi
  2290. %endmacro
  2291.     TEST 0, ebp
  2292.     TEST 1, ebp
  2293.     TEST 2, ebp
  2294.     TEST 3, ebp
  2295.     TEST 0, edx
  2296.     TEST 1, edx
  2297.     TEST 2, edx
  2298.     TEST 3, edx
  2299.     cmp     esi, edi
  2300.     jl .loopi
  2301. .end:
  2302.     pop     esp
  2303.     RET
  2304. %endif ; ARCH