pixel-a.asm
上传用户:hjq518
上传日期:2021-12-09
资源大小:5084k
文件大小:39k
源码类别:

Audio

开发平台:

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. ;*          Laurent Aimar <fenrir@via.ecp.fr>
  8. ;*          Alex Izvorski <aizvorksi@gmail.com>
  9. ;*
  10. ;* This program is free software; you can redistribute it and/or modify
  11. ;* it under the terms of the GNU General Public License as published by
  12. ;* the Free Software Foundation; either version 2 of the License, or
  13. ;* (at your option) any later version.
  14. ;*
  15. ;* This program is distributed in the hope that it will be useful,
  16. ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18. ;* GNU General Public License for more details.
  19. ;*
  20. ;* You should have received a copy of the GNU General Public License
  21. ;* along with this program; if not, write to the Free Software
  22. ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
  23. ;*****************************************************************************
  24. %include "x86inc.asm"
  25. %include "x86util.asm"
  26. SECTION_RODATA
  27. pw_1:    times 8 dw 1
  28. ssim_c1: times 4 dd 416    ; .01*.01*255*255*64
  29. ssim_c2: times 4 dd 235963 ; .03*.03*255*255*64*63
  30. mask_ff: times 16 db 0xff
  31.          times 16 db 0
  32. SECTION .text
  33. %macro HADDD 2 ; sum junk
  34. %if mmsize == 16
  35.     movhlps %2, %1
  36.     paddd   %1, %2
  37.     pshuflw %2, %1, 0xE
  38.     paddd   %1, %2
  39. %else
  40.     mova    %2, %1
  41.     psrlq   %2, 32
  42.     paddd   %1, %2
  43. %endif
  44. %endmacro
  45. %macro HADDW 2
  46.     pmaddwd %1, [pw_1 GLOBAL]
  47.     HADDD   %1, %2
  48. %endmacro
  49. ;=============================================================================
  50. ; SSD
  51. ;=============================================================================
  52. %macro SSD_FULL 6
  53.     mova      m1, [r0+%1]
  54.     mova      m2, [r2+%2]
  55.     mova      m3, [r0+%3]
  56.     mova      m4, [r2+%4]
  57.     mova      m5, m2
  58.     mova      m6, m4
  59.     psubusb   m2, m1
  60.     psubusb   m4, m3
  61.     psubusb   m1, m5
  62.     psubusb   m3, m6
  63.     por       m1, m2
  64.     por       m3, m4
  65.     mova      m2, m1
  66.     mova      m4, m3
  67.     punpcklbw m1, m7
  68.     punpcklbw m3, m7
  69.     punpckhbw m2, m7
  70.     punpckhbw m4, m7
  71.     pmaddwd   m1, m1
  72.     pmaddwd   m2, m2
  73.     pmaddwd   m3, m3
  74.     pmaddwd   m4, m4
  75. %if %6
  76.     lea       r0, [r0+2*r1]
  77.     lea       r2, [r2+2*r3]
  78. %endif
  79.     paddd     m1, m2
  80.     paddd     m3, m4
  81. %if %5
  82.     paddd     m0, m1
  83. %else
  84.     SWAP      m0, m1
  85. %endif
  86.     paddd     m0, m3
  87. %endmacro
  88. %macro SSD_HALF 6
  89.     movh      m1, [r0+%1]
  90.     movh      m2, [r2+%2]
  91.     movh      m3, [r0+%3]
  92.     movh      m4, [r2+%4]
  93.     punpcklbw m1, m7
  94.     punpcklbw m2, m7
  95.     punpcklbw m3, m7
  96.     punpcklbw m4, m7
  97.     psubw     m1, m2
  98.     psubw     m3, m4
  99.     pmaddwd   m1, m1
  100.     pmaddwd   m3, m3
  101. %if %6
  102.     lea       r0, [r0+2*r1]
  103.     lea       r2, [r2+2*r3]
  104. %endif
  105. %if %5
  106.     paddd     m0, m1
  107. %else
  108.     SWAP      m0, m1
  109. %endif
  110.     paddd     m0, m3
  111. %endmacro
  112. ;-----------------------------------------------------------------------------
  113. ; int x264_pixel_ssd_16x16_mmx( uint8_t *, int, uint8_t *, int )
  114. ;-----------------------------------------------------------------------------
  115. %macro SSD 3
  116. cglobal x264_pixel_ssd_%1x%2_%3, 4,4
  117.     pxor    m7, m7
  118. %assign i 0
  119. %rep %2/2
  120. %if %1 > mmsize
  121.     SSD_FULL 0,  0,     mmsize,    mmsize, i, 0
  122.     SSD_FULL r1, r3, r1+mmsize, r3+mmsize, 1, i<%2/2-1
  123. %elif %1 == mmsize
  124.     SSD_FULL 0, 0, r1, r3, i, i<%2/2-1
  125. %else
  126.     SSD_HALF 0, 0, r1, r3, i, i<%2/2-1
  127. %endif
  128. %assign i i+1
  129. %endrep
  130.     HADDD   m0, m1
  131.     movd   eax, m0
  132.     RET
  133. %endmacro
  134. INIT_MMX
  135. SSD 16, 16, mmx
  136. SSD 16,  8, mmx
  137. SSD  8, 16, mmx
  138. SSD  8,  8, mmx
  139. SSD  8,  4, mmx
  140. SSD  4,  8, mmx
  141. SSD  4,  4, mmx
  142. INIT_XMM
  143. SSD 16, 16, sse2
  144. SSD 16,  8, sse2
  145. SSD  8, 16, sse2
  146. SSD  8,  8, sse2
  147. SSD  8,  4, sse2
  148. ;=============================================================================
  149. ; variance
  150. ;=============================================================================
  151. %macro VAR_START 0
  152.     pxor  m5, m5    ; sum
  153.     pxor  m6, m6    ; sum squared
  154.     pxor  m7, m7    ; zero
  155. %ifdef ARCH_X86_64
  156.     %define t3d r3d
  157. %else
  158.     %define t3d r2d
  159. %endif
  160. %endmacro
  161. %macro VAR_END 1
  162. %if mmsize == 16
  163.     movhlps m0, m5
  164.     paddw   m5, m0
  165. %endif
  166.     movifnidn r2d, r2m
  167.     movd   r1d, m5
  168.     movd  [r2], m5  ; return sum
  169.     imul   r1d, r1d
  170.     HADDD   m6, m1
  171.     shr    r1d, %1
  172.     movd   eax, m6
  173.     sub    eax, r1d  ; sqr - (sum * sum >> shift)
  174.     RET
  175. %endmacro
  176. %macro VAR_2ROW 2
  177.     mov      t3d, %2
  178. .loop:
  179.     mova      m0, [r0]
  180.     mova      m1, m0
  181.     mova      m3, [r0+%1]
  182.     mova      m2, m0
  183.     punpcklbw m0, m7
  184.     mova      m4, m3
  185.     punpckhbw m1, m7
  186. %ifidn %1, r1
  187.     lea       r0, [r0+%1*2]
  188. %else
  189.     add       r0, r1
  190. %endif
  191.     punpckhbw m4, m7
  192.     psadbw    m2, m7
  193.     paddw     m5, m2
  194.     mova      m2, m3
  195.     punpcklbw m3, m7
  196.     dec t3d
  197.     psadbw    m2, m7
  198.     pmaddwd   m0, m0
  199.     paddw     m5, m2
  200.     pmaddwd   m1, m1
  201.     paddd     m6, m0
  202.     pmaddwd   m3, m3
  203.     paddd     m6, m1
  204.     pmaddwd   m4, m4
  205.     paddd     m6, m3
  206.     paddd     m6, m4
  207.     jg .loop
  208. %endmacro
  209. ;-----------------------------------------------------------------------------
  210. ; int x264_pixel_var_wxh_mmxext( uint8_t *, int, int * )
  211. ;-----------------------------------------------------------------------------
  212. INIT_MMX
  213. cglobal x264_pixel_var_16x16_mmxext, 2,3
  214.     VAR_START
  215.     VAR_2ROW 8, 16
  216.     VAR_END 8
  217. cglobal x264_pixel_var_8x8_mmxext, 2,3
  218.     VAR_START
  219.     VAR_2ROW r1, 4
  220.     VAR_END 6
  221. INIT_XMM
  222. cglobal x264_pixel_var_16x16_sse2, 2,3
  223.     VAR_START
  224.     VAR_2ROW r1, 8
  225.     VAR_END 8
  226. cglobal x264_pixel_var_8x8_sse2, 2,3
  227.     VAR_START
  228.     mov t3d, 4
  229. .loop:
  230.     movh      m0, [r0]
  231.     movhps    m0, [r0+r1]
  232.     lea       r0, [r0+r1*2]
  233.     mova      m1, m0
  234.     punpcklbw m0, m7
  235.     mova      m2, m1
  236.     punpckhbw m1, m7
  237.     dec t3d
  238.     pmaddwd   m0, m0
  239.     pmaddwd   m1, m1
  240.     psadbw    m2, m7
  241.     paddw     m5, m2
  242.     paddd     m6, m0
  243.     paddd     m6, m1
  244.     jnz .loop
  245.     VAR_END 6
  246. ;=============================================================================
  247. ; SATD
  248. ;=============================================================================
  249. ; phaddw is used only in 4x4 hadamard, because in 8x8 it's slower:
  250. ; even on Penryn, phaddw has latency 3 while paddw and punpck* have 1.
  251. ; 4x4 is special in that 4x4 transpose in xmmregs takes extra munging,
  252. ; whereas phaddw-based transform doesn't care what order the coefs end up in.
  253. %macro PHSUMSUB 3
  254.     movdqa m%3, m%1
  255.     phaddw m%1, m%2
  256.     phsubw m%3, m%2
  257.     SWAP %2, %3
  258. %endmacro
  259. %macro HADAMARD4_ROW_PHADD 5
  260.     PHSUMSUB %1, %2, %5
  261.     PHSUMSUB %3, %4, %5
  262.     PHSUMSUB %1, %3, %5
  263.     PHSUMSUB %2, %4, %5
  264.     SWAP %3, %4
  265. %endmacro
  266. %macro HADAMARD4_1D 4
  267.     SUMSUB_BADC %1, %2, %3, %4
  268.     SUMSUB_BADC %1, %3, %2, %4
  269. %endmacro
  270. %macro HADAMARD4x4_SUM 1    ; %1 = dest (row sum of one block)
  271.     %xdefine %%n n%1
  272.     HADAMARD4_1D  m4, m5, m6, m7
  273.     TRANSPOSE4x4W  4,  5,  6,  7, %%n
  274.     HADAMARD4_1D  m4, m5, m6, m7
  275.     ABS2          m4, m5, m3, m %+ %%n
  276.     ABS2          m6, m7, m3, m %+ %%n
  277.     paddw         m6, m4
  278.     paddw         m7, m5
  279.     pavgw         m6, m7
  280.     SWAP %%n, 6
  281. %endmacro
  282. ; in: r4=3*stride1, r5=3*stride2
  283. ; in: %2 = horizontal offset
  284. ; in: %3 = whether we need to increment pix1 and pix2
  285. ; clobber: m3..m7
  286. ; out: %1 = satd
  287. %macro SATD_4x4_MMX 3
  288.     LOAD_DIFF m4, m3, none, [r0+%2],      [r2+%2]
  289.     LOAD_DIFF m5, m3, none, [r0+r1+%2],   [r2+r3+%2]
  290.     LOAD_DIFF m6, m3, none, [r0+2*r1+%2], [r2+2*r3+%2]
  291.     LOAD_DIFF m7, m3, none, [r0+r4+%2],   [r2+r5+%2]
  292. %if %3
  293.     lea  r0, [r0+4*r1]
  294.     lea  r2, [r2+4*r3]
  295. %endif
  296.     HADAMARD4x4_SUM %1
  297. %endmacro
  298. %macro SATD_8x4_START 1
  299.     SATD_4x4_MMX m0, 0, 0
  300.     SATD_4x4_MMX m1, 4, %1
  301. %endmacro
  302. %macro SATD_8x4_INC 1
  303.     SATD_4x4_MMX m2, 0, 0
  304.     paddw        m0, m1
  305.     SATD_4x4_MMX m1, 4, %1
  306.     paddw        m0, m2
  307. %endmacro
  308. %macro SATD_16x4_START 1
  309.     SATD_4x4_MMX m0,  0, 0
  310.     SATD_4x4_MMX m1,  4, 0
  311.     SATD_4x4_MMX m2,  8, 0
  312.     paddw        m0, m1
  313.     SATD_4x4_MMX m1, 12, %1
  314.     paddw        m0, m2
  315. %endmacro
  316. %macro SATD_16x4_INC 1
  317.     SATD_4x4_MMX m2,  0, 0
  318.     paddw        m0, m1
  319.     SATD_4x4_MMX m1,  4, 0
  320.     paddw        m0, m2
  321.     SATD_4x4_MMX m2,  8, 0
  322.     paddw        m0, m1
  323.     SATD_4x4_MMX m1, 12, %1
  324.     paddw        m0, m2
  325. %endmacro
  326. %macro SATD_8x4_SSE2 1
  327.     LOAD_DIFF_8x4P  m0, m1, m2, m3, m4, m5
  328. %if %1
  329.     lea  r0, [r0+4*r1]
  330.     lea  r2, [r2+4*r3]
  331. %endif
  332.     HADAMARD4_1D    m0, m1, m2, m3
  333.     TRANSPOSE2x4x4W  0,  1,  2,  3,  4
  334.     HADAMARD4_1D    m0, m1, m2, m3
  335.     ABS4            m0, m1, m2, m3, m4, m5
  336.     paddusw  m0, m1
  337.     paddusw  m2, m3
  338.     paddusw  m6, m0
  339.     paddusw  m6, m2
  340. %endmacro
  341. %macro SATD_8x4_PHADD 1
  342.     LOAD_DIFF_8x4P  m0, m1, m2, m3, m4, m5
  343. %if %1
  344.     lea  r0, [r0+4*r1]
  345.     lea  r2, [r2+4*r3]
  346. %endif
  347.     HADAMARD4_1D    m0, m1, m2, m3
  348.     HADAMARD4_ROW_PHADD 0, 1, 2, 3, 4
  349.     ABS4            m0, m1, m2, m3, m4, m5
  350.     paddusw  m0, m1
  351.     paddusw  m2, m3
  352.     paddusw  m6, m0
  353.     paddusw  m6, m2
  354. %endmacro
  355. %macro SATD_START_MMX 0
  356.     lea  r4, [3*r1] ; 3*stride1
  357.     lea  r5, [3*r3] ; 3*stride2
  358. %endmacro
  359. %macro SATD_END_MMX 0
  360.     pshufw      m1, m0, 01001110b
  361.     paddw       m0, m1
  362.     pshufw      m1, m0, 10110001b
  363.     paddw       m0, m1
  364.     movd       eax, m0
  365.     and        eax, 0xffff
  366.     RET
  367. %endmacro
  368. ; FIXME avoid the spilling of regs to hold 3*stride.
  369. ; for small blocks on x86_32, modify pixel pointer instead.
  370. ;-----------------------------------------------------------------------------
  371. ; int x264_pixel_satd_16x16_mmxext (uint8_t *, int, uint8_t *, int )
  372. ;-----------------------------------------------------------------------------
  373. INIT_MMX
  374. cglobal x264_pixel_satd_16x16_mmxext, 4,6
  375.     SATD_START_MMX
  376.     SATD_16x4_START 1
  377.     SATD_16x4_INC 1
  378.     SATD_16x4_INC 1
  379.     SATD_16x4_INC 0
  380.     paddw       m0, m1
  381.     pxor        m3, m3
  382.     pshufw      m1, m0, 01001110b
  383.     paddw       m0, m1
  384.     punpcklwd   m0, m3
  385.     pshufw      m1, m0, 01001110b
  386.     paddd       m0, m1
  387.     movd       eax, m0
  388.     RET
  389. cglobal x264_pixel_satd_16x8_mmxext, 4,6
  390.     SATD_START_MMX
  391.     SATD_16x4_START 1
  392.     SATD_16x4_INC 0
  393.     paddw  m0, m1
  394.     SATD_END_MMX
  395. cglobal x264_pixel_satd_8x16_mmxext, 4,6
  396.     SATD_START_MMX
  397.     SATD_8x4_START 1
  398.     SATD_8x4_INC 1
  399.     SATD_8x4_INC 1
  400.     SATD_8x4_INC 0
  401.     paddw  m0, m1
  402.     SATD_END_MMX
  403. cglobal x264_pixel_satd_8x8_mmxext, 4,6
  404.     SATD_START_MMX
  405.     SATD_8x4_START 1
  406.     SATD_8x4_INC 0
  407.     paddw  m0, m1
  408.     SATD_END_MMX
  409. cglobal x264_pixel_satd_8x4_mmxext, 4,6
  410.     SATD_START_MMX
  411.     SATD_8x4_START 0
  412.     paddw  m0, m1
  413.     SATD_END_MMX
  414. %macro SATD_W4 1
  415. cglobal x264_pixel_satd_4x8_%1, 4,6
  416.     SATD_START_MMX
  417.     SATD_4x4_MMX m0, 0, 1
  418.     SATD_4x4_MMX m1, 0, 0
  419.     paddw  m0, m1
  420.     SATD_END_MMX
  421. cglobal x264_pixel_satd_4x4_%1, 4,6
  422.     SATD_START_MMX
  423.     SATD_4x4_MMX m0, 0, 0
  424.     SATD_END_MMX
  425. %endmacro
  426. SATD_W4 mmxext
  427. %macro SATD_START_SSE2 0
  428.     pxor    m6, m6
  429.     lea     r4, [3*r1]
  430.     lea     r5, [3*r3]
  431. %endmacro
  432. %macro SATD_END_SSE2 0
  433.     psrlw   m6, 1
  434.     HADDW   m6, m7
  435.     movd   eax, m6
  436.     RET
  437. %endmacro
  438. %macro BACKUP_POINTERS 0
  439. %ifdef ARCH_X86_64
  440.     mov    r10, r0
  441.     mov    r11, r2
  442. %endif
  443. %endmacro
  444. %macro RESTORE_AND_INC_POINTERS 0
  445. %ifdef ARCH_X86_64
  446.     lea     r0, [r10+8]
  447.     lea     r2, [r11+8]
  448. %else
  449.     mov     r0, r0m
  450.     mov     r2, r2m
  451.     add     r0, 8
  452.     add     r2, 8
  453. %endif
  454. %endmacro
  455. ;-----------------------------------------------------------------------------
  456. ; int x264_pixel_satd_8x4_sse2 (uint8_t *, int, uint8_t *, int )
  457. ;-----------------------------------------------------------------------------
  458. %macro SATDS_SSE2 1
  459. INIT_XMM
  460. cglobal x264_pixel_satd_16x16_%1, 4,6
  461.     SATD_START_SSE2
  462.     BACKUP_POINTERS
  463.     SATD_8x4_SSE2 1
  464.     SATD_8x4_SSE2 1
  465.     SATD_8x4_SSE2 1
  466.     SATD_8x4_SSE2 0
  467.     RESTORE_AND_INC_POINTERS
  468.     SATD_8x4_SSE2 1
  469.     SATD_8x4_SSE2 1
  470.     SATD_8x4_SSE2 1
  471.     SATD_8x4_SSE2 0
  472.     SATD_END_SSE2
  473. cglobal x264_pixel_satd_16x8_%1, 4,6
  474.     SATD_START_SSE2
  475.     BACKUP_POINTERS
  476.     SATD_8x4_SSE2 1
  477.     SATD_8x4_SSE2 0
  478.     RESTORE_AND_INC_POINTERS
  479.     SATD_8x4_SSE2 1
  480.     SATD_8x4_SSE2 0
  481.     SATD_END_SSE2
  482. cglobal x264_pixel_satd_8x16_%1, 4,6
  483.     SATD_START_SSE2
  484.     SATD_8x4_SSE2 1
  485.     SATD_8x4_SSE2 1
  486.     SATD_8x4_SSE2 1
  487.     SATD_8x4_SSE2 0
  488.     SATD_END_SSE2
  489. cglobal x264_pixel_satd_8x8_%1, 4,6
  490.     SATD_START_SSE2
  491.     SATD_8x4_SSE2 1
  492.     SATD_8x4_SSE2 0
  493.     SATD_END_SSE2
  494. cglobal x264_pixel_satd_8x4_%1, 4,6
  495.     SATD_START_SSE2
  496.     SATD_8x4_SSE2 0
  497.     SATD_END_SSE2
  498. %ifdef ARCH_X86_64
  499. ;-----------------------------------------------------------------------------
  500. ; int x264_pixel_sa8d_8x8_sse2( uint8_t *, int, uint8_t *, int )
  501. ;-----------------------------------------------------------------------------
  502. cglobal x264_pixel_sa8d_8x8_%1
  503.     lea  r4, [3*r1]
  504.     lea  r5, [3*r3]
  505. .skip_lea:
  506.     LOAD_DIFF_8x4P m0, m1, m2, m3, m8, m9
  507.     lea  r0, [r0+4*r1]
  508.     lea  r2, [r2+4*r3]
  509.     LOAD_DIFF_8x4P m4, m5, m6, m7, m8, m9
  510.     HADAMARD8_1D  m0, m1, m2, m3, m4, m5, m6, m7
  511.     TRANSPOSE8x8W  0,  1,  2,  3,  4,  5,  6,  7,  8
  512.     HADAMARD8_1D  m0, m1, m2, m3, m4, m5, m6, m7
  513.     ABS4 m0, m1, m2, m3, m8, m9
  514.     ABS4 m4, m5, m6, m7, m8, m9
  515.     paddusw  m0, m1
  516.     paddusw  m2, m3
  517.     paddusw  m4, m5
  518.     paddusw  m6, m7
  519.     paddusw  m0, m2
  520.     paddusw  m4, m6
  521.     pavgw    m0, m4
  522.     HADDW    m0, m1
  523.     movd eax, m0
  524.     add r10d, eax ; preserve rounding for 16x16
  525.     add eax, 1
  526.     shr eax, 1
  527.     ret
  528. cglobal x264_pixel_sa8d_16x16_%1
  529.     xor  r10d, r10d
  530.     call x264_pixel_sa8d_8x8_%1 ; pix[0]
  531.     lea  r0, [r0+4*r1]
  532.     lea  r2, [r2+4*r3]
  533.     call x264_pixel_sa8d_8x8_%1.skip_lea ; pix[8*stride]
  534.     neg  r4 ; it's already r1*3
  535.     neg  r5
  536.     lea  r0, [r0+4*r4+8]
  537.     lea  r2, [r2+4*r5+8]
  538.     call x264_pixel_sa8d_8x8_%1 ; pix[8]
  539.     lea  r0, [r0+4*r1]
  540.     lea  r2, [r2+4*r3]
  541.     call x264_pixel_sa8d_8x8_%1.skip_lea ; pix[8*stride+8]
  542.     mov  eax, r10d
  543.     add  eax, 1
  544.     shr  eax, 1
  545.     ret
  546. %else ; ARCH_X86_32
  547. cglobal x264_pixel_sa8d_8x8_%1, 4,7
  548.     mov  r6, esp
  549.     and  esp, ~15
  550.     sub  esp, 32
  551.     lea  r4, [3*r1]
  552.     lea  r5, [3*r3]
  553.     LOAD_DIFF_8x4P m0, m1, m2, m3, m6, m7
  554.     movdqa [esp], m2
  555.     lea  r0, [r0+4*r1]
  556.     lea  r2, [r2+4*r3]
  557.     LOAD_DIFF_8x4P m4, m5, m6, m7, m2, m2
  558.     movdqa m2, [esp]
  559.     HADAMARD8_1D  m0, m1, m2, m3, m4, m5, m6, m7
  560.     TRANSPOSE8x8W  0,  1,  2,  3,  4,  5,  6,  7, [esp], [esp+16]
  561.     HADAMARD8_1D  m0, m1, m2, m3, m4, m5, m6, m7
  562. %ifidn %1, sse2
  563.     movdqa [esp], m4
  564.     movdqa [esp+16], m2
  565. %endif
  566.     ABS2 m6, m3, m4, m2
  567.     ABS2 m0, m7, m4, m2
  568.     paddusw m0, m6
  569.     paddusw m7, m3
  570. %ifidn %1, sse2
  571.     movdqa m4, [esp]
  572.     movdqa m2, [esp+16]
  573. %endif
  574.     ABS2 m5, m1, m6, m3
  575.     ABS2 m4, m2, m6, m3
  576.     paddusw m5, m1
  577.     paddusw m4, m2
  578.     paddusw m0, m7
  579.     paddusw m5, m4
  580.     pavgw   m0, m5
  581.     HADDW   m0, m7
  582.     movd eax, m0
  583.     mov  ecx, eax ; preserve rounding for 16x16
  584.     add  eax, 1
  585.     shr  eax, 1
  586.     mov  esp, r6
  587.     RET
  588. %endif ; ARCH
  589. %endmacro ; SATDS_SSE2
  590. %macro SA8D_16x16_32 1
  591. %ifndef ARCH_X86_64
  592. cglobal x264_pixel_sa8d_16x16_%1
  593.     push   ebp
  594.     push   dword [esp+20]   ; stride2
  595.     push   dword [esp+20]   ; pix2
  596.     push   dword [esp+20]   ; stride1
  597.     push   dword [esp+20]   ; pix1
  598.     call x264_pixel_sa8d_8x8_%1
  599.     mov    ebp, ecx
  600.     add    dword [esp+0], 8 ; pix1+8
  601.     add    dword [esp+8], 8 ; pix2+8
  602.     call x264_pixel_sa8d_8x8_%1
  603.     add    ebp, ecx
  604.     mov    eax, [esp+4]
  605.     mov    edx, [esp+12]
  606.     shl    eax, 3
  607.     shl    edx, 3
  608.     add    [esp+0], eax     ; pix1+8*stride1+8
  609.     add    [esp+8], edx     ; pix2+8*stride2+8
  610.     call x264_pixel_sa8d_8x8_%1
  611.     add    ebp, ecx
  612.     sub    dword [esp+0], 8 ; pix1+8*stride1
  613.     sub    dword [esp+8], 8 ; pix2+8*stride2
  614.     call x264_pixel_sa8d_8x8_%1
  615.     lea    eax, [ebp+ecx+1]
  616.     shr    eax, 1
  617.     add    esp, 16
  618.     pop    ebp
  619.     ret
  620. %endif ; !ARCH_X86_64
  621. %endmacro ; SA8D_16x16_32
  622. ;=============================================================================
  623. ; INTRA SATD
  624. ;=============================================================================
  625. %macro INTRA_SA8D_SSE2 1
  626. %ifdef ARCH_X86_64
  627. INIT_XMM
  628. ;-----------------------------------------------------------------------------
  629. ; void x264_intra_sa8d_x3_8x8_core_sse2( uint8_t *fenc, int16_t edges[2][8], int *res )
  630. ;-----------------------------------------------------------------------------
  631. cglobal x264_intra_sa8d_x3_8x8_core_%1
  632.     ; 8x8 hadamard
  633.     pxor        m8, m8
  634.     movq        m0, [r0+0*FENC_STRIDE]
  635.     movq        m1, [r0+1*FENC_STRIDE]
  636.     movq        m2, [r0+2*FENC_STRIDE]
  637.     movq        m3, [r0+3*FENC_STRIDE]
  638.     movq        m4, [r0+4*FENC_STRIDE]
  639.     movq        m5, [r0+5*FENC_STRIDE]
  640.     movq        m6, [r0+6*FENC_STRIDE]
  641.     movq        m7, [r0+7*FENC_STRIDE]
  642.     punpcklbw   m0, m8
  643.     punpcklbw   m1, m8
  644.     punpcklbw   m2, m8
  645.     punpcklbw   m3, m8
  646.     punpcklbw   m4, m8
  647.     punpcklbw   m5, m8
  648.     punpcklbw   m6, m8
  649.     punpcklbw   m7, m8
  650.     HADAMARD8_1D  m0, m1, m2, m3, m4, m5, m6, m7
  651.     TRANSPOSE8x8W  0,  1,  2,  3,  4,  5,  6,  7,  8
  652.     HADAMARD8_1D  m0, m1, m2, m3, m4, m5, m6, m7
  653.     ; dc
  654.     movzx       edi, word [r1+0]
  655.     add          di, word [r1+16]
  656.     add         edi, 8
  657.     and         edi, -16
  658.     shl         edi, 2
  659.     pxor        m15, m15
  660.     movdqa      m8,  m2
  661.     movdqa      m9,  m3
  662.     movdqa      m10, m4
  663.     movdqa      m11, m5
  664.     ABS4        m8, m9, m10, m11, m12, m13
  665.     paddusw     m8,  m10
  666.     paddusw     m9,  m11
  667. %ifidn %1, ssse3
  668.     pabsw       m10, m6
  669.     pabsw       m11, m7
  670.     pabsw       m15, m1
  671. %else
  672.     movdqa      m10, m6
  673.     movdqa      m11, m7
  674.     movdqa      m15, m1
  675.     ABS2        m10, m11, m13, m14
  676.     ABS1        m15, m13
  677. %endif
  678.     paddusw     m10, m11
  679.     paddusw     m8,  m9
  680.     paddusw     m15, m10
  681.     paddusw     m15, m8
  682.     movdqa      m14, m15 ; 7x8 sum
  683.     movdqa      m8,  [r1+0] ; left edge
  684.     movd        m9,  edi
  685.     psllw       m8,  3
  686.     psubw       m8,  m0
  687.     psubw       m9,  m0
  688.     ABS1        m8,  m10
  689.     ABS1        m9,  m11 ; 1x8 sum
  690.     paddusw     m14, m8
  691.     paddusw     m15, m9
  692.     punpcklwd   m0,  m1
  693.     punpcklwd   m2,  m3
  694.     punpcklwd   m4,  m5
  695.     punpcklwd   m6,  m7
  696.     punpckldq   m0,  m2
  697.     punpckldq   m4,  m6
  698.     punpcklqdq  m0,  m4 ; transpose
  699.     movdqa      m1,  [r1+16] ; top edge
  700.     movdqa      m2,  m15
  701.     psllw       m1,  3
  702.     psrldq      m2,  2     ; 8x7 sum
  703.     psubw       m0,  m1  ; 8x1 sum
  704.     ABS1        m0,  m1
  705.     paddusw     m2,  m0
  706.     ; 3x HADDW
  707.     movdqa      m7,  [pw_1 GLOBAL]
  708.     pmaddwd     m2,  m7
  709.     pmaddwd     m14, m7
  710.     pmaddwd     m15, m7
  711.     movdqa      m3,  m2
  712.     punpckldq   m2,  m14
  713.     punpckhdq   m3,  m14
  714.     pshufd      m5,  m15, 0xf5
  715.     paddd       m2,  m3
  716.     paddd       m5,  m15
  717.     movdqa      m3,  m2
  718.     punpcklqdq  m2,  m5
  719.     punpckhqdq  m3,  m5
  720.     pavgw       m3,  m2
  721.     pxor        m0,  m0
  722.     pavgw       m3,  m0
  723.     movq      [r2],  m3 ; i8x8_v, i8x8_h
  724.     psrldq      m3,  8
  725.     movd    [r2+8],  m3 ; i8x8_dc
  726.     ret
  727. %endif ; ARCH_X86_64
  728. %endmacro ; INTRA_SA8D_SSE2
  729. ; in: r0 = fenc
  730. ; out: m0..m3 = hadamard coefs
  731. INIT_MMX
  732. ALIGN 16
  733. load_hadamard:
  734.     pxor        m7, m7
  735.     movd        m0, [r0+0*FENC_STRIDE]
  736.     movd        m1, [r0+1*FENC_STRIDE]
  737.     movd        m2, [r0+2*FENC_STRIDE]
  738.     movd        m3, [r0+3*FENC_STRIDE]
  739.     punpcklbw   m0, m7
  740.     punpcklbw   m1, m7
  741.     punpcklbw   m2, m7
  742.     punpcklbw   m3, m7
  743.     HADAMARD4_1D  m0, m1, m2, m3
  744.     TRANSPOSE4x4W  0,  1,  2,  3,  4
  745.     HADAMARD4_1D  m0, m1, m2, m3
  746.     SAVE_MM_PERMUTATION load_hadamard
  747.     ret
  748. %macro SCALAR_SUMSUB 4
  749.     add %1, %2
  750.     add %3, %4
  751.     add %2, %2
  752.     add %4, %4
  753.     sub %2, %1
  754.     sub %4, %3
  755. %endmacro
  756. %macro SCALAR_HADAMARD_LEFT 5 ; y, 4x tmp
  757. %ifnidn %1, 0
  758.     shl         %1d, 5 ; log(FDEC_STRIDE)
  759. %endif
  760.     movzx       %2d, byte [r1+%1-1+0*FDEC_STRIDE]
  761.     movzx       %3d, byte [r1+%1-1+1*FDEC_STRIDE]
  762.     movzx       %4d, byte [r1+%1-1+2*FDEC_STRIDE]
  763.     movzx       %5d, byte [r1+%1-1+3*FDEC_STRIDE]
  764. %ifnidn %1, 0
  765.     shr         %1d, 5
  766. %endif
  767.     SCALAR_SUMSUB %2d, %3d, %4d, %5d
  768.     SCALAR_SUMSUB %2d, %4d, %3d, %5d
  769.     mov         [left_1d+2*%1+0], %2w
  770.     mov         [left_1d+2*%1+2], %3w
  771.     mov         [left_1d+2*%1+4], %4w
  772.     mov         [left_1d+2*%1+6], %5w
  773. %endmacro
  774. %macro SCALAR_HADAMARD_TOP 5 ; x, 4x tmp
  775.     movzx       %2d, byte [r1+%1-FDEC_STRIDE+0]
  776.     movzx       %3d, byte [r1+%1-FDEC_STRIDE+1]
  777.     movzx       %4d, byte [r1+%1-FDEC_STRIDE+2]
  778.     movzx       %5d, byte [r1+%1-FDEC_STRIDE+3]
  779.     SCALAR_SUMSUB %2d, %3d, %4d, %5d
  780.     SCALAR_SUMSUB %2d, %4d, %3d, %5d
  781.     mov         [top_1d+2*%1+0], %2w
  782.     mov         [top_1d+2*%1+2], %3w
  783.     mov         [top_1d+2*%1+4], %4w
  784.     mov         [top_1d+2*%1+6], %5w
  785. %endmacro
  786. %macro SUM_MM_X3 8 ; 3x sum, 4x tmp, op
  787.     pxor        %7, %7
  788.     pshufw      %4, %1, 01001110b
  789.     pshufw      %5, %2, 01001110b
  790.     pshufw      %6, %3, 01001110b
  791.     paddw       %1, %4
  792.     paddw       %2, %5
  793.     paddw       %3, %6
  794.     punpcklwd   %1, %7
  795.     punpcklwd   %2, %7
  796.     punpcklwd   %3, %7
  797.     pshufw      %4, %1, 01001110b
  798.     pshufw      %5, %2, 01001110b
  799.     pshufw      %6, %3, 01001110b
  800.     %8          %1, %4
  801.     %8          %2, %5
  802.     %8          %3, %6
  803. %endmacro
  804. %macro CLEAR_SUMS 0
  805. %ifdef ARCH_X86_64
  806.     mov   qword [sums+0], 0
  807.     mov   qword [sums+8], 0
  808.     mov   qword [sums+16], 0
  809. %else
  810.     pxor  m7, m7
  811.     movq  [sums+0], m7
  812.     movq  [sums+8], m7
  813.     movq  [sums+16], m7
  814. %endif
  815. %endmacro
  816. ; in: m1..m3
  817. ; out: m7
  818. ; clobber: m4..m6
  819. %macro SUM3x4 1
  820. %ifidn %1, ssse3
  821.     pabsw       m4, m1
  822.     pabsw       m5, m2
  823.     pabsw       m7, m3
  824.     paddw       m4, m5
  825. %else
  826.     movq        m4, m1
  827.     movq        m5, m2
  828.     ABS2        m4, m5, m6, m7
  829.     movq        m7, m3
  830.     paddw       m4, m5
  831.     ABS1        m7, m6
  832. %endif
  833.     paddw       m7, m4
  834. %endmacro
  835. ; in: m0..m3 (4x4), m7 (3x4)
  836. ; out: m0 v, m4 h, m5 dc
  837. ; clobber: m6
  838. %macro SUM4x3 3 ; dc, left, top
  839.     movq        m4, %2
  840.     movd        m5, %1
  841.     psllw       m4, 2
  842.     psubw       m4, m0
  843.     psubw       m5, m0
  844.     punpcklwd   m0, m1
  845.     punpcklwd   m2, m3
  846.     punpckldq   m0, m2 ; transpose
  847.     movq        m1, %3
  848.     psllw       m1, 2
  849.     psubw       m0, m1
  850.     ABS2        m4, m5, m2, m3 ; 1x4 sum
  851.     ABS1        m0, m1 ; 4x1 sum
  852. %endmacro
  853. %macro INTRA_SATDS_MMX 1
  854. INIT_MMX
  855. ;-----------------------------------------------------------------------------
  856. ; void x264_intra_satd_x3_4x4_mmxext( uint8_t *fenc, uint8_t *fdec, int *res )
  857. ;-----------------------------------------------------------------------------
  858. cglobal x264_intra_satd_x3_4x4_%1, 2,6
  859. %ifdef ARCH_X86_64
  860.     ; stack is 16 byte aligned because abi says so
  861.     %define  top_1d  rsp-8  ; size 8
  862.     %define  left_1d rsp-16 ; size 8
  863.     %define  t0  r10
  864.     %define  t0d r10d
  865. %else
  866.     ; stack is 16 byte aligned at least in gcc, and we've pushed 3 regs + return address, so it's still aligned
  867.     SUB         esp, 16
  868.     %define  top_1d  esp+8
  869.     %define  left_1d esp
  870.     %define  t0  r2
  871.     %define  t0d r2d
  872. %endif
  873.     call load_hadamard
  874.     SCALAR_HADAMARD_LEFT 0, r0, r3, r4, r5
  875.     mov         t0d, r0d
  876.     SCALAR_HADAMARD_TOP  0, r0, r3, r4, r5
  877.     lea         t0d, [t0d + r0d + 4]
  878.     and         t0d, -8
  879.     shl         t0d, 1 ; dc
  880.     SUM3x4 %1
  881.     SUM4x3 t0d, [left_1d], [top_1d]
  882.     paddw       m4, m7
  883.     paddw       m5, m7
  884.     movq        m1, m5
  885.     psrlq       m1, 16  ; 4x3 sum
  886.     paddw       m0, m1
  887.     SUM_MM_X3   m0, m4, m5, m1, m2, m3, m6, pavgw
  888. %ifndef ARCH_X86_64
  889.     mov         r2, r2m
  890. %endif
  891.     movd        [r2+0], m0 ; i4x4_v satd
  892.     movd        [r2+4], m4 ; i4x4_h satd
  893.     movd        [r2+8], m5 ; i4x4_dc satd
  894. %ifndef ARCH_X86_64
  895.     ADD         esp, 16
  896. %endif
  897.     RET
  898. %ifdef ARCH_X86_64
  899.     %define  t0  r10
  900.     %define  t0d r10d
  901.     %define  t2  r11
  902.     %define  t2w r11w
  903.     %define  t2d r11d
  904. %else
  905.     %define  t0  r0
  906.     %define  t0d r0d
  907.     %define  t2  r2
  908.     %define  t2w r2w
  909.     %define  t2d r2d
  910. %endif
  911. ;-----------------------------------------------------------------------------
  912. ; void x264_intra_satd_x3_16x16_mmxext( uint8_t *fenc, uint8_t *fdec, int *res )
  913. ;-----------------------------------------------------------------------------
  914. cglobal x264_intra_satd_x3_16x16_%1, 0,7
  915. %ifdef ARCH_X86_64
  916.     %assign  stack_pad  88
  917. %else
  918.     %assign  stack_pad  88 + ((stack_offset+88+4)&15)
  919. %endif
  920.     ; not really needed on x86_64, just shuts up valgrind about storing data below the stack across a function call
  921.     SUB         rsp, stack_pad
  922. %define sums    rsp+64 ; size 24
  923. %define top_1d  rsp+32 ; size 32
  924. %define left_1d rsp    ; size 32
  925.     movifnidn   r1d, r1m
  926.     CLEAR_SUMS
  927.     ; 1D hadamards
  928.     xor         t2d, t2d
  929.     mov         t0d, 12
  930. .loop_edge:
  931.     SCALAR_HADAMARD_LEFT t0, r3, r4, r5, r6
  932.     add         t2d, r3d
  933.     SCALAR_HADAMARD_TOP  t0, r3, r4, r5, r6
  934.     add         t2d, r3d
  935.     sub         t0d, 4
  936.     jge .loop_edge
  937.     shr         t2d, 1
  938.     add         t2d, 8
  939.     and         t2d, -16 ; dc
  940.     ; 2D hadamards
  941.     movifnidn   r0d, r0m
  942.     xor         r3d, r3d
  943. .loop_y:
  944.     xor         r4d, r4d
  945. .loop_x:
  946.     call load_hadamard
  947.     SUM3x4 %1
  948.     SUM4x3 t2d, [left_1d+8*r3], [top_1d+8*r4]
  949.     pavgw       m4, m7
  950.     pavgw       m5, m7
  951.     paddw       m0, [sums+0]  ; i16x16_v satd
  952.     paddw       m4, [sums+8]  ; i16x16_h satd
  953.     paddw       m5, [sums+16] ; i16x16_dc satd
  954.     movq        [sums+0], m0
  955.     movq        [sums+8], m4
  956.     movq        [sums+16], m5
  957.     add         r0, 4
  958.     inc         r4d
  959.     cmp         r4d, 4
  960.     jl  .loop_x
  961.     add         r0, 4*FENC_STRIDE-16
  962.     inc         r3d
  963.     cmp         r3d, 4
  964.     jl  .loop_y
  965. ; horizontal sum
  966.     movifnidn   r2d, r2m
  967.     movq        m2, [sums+16]
  968.     movq        m1, [sums+8]
  969.     movq        m0, [sums+0]
  970.     movq        m7, m2
  971.     SUM_MM_X3   m0, m1, m2, m3, m4, m5, m6, paddd
  972.     psrld       m0, 1
  973.     pslld       m7, 16
  974.     psrld       m7, 16
  975.     paddd       m0, m2
  976.     psubd       m0, m7
  977.     movd        [r2+8], m2 ; i16x16_dc satd
  978.     movd        [r2+4], m1 ; i16x16_h satd
  979.     movd        [r2+0], m0 ; i16x16_v satd
  980.     ADD         rsp, stack_pad
  981.     RET
  982. ;-----------------------------------------------------------------------------
  983. ; void x264_intra_satd_x3_8x8c_mmxext( uint8_t *fenc, uint8_t *fdec, int *res )
  984. ;-----------------------------------------------------------------------------
  985. cglobal x264_intra_satd_x3_8x8c_%1, 0,6
  986.     ; not really needed on x86_64, just shuts up valgrind about storing data below the stack across a function call
  987.     SUB          rsp, 72
  988. %define  sums    rsp+48 ; size 24
  989. %define  dc_1d   rsp+32 ; size 16
  990. %define  top_1d  rsp+16 ; size 16
  991. %define  left_1d rsp    ; size 16
  992.     movifnidn   r1d, r1m
  993.     CLEAR_SUMS
  994.     ; 1D hadamards
  995.     mov         t0d, 4
  996. .loop_edge:
  997.     SCALAR_HADAMARD_LEFT t0, t2, r3, r4, r5
  998.     SCALAR_HADAMARD_TOP  t0, t2, r3, r4, r5
  999.     sub         t0d, 4
  1000.     jge .loop_edge
  1001.     ; dc
  1002.     movzx       t2d, word [left_1d+0]
  1003.     movzx       r3d, word [top_1d+0]
  1004.     movzx       r4d, word [left_1d+8]
  1005.     movzx       r5d, word [top_1d+8]
  1006.     add         t2d, r3d
  1007.     lea         r3, [r4 + r5]
  1008.     lea         t2, [2*t2 + 8]
  1009.     lea         r3, [2*r3 + 8]
  1010.     lea         r4, [4*r4 + 8]
  1011.     lea         r5, [4*r5 + 8]
  1012.     and         t2d, -16 ; tl
  1013.     and         r3d, -16 ; br
  1014.     and         r4d, -16 ; bl
  1015.     and         r5d, -16 ; tr
  1016.     mov         [dc_1d+ 0], t2d ; tl
  1017.     mov         [dc_1d+ 4], r5d ; tr
  1018.     mov         [dc_1d+ 8], r4d ; bl
  1019.     mov         [dc_1d+12], r3d ; br
  1020.     lea         r5, [dc_1d]
  1021.     ; 2D hadamards
  1022.     movifnidn   r0d, r0m
  1023.     movifnidn   r2d, r2m
  1024.     xor         r3d, r3d
  1025. .loop_y:
  1026.     xor         r4d, r4d
  1027. .loop_x:
  1028.     call load_hadamard
  1029.     SUM3x4 %1
  1030.     SUM4x3 [r5+4*r4], [left_1d+8*r3], [top_1d+8*r4]
  1031.     pavgw       m4, m7
  1032.     pavgw       m5, m7
  1033.     paddw       m0, [sums+16] ; i4x4_v satd
  1034.     paddw       m4, [sums+8]  ; i4x4_h satd
  1035.     paddw       m5, [sums+0]  ; i4x4_dc satd
  1036.     movq        [sums+16], m0
  1037.     movq        [sums+8], m4
  1038.     movq        [sums+0], m5
  1039.     add         r0, 4
  1040.     inc         r4d
  1041.     cmp         r4d, 2
  1042.     jl  .loop_x
  1043.     add         r0, 4*FENC_STRIDE-8
  1044.     add         r5, 8
  1045.     inc         r3d
  1046.     cmp         r3d, 2
  1047.     jl  .loop_y
  1048. ; horizontal sum
  1049.     movq        m0, [sums+0]
  1050.     movq        m1, [sums+8]
  1051.     movq        m2, [sums+16]
  1052.     movq        m7, m0
  1053.     psrlq       m7, 15
  1054.     paddw       m2, m7
  1055.     SUM_MM_X3   m0, m1, m2, m3, m4, m5, m6, paddd
  1056.     psrld       m2, 1
  1057.     movd        [r2+0], m0 ; i8x8c_dc satd
  1058.     movd        [r2+4], m1 ; i8x8c_h satd
  1059.     movd        [r2+8], m2 ; i8x8c_v satd
  1060.     ADD         rsp, 72
  1061.     RET
  1062. %endmacro ; INTRA_SATDS_MMX
  1063. ; instantiate satds
  1064. %ifndef ARCH_X86_64
  1065. cextern x264_pixel_sa8d_8x8_mmxext
  1066. SA8D_16x16_32 mmxext
  1067. %endif
  1068. %define ABS1 ABS1_MMX
  1069. %define ABS2 ABS2_MMX
  1070. SATDS_SSE2 sse2
  1071. SA8D_16x16_32 sse2
  1072. INTRA_SA8D_SSE2 sse2
  1073. INTRA_SATDS_MMX mmxext
  1074. %define ABS1 ABS1_SSSE3
  1075. %define ABS2 ABS2_SSSE3
  1076. SATDS_SSE2 ssse3
  1077. SA8D_16x16_32 ssse3
  1078. INTRA_SA8D_SSE2 ssse3
  1079. INTRA_SATDS_MMX ssse3
  1080. SATD_W4 ssse3 ; mmx, but uses pabsw from ssse3.
  1081. %define SATD_8x4_SSE2 SATD_8x4_PHADD
  1082. SATDS_SSE2 ssse3_phadd
  1083. ;=============================================================================
  1084. ; SSIM
  1085. ;=============================================================================
  1086. ;-----------------------------------------------------------------------------
  1087. ; void x264_pixel_ssim_4x4x2_core_sse2( const uint8_t *pix1, int stride1,
  1088. ;                                       const uint8_t *pix2, int stride2, int sums[2][4] )
  1089. ;-----------------------------------------------------------------------------
  1090. cglobal x264_pixel_ssim_4x4x2_core_sse2, 4,4
  1091.     pxor      m0, m0
  1092.     pxor      m1, m1
  1093.     pxor      m2, m2
  1094.     pxor      m3, m3
  1095.     pxor      m4, m4
  1096. %rep 4
  1097.     movq      m5, [r0]
  1098.     movq      m6, [r2]
  1099.     punpcklbw m5, m0
  1100.     punpcklbw m6, m0
  1101.     paddw     m1, m5
  1102.     paddw     m2, m6
  1103.     movdqa    m7, m5
  1104.     pmaddwd   m5, m5
  1105.     pmaddwd   m7, m6
  1106.     pmaddwd   m6, m6
  1107.     paddd     m3, m5
  1108.     paddd     m4, m7
  1109.     paddd     m3, m6
  1110.     add       r0, r1
  1111.     add       r2, r3
  1112. %endrep
  1113.     ; PHADDW m1, m2
  1114.     ; PHADDD m3, m4
  1115.     movdqa    m7, [pw_1 GLOBAL]
  1116.     pshufd    m5, m3, 0xb1
  1117.     pmaddwd   m1, m7
  1118.     pmaddwd   m2, m7
  1119.     pshufd    m6, m4, 0xb1
  1120.     packssdw  m1, m2
  1121.     paddd     m3, m5
  1122.     pshufd    m1, m1, 0xd8
  1123.     paddd     m4, m6
  1124.     pmaddwd   m1, m7
  1125.     movdqa    m5, m3
  1126.     punpckldq m3, m4
  1127.     punpckhdq m5, m4
  1128. %ifdef ARCH_X86_64
  1129.     %define t0 r4
  1130. %else
  1131.     %define t0 eax
  1132.     mov t0, r4m
  1133. %endif
  1134.     movq      [t0+ 0], m1
  1135.     movq      [t0+ 8], m3
  1136.     psrldq    m1, 8
  1137.     movq      [t0+16], m1
  1138.     movq      [t0+24], m5
  1139.     RET
  1140. ;-----------------------------------------------------------------------------
  1141. ; float x264_pixel_ssim_end_sse2( int sum0[5][4], int sum1[5][4], int width )
  1142. ;-----------------------------------------------------------------------------
  1143. cglobal x264_pixel_ssim_end4_sse2, 3,3
  1144.     movdqa    m0, [r0+ 0]
  1145.     movdqa    m1, [r0+16]
  1146.     movdqa    m2, [r0+32]
  1147.     movdqa    m3, [r0+48]
  1148.     movdqa    m4, [r0+64]
  1149.     paddd     m0, [r1+ 0]
  1150.     paddd     m1, [r1+16]
  1151.     paddd     m2, [r1+32]
  1152.     paddd     m3, [r1+48]
  1153.     paddd     m4, [r1+64]
  1154.     paddd     m0, m1
  1155.     paddd     m1, m2
  1156.     paddd     m2, m3
  1157.     paddd     m3, m4
  1158.     movdqa    m5, [ssim_c1 GLOBAL]
  1159.     movdqa    m6, [ssim_c2 GLOBAL]
  1160.     TRANSPOSE4x4D  0, 1, 2, 3, 4
  1161. ;   s1=m0, s2=m1, ss=m2, s12=m3
  1162.     movdqa    m4, m1
  1163.     pslld     m1, 16
  1164.     pmaddwd   m4, m0  ; s1*s2
  1165.     por       m0, m1
  1166.     pmaddwd   m0, m0  ; s1*s1 + s2*s2
  1167.     pslld     m4, 1
  1168.     pslld     m3, 7
  1169.     pslld     m2, 6
  1170.     psubd     m3, m4  ; covar*2
  1171.     psubd     m2, m0  ; vars
  1172.     paddd     m0, m5
  1173.     paddd     m4, m5
  1174.     paddd     m3, m6
  1175.     paddd     m2, m6
  1176.     cvtdq2ps  m0, m0  ; (float)(s1*s1 + s2*s2 + ssim_c1)
  1177.     cvtdq2ps  m4, m4  ; (float)(s1*s2*2 + ssim_c1)
  1178.     cvtdq2ps  m3, m3  ; (float)(covar*2 + ssim_c2)
  1179.     cvtdq2ps  m2, m2  ; (float)(vars + ssim_c2)
  1180.     mulps     m4, m3
  1181.     mulps     m0, m2
  1182.     divps     m4, m0  ; ssim
  1183.     cmp       r2d, 4
  1184.     je .skip ; faster only if this is the common case; remove branch if we use ssim on a macroblock level
  1185.     neg       r2
  1186. %ifdef PIC
  1187.     lea       r3, [mask_ff + 16 GLOBAL]
  1188.     movdqu    m1, [r3 + r2*4]
  1189. %else
  1190.     movdqu    m1, [mask_ff + r2*4 + 16 GLOBAL]
  1191. %endif
  1192.     pand      m4, m1
  1193. .skip:
  1194.     movhlps   m0, m4
  1195.     addps     m0, m4
  1196.     pshuflw   m4, m0, 0xE
  1197.     addss     m0, m4
  1198. %ifndef ARCH_X86_64
  1199.     movd     r0m, m0
  1200.     fld     dword r0m
  1201. %endif
  1202.     RET
  1203. ;=============================================================================
  1204. ; Successive Elimination ADS
  1205. ;=============================================================================
  1206. %macro ADS_START 1 ; unroll_size
  1207. %ifdef ARCH_X86_64
  1208.     %define t0  r6
  1209.     mov     r10, rsp
  1210. %else
  1211.     %define t0  r4
  1212.     mov     rbp, rsp
  1213. %endif
  1214.     mov     r0d, r5m
  1215.     sub     rsp, r0
  1216.     sub     rsp, %1*4-1
  1217.     and     rsp, ~15
  1218.     mov     t0,  rsp
  1219.     shl     r2d,  1
  1220. %endmacro
  1221. %macro ADS_END 1
  1222.     add     r1, 8*%1
  1223.     add     r3, 8*%1
  1224.     add     t0, 4*%1
  1225.     sub     r0d, 4*%1
  1226.     jg .loop
  1227.     jmp ads_mvs
  1228. %endmacro
  1229. %define ABS1 ABS1_MMX
  1230. ;-----------------------------------------------------------------------------
  1231. ; int x264_pixel_ads4_mmxext( int enc_dc[4], uint16_t *sums, int delta,
  1232. ;                             uint16_t *cost_mvx, int16_t *mvs, int width, int thresh )
  1233. ;-----------------------------------------------------------------------------
  1234. cglobal x264_pixel_ads4_mmxext, 4,7
  1235.     movq    mm6, [r0]
  1236.     movq    mm4, [r0+8]
  1237.     pshufw  mm7, mm6, 0
  1238.     pshufw  mm6, mm6, 0xAA
  1239.     pshufw  mm5, mm4, 0
  1240.     pshufw  mm4, mm4, 0xAA
  1241.     ADS_START 1
  1242. .loop:
  1243.     movq    mm0, [r1]
  1244.     movq    mm1, [r1+16]
  1245.     psubw   mm0, mm7
  1246.     psubw   mm1, mm6
  1247.     ABS1    mm0, mm2
  1248.     ABS1    mm1, mm3
  1249.     movq    mm2, [r1+r2]
  1250.     movq    mm3, [r1+r2+16]
  1251.     psubw   mm2, mm5
  1252.     psubw   mm3, mm4
  1253.     paddw   mm0, mm1
  1254.     ABS1    mm2, mm1
  1255.     ABS1    mm3, mm1
  1256.     paddw   mm0, mm2
  1257.     paddw   mm0, mm3
  1258. %ifdef ARCH_X86_64
  1259.     pshufw  mm1, [r10+8], 0
  1260. %else
  1261.     pshufw  mm1, [ebp+stack_offset+28], 0
  1262. %endif
  1263.     paddusw mm0, [r3]
  1264.     psubusw mm1, mm0
  1265.     packsswb mm1, mm1
  1266.     movd    [t0], mm1
  1267.     ADS_END 1
  1268. cglobal x264_pixel_ads2_mmxext, 4,7
  1269.     movq    mm6, [r0]
  1270.     pshufw  mm5, r6m, 0
  1271.     pshufw  mm7, mm6, 0
  1272.     pshufw  mm6, mm6, 0xAA
  1273.     ADS_START 1
  1274. .loop:
  1275.     movq    mm0, [r1]
  1276.     movq    mm1, [r1+r2]
  1277.     psubw   mm0, mm7
  1278.     psubw   mm1, mm6
  1279.     ABS1    mm0, mm2
  1280.     ABS1    mm1, mm3
  1281.     paddw   mm0, mm1
  1282.     paddusw mm0, [r3]
  1283.     movq    mm4, mm5
  1284.     psubusw mm4, mm0
  1285.     packsswb mm4, mm4
  1286.     movd    [t0], mm4
  1287.     ADS_END 1
  1288. cglobal x264_pixel_ads1_mmxext, 4,7
  1289.     pshufw  mm7, [r0], 0
  1290.     pshufw  mm6, r6m, 0
  1291.     ADS_START 2
  1292. .loop:
  1293.     movq    mm0, [r1]
  1294.     movq    mm1, [r1+8]
  1295.     psubw   mm0, mm7
  1296.     psubw   mm1, mm7
  1297.     ABS1    mm0, mm2
  1298.     ABS1    mm1, mm3
  1299.     paddusw mm0, [r3]
  1300.     paddusw mm1, [r3+8]
  1301.     movq    mm4, mm6
  1302.     movq    mm5, mm6
  1303.     psubusw mm4, mm0
  1304.     psubusw mm5, mm1
  1305.     packsswb mm4, mm5
  1306.     movq    [t0], mm4
  1307.     ADS_END 2
  1308. %macro ADS_SSE2 1
  1309. cglobal x264_pixel_ads4_%1, 4,7
  1310.     movdqa  xmm4, [r0]
  1311.     pshuflw xmm7, xmm4, 0
  1312.     pshuflw xmm6, xmm4, 0xAA
  1313.     pshufhw xmm5, xmm4, 0
  1314.     pshufhw xmm4, xmm4, 0xAA
  1315.     punpcklqdq xmm7, xmm7
  1316.     punpcklqdq xmm6, xmm6
  1317.     punpckhqdq xmm5, xmm5
  1318.     punpckhqdq xmm4, xmm4
  1319. %ifdef ARCH_X86_64
  1320.     pshuflw xmm8, r6m, 0
  1321.     punpcklqdq xmm8, xmm8
  1322.     ADS_START 2
  1323.     movdqu  xmm10, [r1]
  1324.     movdqu  xmm11, [r1+r2]
  1325. .loop:
  1326.     movdqa  xmm0, xmm10
  1327.     movdqu  xmm1, [r1+16]
  1328.     movdqa  xmm10, xmm1
  1329.     psubw   xmm0, xmm7
  1330.     psubw   xmm1, xmm6
  1331.     ABS1    xmm0, xmm2
  1332.     ABS1    xmm1, xmm3
  1333.     movdqa  xmm2, xmm11
  1334.     movdqu  xmm3, [r1+r2+16]
  1335.     movdqa  xmm11, xmm3
  1336.     psubw   xmm2, xmm5
  1337.     psubw   xmm3, xmm4
  1338.     paddw   xmm0, xmm1
  1339.     movdqu  xmm9, [r3]
  1340.     ABS1    xmm2, xmm1
  1341.     ABS1    xmm3, xmm1
  1342.     paddw   xmm0, xmm2
  1343.     paddw   xmm0, xmm3
  1344.     paddusw xmm0, xmm9
  1345.     movdqa  xmm1, xmm8
  1346.     psubusw xmm1, xmm0
  1347.     packsswb xmm1, xmm1
  1348.     movq    [t0], xmm1
  1349. %else
  1350.     ADS_START 2
  1351. .loop:
  1352.     movdqu  xmm0, [r1]
  1353.     movdqu  xmm1, [r1+16]
  1354.     psubw   xmm0, xmm7
  1355.     psubw   xmm1, xmm6
  1356.     ABS1    xmm0, xmm2
  1357.     ABS1    xmm1, xmm3
  1358.     movdqu  xmm2, [r1+r2]
  1359.     movdqu  xmm3, [r1+r2+16]
  1360.     psubw   xmm2, xmm5
  1361.     psubw   xmm3, xmm4
  1362.     paddw   xmm0, xmm1
  1363.     ABS1    xmm2, xmm1
  1364.     ABS1    xmm3, xmm1
  1365.     paddw   xmm0, xmm2
  1366.     paddw   xmm0, xmm3
  1367.     movd    xmm1, [ebp+stack_offset+28]
  1368.     movdqu  xmm2, [r3]
  1369.     pshuflw xmm1, xmm1, 0
  1370.     punpcklqdq xmm1, xmm1
  1371.     paddusw xmm0, xmm2
  1372.     psubusw xmm1, xmm0
  1373.     packsswb xmm1, xmm1
  1374.     movq    [t0], xmm1
  1375. %endif ; ARCH
  1376.     ADS_END 2
  1377. cglobal x264_pixel_ads2_%1, 4,7
  1378.     movq    xmm6, [r0]
  1379.     movd    xmm5, r6m
  1380.     pshuflw xmm7, xmm6, 0
  1381.     pshuflw xmm6, xmm6, 0xAA
  1382.     pshuflw xmm5, xmm5, 0
  1383.     punpcklqdq xmm7, xmm7
  1384.     punpcklqdq xmm6, xmm6
  1385.     punpcklqdq xmm5, xmm5
  1386.     ADS_START 2
  1387. .loop:
  1388.     movdqu  xmm0, [r1]
  1389.     movdqu  xmm1, [r1+r2]
  1390.     psubw   xmm0, xmm7
  1391.     psubw   xmm1, xmm6
  1392.     movdqu  xmm4, [r3]
  1393.     ABS1    xmm0, xmm2
  1394.     ABS1    xmm1, xmm3
  1395.     paddw   xmm0, xmm1
  1396.     paddusw xmm0, xmm4
  1397.     movdqa  xmm1, xmm5
  1398.     psubusw xmm1, xmm0
  1399.     packsswb xmm1, xmm1
  1400.     movq    [t0], xmm1
  1401.     ADS_END 2
  1402. cglobal x264_pixel_ads1_%1, 4,7
  1403.     movd    xmm7, [r0]
  1404.     movd    xmm6, r6m
  1405.     pshuflw xmm7, xmm7, 0
  1406.     pshuflw xmm6, xmm6, 0
  1407.     punpcklqdq xmm7, xmm7
  1408.     punpcklqdq xmm6, xmm6
  1409.     ADS_START 4
  1410. .loop:
  1411.     movdqu  xmm0, [r1]
  1412.     movdqu  xmm1, [r1+16]
  1413.     psubw   xmm0, xmm7
  1414.     psubw   xmm1, xmm7
  1415.     movdqu  xmm2, [r3]
  1416.     movdqu  xmm3, [r3+16]
  1417.     ABS1    xmm0, xmm4
  1418.     ABS1    xmm1, xmm5
  1419.     paddusw xmm0, xmm2
  1420.     paddusw xmm1, xmm3
  1421.     movdqa  xmm4, xmm6
  1422.     movdqa  xmm5, xmm6
  1423.     psubusw xmm4, xmm0
  1424.     psubusw xmm5, xmm1
  1425.     packsswb xmm4, xmm5
  1426.     movdqa  [t0], xmm4
  1427.     ADS_END 4
  1428. %endmacro
  1429. ADS_SSE2 sse2
  1430. %define ABS1 ABS1_SSSE3
  1431. ADS_SSE2 ssse3
  1432. ; int x264_pixel_ads_mvs( int16_t *mvs, uint8_t *masks, int width )
  1433. ; {
  1434. ;     int nmv=0, i, j;
  1435. ;     *(uint32_t*)(masks+width) = 0;
  1436. ;     for( i=0; i<width; i+=8 )
  1437. ;     {
  1438. ;         uint64_t mask = *(uint64_t*)(masks+i);
  1439. ;         if( !mask ) continue;
  1440. ;         for( j=0; j<8; j++ )
  1441. ;             if( mask & (255<<j*8) )
  1442. ;                 mvs[nmv++] = i+j;
  1443. ;     }
  1444. ;     return nmv;
  1445. ; }
  1446. cglobal x264_pixel_ads_mvs
  1447. ads_mvs:
  1448.     xor     eax, eax
  1449.     xor     esi, esi
  1450. %ifdef ARCH_X86_64
  1451.     ; mvs = r4
  1452.     ; masks = rsp
  1453.     ; width = r5
  1454.     ; clear last block in case width isn't divisible by 8. (assume divisible by 4, so clearing 4 bytes is enough.)
  1455.     mov     dword [rsp+r5], 0
  1456.     jmp .loopi
  1457. .loopi0:
  1458.     add     esi, 8
  1459.     cmp     esi, r5d
  1460.     jge .end
  1461. .loopi:
  1462.     mov     rdi, [rsp+rsi]
  1463.     test    rdi, rdi
  1464.     jz .loopi0
  1465.     xor     ecx, ecx
  1466. %macro TEST 1
  1467.     mov     [r4+rax*2], si
  1468.     test    edi, 0xff<<(%1*8)
  1469.     setne   cl
  1470.     add     eax, ecx
  1471.     inc     esi
  1472. %endmacro
  1473.     TEST 0
  1474.     TEST 1
  1475.     TEST 2
  1476.     TEST 3
  1477.     shr     rdi, 32
  1478.     TEST 0
  1479.     TEST 1
  1480.     TEST 2
  1481.     TEST 3
  1482.     cmp     esi, r5d
  1483.     jl .loopi
  1484. .end:
  1485.     mov     rsp, r10
  1486.     ret
  1487. %else
  1488.     ; no PROLOGUE, inherit from x264_pixel_ads1
  1489.     mov     ebx, [ebp+stack_offset+20] ; mvs
  1490.     mov     edi, [ebp+stack_offset+24] ; width
  1491.     mov     dword [esp+edi], 0
  1492.     push    ebp
  1493.     jmp .loopi
  1494. .loopi0:
  1495.     add     esi, 8
  1496.     cmp     esi, edi
  1497.     jge .end
  1498. .loopi:
  1499.     mov     ebp, [esp+esi+4]
  1500.     mov     edx, [esp+esi+8]
  1501.     mov     ecx, ebp
  1502.     or      ecx, edx
  1503.     jz .loopi0
  1504.     xor     ecx, ecx
  1505. %macro TEST 2
  1506.     mov     [ebx+eax*2], si
  1507.     test    %2, 0xff<<(%1*8)
  1508.     setne   cl
  1509.     add     eax, ecx
  1510.     inc     esi
  1511. %endmacro
  1512.     TEST 0, ebp
  1513.     TEST 1, ebp
  1514.     TEST 2, ebp
  1515.     TEST 3, ebp
  1516.     TEST 0, edx
  1517.     TEST 1, edx
  1518.     TEST 2, edx
  1519.     TEST 3, edx
  1520.     cmp     esi, edi
  1521.     jl .loopi
  1522. .end:
  1523.     pop     esp
  1524.     RET
  1525. %endif ; ARCH