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

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. ;*****************************************************************************
  2. ;* sad-a.asm: h264 encoder library
  3. ;*****************************************************************************
  4. ;* Copyright (C) 2003-2008 x264 project
  5. ;*
  6. ;* Authors: Loren Merritt <lorenm@u.washington.edu>
  7. ;*          Jason Garrett-Glaser <darkshikari@gmail.com>
  8. ;*          Laurent Aimar <fenrir@via.ecp.fr>
  9. ;*          Alex Izvorski <aizvorksi@gmail.com>
  10. ;*
  11. ;* This program is free software; you can redistribute it and/or modify
  12. ;* it under the terms of the GNU General Public License as published by
  13. ;* the Free Software Foundation; either version 2 of the License, or
  14. ;* (at your option) any later version.
  15. ;*
  16. ;* This program is distributed in the hope that it will be useful,
  17. ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19. ;* GNU General Public License for more details.
  20. ;*
  21. ;* You should have received a copy of the GNU General Public License
  22. ;* along with this program; if not, write to the Free Software
  23. ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
  24. ;*****************************************************************************
  25. %include "x86inc.asm"
  26. %include "x86util.asm"
  27. SECTION_RODATA
  28. pb_3: times 16 db 3
  29. pb_shuf8x8c: db 0,0,0,0,2,2,2,2,4,4,4,4,6,6,6,6
  30. pw_8: times 4 dw 8
  31. sw_64: dd 64
  32. SECTION .text
  33. ;=============================================================================
  34. ; SAD MMX
  35. ;=============================================================================
  36. %macro SAD_INC_2x16P 0
  37.     movq    mm1,    [r0]
  38.     movq    mm2,    [r0+8]
  39.     movq    mm3,    [r0+r1]
  40.     movq    mm4,    [r0+r1+8]
  41.     psadbw  mm1,    [r2]
  42.     psadbw  mm2,    [r2+8]
  43.     psadbw  mm3,    [r2+r3]
  44.     psadbw  mm4,    [r2+r3+8]
  45.     lea     r0,     [r0+2*r1]
  46.     paddw   mm1,    mm2
  47.     paddw   mm3,    mm4
  48.     lea     r2,     [r2+2*r3]
  49.     paddw   mm0,    mm1
  50.     paddw   mm0,    mm3
  51. %endmacro
  52. %macro SAD_INC_2x8P 0
  53.     movq    mm1,    [r0]
  54.     movq    mm2,    [r0+r1]
  55.     psadbw  mm1,    [r2]
  56.     psadbw  mm2,    [r2+r3]
  57.     lea     r0,     [r0+2*r1]
  58.     paddw   mm0,    mm1
  59.     paddw   mm0,    mm2
  60.     lea     r2,     [r2+2*r3]
  61. %endmacro
  62. %macro SAD_INC_2x4P 0
  63.     movd    mm1,    [r0]
  64.     movd    mm2,    [r2]
  65.     punpckldq mm1,  [r0+r1]
  66.     punpckldq mm2,  [r2+r3]
  67.     psadbw  mm1,    mm2
  68.     paddw   mm0,    mm1
  69.     lea     r0,     [r0+2*r1]
  70.     lea     r2,     [r2+2*r3]
  71. %endmacro
  72. ;-----------------------------------------------------------------------------
  73. ; int x264_pixel_sad_16x16_mmxext (uint8_t *, int, uint8_t *, int )
  74. ;-----------------------------------------------------------------------------
  75. %macro SAD 2
  76. cglobal x264_pixel_sad_%1x%2_mmxext, 4,4
  77.     pxor    mm0, mm0
  78. %rep %2/2
  79.     SAD_INC_2x%1P
  80. %endrep
  81.     movd    eax, mm0
  82.     RET
  83. %endmacro
  84. SAD 16, 16
  85. SAD 16,  8
  86. SAD  8, 16
  87. SAD  8,  8
  88. SAD  8,  4
  89. SAD  4,  8
  90. SAD  4,  4
  91. ;=============================================================================
  92. ; SAD XMM
  93. ;=============================================================================
  94. %macro SAD_END_SSE2 0
  95.     movhlps m1, m0
  96.     paddw   m0, m1
  97.     movd   eax, m0
  98.     RET
  99. %endmacro
  100. %macro SAD_W16 1
  101. ;-----------------------------------------------------------------------------
  102. ; int x264_pixel_sad_16x16_sse2 (uint8_t *, int, uint8_t *, int )
  103. ;-----------------------------------------------------------------------------
  104. cglobal x264_pixel_sad_16x16_%1, 4,4,8
  105.     movdqu  m0, [r2]
  106.     movdqu  m1, [r2+r3]
  107.     lea     r2, [r2+2*r3]
  108.     movdqu  m2, [r2]
  109.     movdqu  m3, [r2+r3]
  110.     lea     r2, [r2+2*r3]
  111.     psadbw  m0, [r0]
  112.     psadbw  m1, [r0+r1]
  113.     lea     r0, [r0+2*r1]
  114.     movdqu  m4, [r2]
  115.     paddw   m0, m1
  116.     psadbw  m2, [r0]
  117.     psadbw  m3, [r0+r1]
  118.     lea     r0, [r0+2*r1]
  119.     movdqu  m5, [r2+r3]
  120.     lea     r2, [r2+2*r3]
  121.     paddw   m2, m3
  122.     movdqu  m6, [r2]
  123.     movdqu  m7, [r2+r3]
  124.     lea     r2, [r2+2*r3]
  125.     paddw   m0, m2
  126.     psadbw  m4, [r0]
  127.     psadbw  m5, [r0+r1]
  128.     lea     r0, [r0+2*r1]
  129.     movdqu  m1, [r2]
  130.     paddw   m4, m5
  131.     psadbw  m6, [r0]
  132.     psadbw  m7, [r0+r1]
  133.     lea     r0, [r0+2*r1]
  134.     movdqu  m2, [r2+r3]
  135.     lea     r2, [r2+2*r3]
  136.     paddw   m6, m7
  137.     movdqu  m3, [r2]
  138.     paddw   m0, m4
  139.     movdqu  m4, [r2+r3]
  140.     lea     r2, [r2+2*r3]
  141.     paddw   m0, m6
  142.     psadbw  m1, [r0]
  143.     psadbw  m2, [r0+r1]
  144.     lea     r0, [r0+2*r1]
  145.     movdqu  m5, [r2]
  146.     paddw   m1, m2
  147.     psadbw  m3, [r0]
  148.     psadbw  m4, [r0+r1]
  149.     lea     r0, [r0+2*r1]
  150.     movdqu  m6, [r2+r3]
  151.     lea     r2, [r2+2*r3]
  152.     paddw   m3, m4
  153.     movdqu  m7, [r2]
  154.     paddw   m0, m1
  155.     movdqu  m1, [r2+r3]
  156.     paddw   m0, m3
  157.     psadbw  m5, [r0]
  158.     psadbw  m6, [r0+r1]
  159.     lea     r0, [r0+2*r1]
  160.     paddw   m5, m6
  161.     psadbw  m7, [r0]
  162.     psadbw  m1, [r0+r1]
  163.     paddw   m7, m1
  164.     paddw   m0, m5
  165.     paddw   m0, m7
  166.     SAD_END_SSE2
  167. ;-----------------------------------------------------------------------------
  168. ; int x264_pixel_sad_16x8_sse2 (uint8_t *, int, uint8_t *, int )
  169. ;-----------------------------------------------------------------------------
  170. cglobal x264_pixel_sad_16x8_%1, 4,4
  171.     movdqu  m0, [r2]
  172.     movdqu  m2, [r2+r3]
  173.     lea     r2, [r2+2*r3]
  174.     movdqu  m3, [r2]
  175.     movdqu  m4, [r2+r3]
  176.     psadbw  m0, [r0]
  177.     psadbw  m2, [r0+r1]
  178.     lea     r0, [r0+2*r1]
  179.     psadbw  m3, [r0]
  180.     psadbw  m4, [r0+r1]
  181.     lea     r0, [r0+2*r1]
  182.     lea     r2, [r2+2*r3]
  183.     paddw   m0, m2
  184.     paddw   m3, m4
  185.     paddw   m0, m3
  186.     movdqu  m1, [r2]
  187.     movdqu  m2, [r2+r3]
  188.     lea     r2, [r2+2*r3]
  189.     movdqu  m3, [r2]
  190.     movdqu  m4, [r2+r3]
  191.     psadbw  m1, [r0]
  192.     psadbw  m2, [r0+r1]
  193.     lea     r0, [r0+2*r1]
  194.     psadbw  m3, [r0]
  195.     psadbw  m4, [r0+r1]
  196.     lea     r0, [r0+2*r1]
  197.     lea     r2, [r2+2*r3]
  198.     paddw   m1, m2
  199.     paddw   m3, m4
  200.     paddw   m0, m1
  201.     paddw   m0, m3
  202.     SAD_END_SSE2
  203. %endmacro
  204. INIT_XMM
  205. SAD_W16 sse2
  206. %define movdqu lddqu
  207. SAD_W16 sse3
  208. %define movdqu movdqa
  209. SAD_W16 sse2_aligned
  210. %undef movdqu
  211. %macro SAD_INC_4x8P_SSE 1
  212.     movq    m1, [r0]
  213.     movq    m2, [r0+r1]
  214.     lea     r0, [r0+2*r1]
  215.     movq    m3, [r2]
  216.     movq    m4, [r2+r3]
  217.     lea     r2, [r2+2*r3]
  218.     movhps  m1, [r0]
  219.     movhps  m2, [r0+r1]
  220.     movhps  m3, [r2]
  221.     movhps  m4, [r2+r3]
  222.     lea     r0, [r0+2*r1]
  223.     psadbw  m1, m3
  224.     psadbw  m2, m4
  225.     lea     r2, [r2+2*r3]
  226. %if %1
  227.     paddw   m0, m1
  228. %else
  229.     SWAP    m0, m1
  230. %endif
  231.     paddw   m0, m2
  232. %endmacro
  233. ;Even on Nehalem, no sizes other than 8x16 benefit from this method.
  234. cglobal x264_pixel_sad_8x16_sse2, 4,4
  235.     SAD_INC_4x8P_SSE 0
  236.     SAD_INC_4x8P_SSE 1
  237.     SAD_INC_4x8P_SSE 1
  238.     SAD_INC_4x8P_SSE 1
  239.     SAD_END_SSE2
  240.     RET
  241. ;-----------------------------------------------------------------------------
  242. ; void intra_sad_x3_4x4 ( uint8_t *fenc, uint8_t *fdec, int res[3] );
  243. ;-----------------------------------------------------------------------------
  244. cglobal x264_intra_sad_x3_4x4_mmxext, 3,3
  245.     pxor      mm7, mm7
  246.     movd      mm0, [r1-FDEC_STRIDE]
  247.     movd      mm1, [r0+FENC_STRIDE*0]
  248.     movd      mm2, [r0+FENC_STRIDE*2]
  249.     punpckldq mm0, mm0
  250.     punpckldq mm1, [r0+FENC_STRIDE*1]
  251.     punpckldq mm2, [r0+FENC_STRIDE*3]
  252.     movq      mm6, mm0
  253.     movq      mm3, mm1
  254.     psadbw    mm3, mm0
  255.     psadbw    mm0, mm2
  256.     paddw     mm0, mm3
  257.     movd     [r2], mm0 ;V prediction cost
  258.     movd      mm3, [r1+FDEC_STRIDE*0-4]
  259.     movd      mm0, [r1+FDEC_STRIDE*1-4]
  260.     movd      mm4, [r1+FDEC_STRIDE*2-4]
  261.     movd      mm5, [r1+FDEC_STRIDE*3-4]
  262.     punpcklbw mm3, mm0
  263.     punpcklbw mm4, mm5
  264.     movq      mm5, mm3
  265.     punpckhwd mm5, mm4
  266.     punpckhdq mm5, mm6
  267.     psadbw    mm5, mm7
  268.     punpckhbw mm3, mm3
  269.     punpckhbw mm4, mm4
  270.     punpckhwd mm3, mm3
  271.     punpckhwd mm4, mm4
  272.     psraw     mm5, 2
  273.     pavgw     mm5, mm7
  274.     punpcklbw mm5, mm5
  275.     pshufw    mm5, mm5, 0x0 ;DC prediction
  276.     movq      mm6, mm5
  277.     psadbw    mm5, mm1
  278.     psadbw    mm6, mm2
  279.     psadbw    mm1, mm3
  280.     psadbw    mm2, mm4
  281.     paddw     mm5, mm6
  282.     paddw     mm1, mm2
  283.     movd   [r2+8], mm5 ;DC prediction cost
  284.     movd   [r2+4], mm1 ;H prediction cost
  285.     RET
  286. ;-----------------------------------------------------------------------------
  287. ; void intra_sad_x3_8x8 ( uint8_t *fenc, uint8_t edge[33], int res[3]);
  288. ;-----------------------------------------------------------------------------
  289. ;m0 = DC
  290. ;m6 = V
  291. ;m7 = H
  292. ;m1 = DC score
  293. ;m2 = V score
  294. ;m3 = H score
  295. ;m5 = pixel row
  296. ;m4 = temp
  297. %macro INTRA_SAD_HVDC_ITER 2
  298.     movq      m5, [r0+FENC_STRIDE*%1]
  299.     movq      m4, m5
  300.     psadbw    m4, m0
  301. %if %1
  302.     paddw     m1, m4
  303. %else
  304.     SWAP      m1, m4
  305. %endif
  306.     movq      m4, m5
  307.     psadbw    m4, m6
  308. %if %1
  309.     paddw     m2, m4
  310. %else
  311.     SWAP      m2, m4
  312. %endif
  313.     pshufw    m4, m7, %2
  314.     psadbw    m5, m4
  315. %if %1
  316.     paddw     m3, m5
  317. %else
  318.     SWAP      m3, m5
  319. %endif
  320. %endmacro
  321. INIT_MMX
  322. cglobal x264_intra_sad_x3_8x8_mmxext, 3,3
  323.     movq      m7, [r1+7]
  324.     pxor      m0, m0
  325.     movq      m6, [r1+16]  ;V prediction
  326.     pxor      m1, m1
  327.     psadbw    m0, m7
  328.     psadbw    m1, m6
  329.     paddw     m0, m1
  330.     paddw     m0, [pw_8 GLOBAL]
  331.     psrlw     m0, 4
  332.     punpcklbw m0, m0
  333.     pshufw    m0, m0, 0x0 ;DC prediction
  334.     punpckhbw m7, m7
  335.     INTRA_SAD_HVDC_ITER 0, 0xff
  336.     INTRA_SAD_HVDC_ITER 1, 0xaa
  337.     INTRA_SAD_HVDC_ITER 2, 0x55
  338.     INTRA_SAD_HVDC_ITER 3, 0x00
  339.     movq      m7, [r1+7]
  340.     punpcklbw m7, m7
  341.     INTRA_SAD_HVDC_ITER 4, 0xff
  342.     INTRA_SAD_HVDC_ITER 5, 0xaa
  343.     INTRA_SAD_HVDC_ITER 6, 0x55
  344.     INTRA_SAD_HVDC_ITER 7, 0x00
  345.     movd  [r2+0], m2
  346.     movd  [r2+4], m3
  347.     movd  [r2+8], m1
  348.     RET
  349. ;-----------------------------------------------------------------------------
  350. ; void intra_sad_x3_8x8c ( uint8_t *fenc, uint8_t *fdec, int res[3] );
  351. ;-----------------------------------------------------------------------------
  352. %macro INTRA_SAD_HV_ITER 2
  353. %ifidn %2, ssse3
  354.     movd        m1, [r1 + FDEC_STRIDE*(%1-4) - 4]
  355.     movd        m3, [r1 + FDEC_STRIDE*(%1-3) - 4]
  356.     pshufb      m1, m7
  357.     pshufb      m3, m7
  358. %else
  359.     movq        m1, [r1 + FDEC_STRIDE*(%1-4) - 8]
  360.     movq        m3, [r1 + FDEC_STRIDE*(%1-3) - 8]
  361.     punpckhbw   m1, m1
  362.     punpckhbw   m3, m3
  363.     pshufw      m1, m1, 0xff
  364.     pshufw      m3, m3, 0xff
  365. %endif
  366.     movq        m4, [r0 + FENC_STRIDE*(%1+0)]
  367.     movq        m5, [r0 + FENC_STRIDE*(%1+1)]
  368.     psadbw      m1, m4
  369.     psadbw      m3, m5
  370.     psadbw      m4, m6
  371.     psadbw      m5, m6
  372.     paddw       m1, m3
  373.     paddw       m4, m5
  374. %if %1
  375.     paddw       m0, m1
  376.     paddw       m2, m4
  377. %else
  378.     SWAP 0,1
  379.     SWAP 2,4
  380. %endif
  381. %endmacro
  382. %macro INTRA_SAD_8x8C 1
  383. cglobal x264_intra_sad_x3_8x8c_%1, 3,3
  384.     movq        m6, [r1 - FDEC_STRIDE]
  385.     add         r1, FDEC_STRIDE*4
  386. %ifidn %1,ssse3
  387.     movq        m7, [pb_3 GLOBAL]
  388. %endif
  389.     INTRA_SAD_HV_ITER 0, %1
  390.     INTRA_SAD_HV_ITER 2, %1
  391.     INTRA_SAD_HV_ITER 4, %1
  392.     INTRA_SAD_HV_ITER 6, %1
  393.     movd    [r2+4], m0
  394.     movd    [r2+8], m2
  395.     pxor        m7, m7
  396.     movq        m2, [r1 + FDEC_STRIDE*-4 - 8]
  397.     movq        m4, [r1 + FDEC_STRIDE*-2 - 8]
  398.     movq        m3, [r1 + FDEC_STRIDE* 0 - 8]
  399.     movq        m5, [r1 + FDEC_STRIDE* 2 - 8]
  400.     punpckhbw   m2, [r1 + FDEC_STRIDE*-3 - 8]
  401.     punpckhbw   m4, [r1 + FDEC_STRIDE*-1 - 8]
  402.     punpckhbw   m3, [r1 + FDEC_STRIDE* 1 - 8]
  403.     punpckhbw   m5, [r1 + FDEC_STRIDE* 3 - 8]
  404.     punpckhbw   m2, m4
  405.     punpckhbw   m3, m5
  406.     psrlq       m2, 32
  407.     psrlq       m3, 32
  408.     psadbw      m2, m7 ; s2
  409.     psadbw      m3, m7 ; s3
  410.     movq        m1, m6
  411.     SWAP        0, 6
  412.     punpckldq   m0, m7
  413.     punpckhdq   m1, m7
  414.     psadbw      m0, m7 ; s0
  415.     psadbw      m1, m7 ; s1
  416.     punpcklwd   m0, m1
  417.     punpcklwd   m2, m3
  418.     punpckldq   m0, m2 ;s0 s1 s2 s3
  419.     pshufw      m3, m0, 11110110b ;s2,s1,s3,s3
  420.     pshufw      m0, m0, 01110100b ;s0,s1,s3,s1
  421.     paddw       m0, m3
  422.     psrlw       m0, 2
  423.     pavgw       m0, m7 ; s0+s2, s1, s3, s1+s3
  424. %ifidn %1, ssse3
  425.     movq2dq   xmm0, m0
  426.     pshufb    xmm0, [pb_shuf8x8c GLOBAL]
  427.     movq      xmm1, [r0+FENC_STRIDE*0]
  428.     movq      xmm2, [r0+FENC_STRIDE*1]
  429.     movq      xmm3, [r0+FENC_STRIDE*2]
  430.     movq      xmm4, [r0+FENC_STRIDE*3]
  431.     movhps    xmm1, [r0+FENC_STRIDE*4]
  432.     movhps    xmm2, [r0+FENC_STRIDE*5]
  433.     movhps    xmm3, [r0+FENC_STRIDE*6]
  434.     movhps    xmm4, [r0+FENC_STRIDE*7]
  435.     psadbw    xmm1, xmm0
  436.     psadbw    xmm2, xmm0
  437.     psadbw    xmm3, xmm0
  438.     psadbw    xmm4, xmm0
  439.     paddw     xmm1, xmm2
  440.     paddw     xmm1, xmm3
  441.     paddw     xmm1, xmm4
  442.     movhlps   xmm0, xmm1
  443.     paddw     xmm1, xmm0
  444.     movd      [r2], xmm1
  445. %else
  446.     packuswb    m0, m0
  447.     punpcklbw   m0, m0
  448.     movq        m1, m0
  449.     punpcklbw   m0, m0 ; 4x dc0 4x dc1
  450.     punpckhbw   m1, m1 ; 4x dc2 4x dc3
  451.     movq        m2, [r0+FENC_STRIDE*0]
  452.     movq        m3, [r0+FENC_STRIDE*1]
  453.     movq        m4, [r0+FENC_STRIDE*2]
  454.     movq        m5, [r0+FENC_STRIDE*3]
  455.     movq        m6, [r0+FENC_STRIDE*4]
  456.     movq        m7, [r0+FENC_STRIDE*5]
  457.     psadbw      m2, m0
  458.     psadbw      m3, m0
  459.     psadbw      m4, m0
  460.     psadbw      m5, m0
  461.     movq        m0, [r0+FENC_STRIDE*6]
  462.     psadbw      m6, m1
  463.     psadbw      m7, m1
  464.     psadbw      m0, m1
  465.     psadbw      m1, [r0+FENC_STRIDE*7]
  466.     paddw       m2, m3
  467.     paddw       m4, m5
  468.     paddw       m6, m7
  469.     paddw       m0, m1
  470.     paddw       m2, m4
  471.     paddw       m6, m0
  472.     paddw       m2, m6
  473.     movd      [r2], m2
  474. %endif
  475.     RET
  476. %endmacro
  477. INIT_MMX
  478. INTRA_SAD_8x8C mmxext
  479. INTRA_SAD_8x8C ssse3
  480. ;-----------------------------------------------------------------------------
  481. ; void intra_sad_x3_16x16 ( uint8_t *fenc, uint8_t *fdec, int res[3] );
  482. ;-----------------------------------------------------------------------------
  483. ;xmm7: DC prediction    xmm6: H prediction  xmm5: V prediction
  484. ;xmm4: DC pred score    xmm3: H pred score  xmm2: V pred score
  485. %macro INTRA_SAD16 1-2 0
  486. cglobal x264_intra_sad_x3_16x16_%1,3,5,%2
  487.     pxor    mm0, mm0
  488.     pxor    mm1, mm1
  489.     psadbw  mm0, [r1-FDEC_STRIDE+0]
  490.     psadbw  mm1, [r1-FDEC_STRIDE+8]
  491.     paddw   mm0, mm1
  492.     movd    r3d, mm0
  493. %ifidn %1, ssse3
  494.     mova  m1, [pb_3 GLOBAL]
  495. %endif
  496. %assign x 0
  497. %rep 16
  498.     movzx   r4d, byte [r1-1+FDEC_STRIDE*x]
  499.     add     r3d, r4d
  500. %assign x x+1
  501. %endrep
  502.     add     r3d, 16
  503.     shr     r3d, 5
  504.     imul    r3d, 0x01010101
  505.     movd    m7, r3d
  506.     mova    m5, [r1-FDEC_STRIDE]
  507. %if mmsize==16
  508.     pshufd  m7, m7, 0
  509. %else
  510.     mova    m1, [r1-FDEC_STRIDE+8]
  511.     punpckldq m7, m7
  512. %endif
  513.     pxor    m4, m4
  514.     pxor    m3, m3
  515.     pxor    m2, m2
  516.     mov     r3d, 15*FENC_STRIDE
  517. .vloop:
  518.     SPLATB  m6, r1+r3*2-1, m1
  519.     mova    m0, [r0+r3]
  520.     psadbw  m0, m7
  521.     paddw   m4, m0
  522.     mova    m0, [r0+r3]
  523.     psadbw  m0, m5
  524.     paddw   m2, m0
  525. %if mmsize==8
  526.     mova    m0, [r0+r3]
  527.     psadbw  m0, m6
  528.     paddw   m3, m0
  529.     mova    m0, [r0+r3+8]
  530.     psadbw  m0, m7
  531.     paddw   m4, m0
  532.     mova    m0, [r0+r3+8]
  533.     psadbw  m0, m1
  534.     paddw   m2, m0
  535.     psadbw  m6, [r0+r3+8]
  536.     paddw   m3, m6
  537. %else
  538.     psadbw  m6, [r0+r3]
  539.     paddw   m3, m6
  540. %endif
  541.     add     r3d, -FENC_STRIDE
  542.     jge .vloop
  543. %if mmsize==16
  544.     pslldq  m3, 4
  545.     por     m3, m2
  546.     movhlps m1, m3
  547.     paddw   m3, m1
  548.     movq  [r2+0], m3
  549.     movhlps m1, m4
  550.     paddw   m4, m1
  551. %else
  552.     movd  [r2+0], m2
  553.     movd  [r2+4], m3
  554. %endif
  555.     movd  [r2+8], m4
  556.     RET
  557. %endmacro
  558. INIT_MMX
  559. %define SPLATB SPLATB_MMX
  560. INTRA_SAD16 mmxext
  561. INIT_XMM
  562. INTRA_SAD16 sse2, 8
  563. %define SPLATB SPLATB_SSSE3
  564. INTRA_SAD16 ssse3, 8
  565. ;=============================================================================
  566. ; SAD x3/x4 MMX
  567. ;=============================================================================
  568. %macro SAD_X3_START_1x8P 0
  569.     movq    mm3,    [r0]
  570.     movq    mm0,    [r1]
  571.     movq    mm1,    [r2]
  572.     movq    mm2,    [r3]
  573.     psadbw  mm0,    mm3
  574.     psadbw  mm1,    mm3
  575.     psadbw  mm2,    mm3
  576. %endmacro
  577. %macro SAD_X3_1x8P 2
  578.     movq    mm3,    [r0+%1]
  579.     movq    mm4,    [r1+%2]
  580.     movq    mm5,    [r2+%2]
  581.     movq    mm6,    [r3+%2]
  582.     psadbw  mm4,    mm3
  583.     psadbw  mm5,    mm3
  584.     psadbw  mm6,    mm3
  585.     paddw   mm0,    mm4
  586.     paddw   mm1,    mm5
  587.     paddw   mm2,    mm6
  588. %endmacro
  589. %macro SAD_X3_START_2x4P 3
  590.     movd      mm3,  [r0]
  591.     movd      %1,   [r1]
  592.     movd      %2,   [r2]
  593.     movd      %3,   [r3]
  594.     punpckldq mm3,  [r0+FENC_STRIDE]
  595.     punpckldq %1,   [r1+r4]
  596.     punpckldq %2,   [r2+r4]
  597.     punpckldq %3,   [r3+r4]
  598.     psadbw    %1,   mm3
  599.     psadbw    %2,   mm3
  600.     psadbw    %3,   mm3
  601. %endmacro
  602. %macro SAD_X3_2x16P 1
  603. %if %1
  604.     SAD_X3_START_1x8P
  605. %else
  606.     SAD_X3_1x8P 0, 0
  607. %endif
  608.     SAD_X3_1x8P 8, 8
  609.     SAD_X3_1x8P FENC_STRIDE, r4
  610.     SAD_X3_1x8P FENC_STRIDE+8, r4+8
  611.     add     r0, 2*FENC_STRIDE
  612.     lea     r1, [r1+2*r4]
  613.     lea     r2, [r2+2*r4]
  614.     lea     r3, [r3+2*r4]
  615. %endmacro
  616. %macro SAD_X3_2x8P 1
  617. %if %1
  618.     SAD_X3_START_1x8P
  619. %else
  620.     SAD_X3_1x8P 0, 0
  621. %endif
  622.     SAD_X3_1x8P FENC_STRIDE, r4
  623.     add     r0, 2*FENC_STRIDE
  624.     lea     r1, [r1+2*r4]
  625.     lea     r2, [r2+2*r4]
  626.     lea     r3, [r3+2*r4]
  627. %endmacro
  628. %macro SAD_X3_2x4P 1
  629. %if %1
  630.     SAD_X3_START_2x4P mm0, mm1, mm2
  631. %else
  632.     SAD_X3_START_2x4P mm4, mm5, mm6
  633.     paddw     mm0,  mm4
  634.     paddw     mm1,  mm5
  635.     paddw     mm2,  mm6
  636. %endif
  637.     add     r0, 2*FENC_STRIDE
  638.     lea     r1, [r1+2*r4]
  639.     lea     r2, [r2+2*r4]
  640.     lea     r3, [r3+2*r4]
  641. %endmacro
  642. %macro SAD_X4_START_1x8P 0
  643.     movq    mm7,    [r0]
  644.     movq    mm0,    [r1]
  645.     movq    mm1,    [r2]
  646.     movq    mm2,    [r3]
  647.     movq    mm3,    [r4]
  648.     psadbw  mm0,    mm7
  649.     psadbw  mm1,    mm7
  650.     psadbw  mm2,    mm7
  651.     psadbw  mm3,    mm7
  652. %endmacro
  653. %macro SAD_X4_1x8P 2
  654.     movq    mm7,    [r0+%1]
  655.     movq    mm4,    [r1+%2]
  656.     movq    mm5,    [r2+%2]
  657.     movq    mm6,    [r3+%2]
  658.     psadbw  mm4,    mm7
  659.     psadbw  mm5,    mm7
  660.     psadbw  mm6,    mm7
  661.     psadbw  mm7,    [r4+%2]
  662.     paddw   mm0,    mm4
  663.     paddw   mm1,    mm5
  664.     paddw   mm2,    mm6
  665.     paddw   mm3,    mm7
  666. %endmacro
  667. %macro SAD_X4_START_2x4P 0
  668.     movd      mm7,  [r0]
  669.     movd      mm0,  [r1]
  670.     movd      mm1,  [r2]
  671.     movd      mm2,  [r3]
  672.     movd      mm3,  [r4]
  673.     punpckldq mm7,  [r0+FENC_STRIDE]
  674.     punpckldq mm0,  [r1+r5]
  675.     punpckldq mm1,  [r2+r5]
  676.     punpckldq mm2,  [r3+r5]
  677.     punpckldq mm3,  [r4+r5]
  678.     psadbw    mm0,  mm7
  679.     psadbw    mm1,  mm7
  680.     psadbw    mm2,  mm7
  681.     psadbw    mm3,  mm7
  682. %endmacro
  683. %macro SAD_X4_INC_2x4P 0
  684.     movd      mm7,  [r0]
  685.     movd      mm4,  [r1]
  686.     movd      mm5,  [r2]
  687.     punpckldq mm7,  [r0+FENC_STRIDE]
  688.     punpckldq mm4,  [r1+r5]
  689.     punpckldq mm5,  [r2+r5]
  690.     psadbw    mm4,  mm7
  691.     psadbw    mm5,  mm7
  692.     paddw     mm0,  mm4
  693.     paddw     mm1,  mm5
  694.     movd      mm4,  [r3]
  695.     movd      mm5,  [r4]
  696.     punpckldq mm4,  [r3+r5]
  697.     punpckldq mm5,  [r4+r5]
  698.     psadbw    mm4,  mm7
  699.     psadbw    mm5,  mm7
  700.     paddw     mm2,  mm4
  701.     paddw     mm3,  mm5
  702. %endmacro
  703. %macro SAD_X4_2x16P 1
  704. %if %1
  705.     SAD_X4_START_1x8P
  706. %else
  707.     SAD_X4_1x8P 0, 0
  708. %endif
  709.     SAD_X4_1x8P 8, 8
  710.     SAD_X4_1x8P FENC_STRIDE, r5
  711.     SAD_X4_1x8P FENC_STRIDE+8, r5+8
  712.     add     r0, 2*FENC_STRIDE
  713.     lea     r1, [r1+2*r5]
  714.     lea     r2, [r2+2*r5]
  715.     lea     r3, [r3+2*r5]
  716.     lea     r4, [r4+2*r5]
  717. %endmacro
  718. %macro SAD_X4_2x8P 1
  719. %if %1
  720.     SAD_X4_START_1x8P
  721. %else
  722.     SAD_X4_1x8P 0, 0
  723. %endif
  724.     SAD_X4_1x8P FENC_STRIDE, r5
  725.     add     r0, 2*FENC_STRIDE
  726.     lea     r1, [r1+2*r5]
  727.     lea     r2, [r2+2*r5]
  728.     lea     r3, [r3+2*r5]
  729.     lea     r4, [r4+2*r5]
  730. %endmacro
  731. %macro SAD_X4_2x4P 1
  732. %if %1
  733.     SAD_X4_START_2x4P
  734. %else
  735.     SAD_X4_INC_2x4P
  736. %endif
  737.     add     r0, 2*FENC_STRIDE
  738.     lea     r1, [r1+2*r5]
  739.     lea     r2, [r2+2*r5]
  740.     lea     r3, [r3+2*r5]
  741.     lea     r4, [r4+2*r5]
  742. %endmacro
  743. %macro SAD_X3_END 0
  744. %ifdef UNIX64
  745.     movd    [r5+0], mm0
  746.     movd    [r5+4], mm1
  747.     movd    [r5+8], mm2
  748. %else
  749.     mov     r0, r5mp
  750.     movd    [r0+0], mm0
  751.     movd    [r0+4], mm1
  752.     movd    [r0+8], mm2
  753. %endif
  754.     RET
  755. %endmacro
  756. %macro SAD_X4_END 0
  757.     mov     r0, r6mp
  758.     movd    [r0+0], mm0
  759.     movd    [r0+4], mm1
  760.     movd    [r0+8], mm2
  761.     movd    [r0+12], mm3
  762.     RET
  763. %endmacro
  764. ;-----------------------------------------------------------------------------
  765. ; void x264_pixel_sad_x3_16x16_mmxext( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1,
  766. ;                                      uint8_t *pix2, int i_stride, int scores[3] )
  767. ;-----------------------------------------------------------------------------
  768. %macro SAD_X 3
  769. cglobal x264_pixel_sad_x%1_%2x%3_mmxext, %1+2, %1+2
  770. %ifdef WIN64
  771.     %assign i %1+1
  772.     movsxd r %+ i, r %+ i %+ d
  773. %endif
  774.     SAD_X%1_2x%2P 1
  775. %rep %3/2-1
  776.     SAD_X%1_2x%2P 0
  777. %endrep
  778.     SAD_X%1_END
  779. %endmacro
  780. SAD_X 3, 16, 16
  781. SAD_X 3, 16,  8
  782. SAD_X 3,  8, 16
  783. SAD_X 3,  8,  8
  784. SAD_X 3,  8,  4
  785. SAD_X 3,  4,  8
  786. SAD_X 3,  4,  4
  787. SAD_X 4, 16, 16
  788. SAD_X 4, 16,  8
  789. SAD_X 4,  8, 16
  790. SAD_X 4,  8,  8
  791. SAD_X 4,  8,  4
  792. SAD_X 4,  4,  8
  793. SAD_X 4,  4,  4
  794. ;=============================================================================
  795. ; SAD x3/x4 XMM
  796. ;=============================================================================
  797. %macro SAD_X3_START_1x16P_SSE2 0
  798.     movdqa xmm3, [r0]
  799.     movdqu xmm0, [r1]
  800.     movdqu xmm1, [r2]
  801.     movdqu xmm2, [r3]
  802.     psadbw xmm0, xmm3
  803.     psadbw xmm1, xmm3
  804.     psadbw xmm2, xmm3
  805. %endmacro
  806. %macro SAD_X3_1x16P_SSE2 2
  807.     movdqa xmm3, [r0+%1]
  808.     movdqu xmm4, [r1+%2]
  809.     movdqu xmm5, [r2+%2]
  810.     movdqu xmm6, [r3+%2]
  811.     psadbw xmm4, xmm3
  812.     psadbw xmm5, xmm3
  813.     psadbw xmm6, xmm3
  814.     paddw  xmm0, xmm4
  815.     paddw  xmm1, xmm5
  816.     paddw  xmm2, xmm6
  817. %endmacro
  818. %macro SAD_X3_2x16P_SSE2 1
  819. %if %1
  820.     SAD_X3_START_1x16P_SSE2
  821. %else
  822.     SAD_X3_1x16P_SSE2 0, 0
  823. %endif
  824.     SAD_X3_1x16P_SSE2 FENC_STRIDE, r4
  825.     add  r0, 2*FENC_STRIDE
  826.     lea  r1, [r1+2*r4]
  827.     lea  r2, [r2+2*r4]
  828.     lea  r3, [r3+2*r4]
  829. %endmacro
  830. %macro SAD_X3_START_2x8P_SSE2 0
  831.     movq    xmm7, [r0]
  832.     movq    xmm0, [r1]
  833.     movq    xmm1, [r2]
  834.     movq    xmm2, [r3]
  835.     movhps  xmm7, [r0+FENC_STRIDE]
  836.     movhps  xmm0, [r1+r4]
  837.     movhps  xmm1, [r2+r4]
  838.     movhps  xmm2, [r3+r4]
  839.     psadbw  xmm0, xmm7
  840.     psadbw  xmm1, xmm7
  841.     psadbw  xmm2, xmm7
  842. %endmacro
  843. %macro SAD_X3_2x8P_SSE2 0
  844.     movq    xmm7, [r0]
  845.     movq    xmm3, [r1]
  846.     movq    xmm4, [r2]
  847.     movq    xmm5, [r3]
  848.     movhps  xmm7, [r0+FENC_STRIDE]
  849.     movhps  xmm3, [r1+r4]
  850.     movhps  xmm4, [r2+r4]
  851.     movhps  xmm5, [r3+r4]
  852.     psadbw  xmm3, xmm7
  853.     psadbw  xmm4, xmm7
  854.     psadbw  xmm5, xmm7
  855.     paddw   xmm0, xmm3
  856.     paddw   xmm1, xmm4
  857.     paddw   xmm2, xmm5
  858. %endmacro
  859. %macro SAD_X4_START_2x8P_SSE2 0
  860.     movq    xmm7, [r0]
  861.     movq    xmm0, [r1]
  862.     movq    xmm1, [r2]
  863.     movq    xmm2, [r3]
  864.     movq    xmm3, [r4]
  865.     movhps  xmm7, [r0+FENC_STRIDE]
  866.     movhps  xmm0, [r1+r5]
  867.     movhps  xmm1, [r2+r5]
  868.     movhps  xmm2, [r3+r5]
  869.     movhps  xmm3, [r4+r5]
  870.     psadbw  xmm0, xmm7
  871.     psadbw  xmm1, xmm7
  872.     psadbw  xmm2, xmm7
  873.     psadbw  xmm3, xmm7
  874. %endmacro
  875. %macro SAD_X4_2x8P_SSE2 0
  876.     movq    xmm7, [r0]
  877.     movq    xmm4, [r1]
  878.     movq    xmm5, [r2]
  879. %ifdef ARCH_X86_64
  880.     movq    xmm6, [r3]
  881.     movq    xmm8, [r4]
  882.     movhps  xmm7, [r0+FENC_STRIDE]
  883.     movhps  xmm4, [r1+r5]
  884.     movhps  xmm5, [r2+r5]
  885.     movhps  xmm6, [r3+r5]
  886.     movhps  xmm8, [r4+r5]
  887.     psadbw  xmm4, xmm7
  888.     psadbw  xmm5, xmm7
  889.     psadbw  xmm6, xmm7
  890.     psadbw  xmm8, xmm7
  891.     paddw   xmm0, xmm4
  892.     paddw   xmm1, xmm5
  893.     paddw   xmm2, xmm6
  894.     paddw   xmm3, xmm8
  895. %else
  896.     movhps  xmm7, [r0+FENC_STRIDE]
  897.     movhps  xmm4, [r1+r5]
  898.     movhps  xmm5, [r2+r5]
  899.     psadbw  xmm4, xmm7
  900.     psadbw  xmm5, xmm7
  901.     paddw   xmm0, xmm4
  902.     paddw   xmm1, xmm5
  903.     movq    xmm6, [r3]
  904.     movq    xmm4, [r4]
  905.     movhps  xmm6, [r3+r5]
  906.     movhps  xmm4, [r4+r5]
  907.     psadbw  xmm6, xmm7
  908.     psadbw  xmm4, xmm7
  909.     paddw   xmm2, xmm6
  910.     paddw   xmm3, xmm4
  911. %endif
  912. %endmacro
  913. %macro SAD_X4_START_1x16P_SSE2 0
  914.     movdqa xmm7, [r0]
  915.     movdqu xmm0, [r1]
  916.     movdqu xmm1, [r2]
  917.     movdqu xmm2, [r3]
  918.     movdqu xmm3, [r4]
  919.     psadbw xmm0, xmm7
  920.     psadbw xmm1, xmm7
  921.     psadbw xmm2, xmm7
  922.     psadbw xmm3, xmm7
  923. %endmacro
  924. %macro SAD_X4_1x16P_SSE2 2
  925.     movdqa xmm7, [r0+%1]
  926.     movdqu xmm4, [r1+%2]
  927.     movdqu xmm5, [r2+%2]
  928.     movdqu xmm6, [r3+%2]
  929. %ifdef ARCH_X86_64
  930.     movdqu xmm8, [r4+%2]
  931.     psadbw xmm4, xmm7
  932.     psadbw xmm5, xmm7
  933.     psadbw xmm6, xmm7
  934.     psadbw xmm8, xmm7
  935.     paddw  xmm0, xmm4
  936.     paddw  xmm1, xmm5
  937.     paddw  xmm2, xmm6
  938.     paddw  xmm3, xmm8
  939. %else
  940.     psadbw xmm4, xmm7
  941.     psadbw xmm5, xmm7
  942.     paddw  xmm0, xmm4
  943.     psadbw xmm6, xmm7
  944.     movdqu xmm4, [r4+%2]
  945.     paddw  xmm1, xmm5
  946.     psadbw xmm4, xmm7
  947.     paddw  xmm2, xmm6
  948.     paddw  xmm3, xmm4
  949. %endif
  950. %endmacro
  951. %macro SAD_X4_2x16P_SSE2 1
  952. %if %1
  953.     SAD_X4_START_1x16P_SSE2
  954. %else
  955.     SAD_X4_1x16P_SSE2 0, 0
  956. %endif
  957.     SAD_X4_1x16P_SSE2 FENC_STRIDE, r5
  958.     add  r0, 2*FENC_STRIDE
  959.     lea  r1, [r1+2*r5]
  960.     lea  r2, [r2+2*r5]
  961.     lea  r3, [r3+2*r5]
  962.     lea  r4, [r4+2*r5]
  963. %endmacro
  964. %macro SAD_X3_2x8P_SSE2 1
  965. %if %1
  966.     SAD_X3_START_2x8P_SSE2
  967. %else
  968.     SAD_X3_2x8P_SSE2
  969. %endif
  970.     add  r0, 2*FENC_STRIDE
  971.     lea  r1, [r1+2*r4]
  972.     lea  r2, [r2+2*r4]
  973.     lea  r3, [r3+2*r4]
  974. %endmacro
  975. %macro SAD_X4_2x8P_SSE2 1
  976. %if %1
  977.     SAD_X4_START_2x8P_SSE2
  978. %else
  979.     SAD_X4_2x8P_SSE2
  980. %endif
  981.     add  r0, 2*FENC_STRIDE
  982.     lea  r1, [r1+2*r5]
  983.     lea  r2, [r2+2*r5]
  984.     lea  r3, [r3+2*r5]
  985.     lea  r4, [r4+2*r5]
  986. %endmacro
  987. %macro SAD_X3_END_SSE2 0
  988.     movhlps xmm4, xmm0
  989.     movhlps xmm5, xmm1
  990.     movhlps xmm6, xmm2
  991.     paddw   xmm0, xmm4
  992.     paddw   xmm1, xmm5
  993.     paddw   xmm2, xmm6
  994. %ifdef UNIX64
  995.     movd [r5+0], xmm0
  996.     movd [r5+4], xmm1
  997.     movd [r5+8], xmm2
  998. %else
  999.     mov      r0, r5mp
  1000.     movd [r0+0], xmm0
  1001.     movd [r0+4], xmm1
  1002.     movd [r0+8], xmm2
  1003. %endif
  1004.     RET
  1005. %endmacro
  1006. %macro SAD_X4_END_SSE2 0
  1007.     mov       r0, r6mp
  1008.     psllq   xmm1, 32
  1009.     psllq   xmm3, 32
  1010.     paddw   xmm0, xmm1
  1011.     paddw   xmm2, xmm3
  1012.     movhlps xmm1, xmm0
  1013.     movhlps xmm3, xmm2
  1014.     paddw   xmm0, xmm1
  1015.     paddw   xmm2, xmm3
  1016.     movq  [r0+0], xmm0
  1017.     movq  [r0+8], xmm2
  1018.     RET
  1019. %endmacro
  1020. %macro SAD_X3_START_1x16P_SSE2_MISALIGN 0
  1021.     movdqa xmm2, [r0]
  1022.     movdqu xmm0, [r1]
  1023.     movdqu xmm1, [r2]
  1024.     psadbw xmm0, xmm2
  1025.     psadbw xmm1, xmm2
  1026.     psadbw xmm2, [r3]
  1027. %endmacro
  1028. %macro SAD_X3_1x16P_SSE2_MISALIGN 2
  1029.     movdqa xmm3, [r0+%1]
  1030.     movdqu xmm4, [r1+%2]
  1031.     movdqu xmm5, [r2+%2]
  1032.     psadbw xmm4, xmm3
  1033.     psadbw xmm5, xmm3
  1034.     psadbw xmm3, [r3+%2]
  1035.     paddw  xmm0, xmm4
  1036.     paddw  xmm1, xmm5
  1037.     paddw  xmm2, xmm3
  1038. %endmacro
  1039. %macro SAD_X4_START_1x16P_SSE2_MISALIGN 0
  1040.     movdqa xmm3, [r0]
  1041.     movdqu xmm0, [r1]
  1042.     movdqu xmm1, [r2]
  1043.     movdqu xmm2, [r3]
  1044.     psadbw xmm0, xmm3
  1045.     psadbw xmm1, xmm3
  1046.     psadbw xmm2, xmm3
  1047.     psadbw xmm3, [r4]
  1048. %endmacro
  1049. %macro SAD_X4_1x16P_SSE2_MISALIGN 2
  1050.     movdqa xmm7, [r0+%1]
  1051.     movdqu xmm4, [r1+%2]
  1052.     movdqu xmm5, [r2+%2]
  1053.     movdqu xmm6, [r3+%2]
  1054.     psadbw xmm4, xmm7
  1055.     psadbw xmm5, xmm7
  1056.     psadbw xmm6, xmm7
  1057.     psadbw xmm7, [r4+%2]
  1058.     paddw  xmm0, xmm4
  1059.     paddw  xmm1, xmm5
  1060.     paddw  xmm2, xmm6
  1061.     paddw  xmm3, xmm7
  1062. %endmacro
  1063. %macro SAD_X3_2x16P_SSE2_MISALIGN 1
  1064. %if %1
  1065.     SAD_X3_START_1x16P_SSE2_MISALIGN
  1066. %else
  1067.     SAD_X3_1x16P_SSE2_MISALIGN 0, 0
  1068. %endif
  1069.     SAD_X3_1x16P_SSE2_MISALIGN FENC_STRIDE, r4
  1070.     add  r0, 2*FENC_STRIDE
  1071.     lea  r1, [r1+2*r4]
  1072.     lea  r2, [r2+2*r4]
  1073.     lea  r3, [r3+2*r4]
  1074. %endmacro
  1075. %macro SAD_X4_2x16P_SSE2_MISALIGN 1
  1076. %if %1
  1077.     SAD_X4_START_1x16P_SSE2_MISALIGN
  1078. %else
  1079.     SAD_X4_1x16P_SSE2_MISALIGN 0, 0
  1080. %endif
  1081.     SAD_X4_1x16P_SSE2_MISALIGN FENC_STRIDE, r5
  1082.     add  r0, 2*FENC_STRIDE
  1083.     lea  r1, [r1+2*r5]
  1084.     lea  r2, [r2+2*r5]
  1085.     lea  r3, [r3+2*r5]
  1086.     lea  r4, [r4+2*r5]
  1087. %endmacro
  1088. ;-----------------------------------------------------------------------------
  1089. ; void x264_pixel_sad_x3_16x16_sse2( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1,
  1090. ;                                    uint8_t *pix2, int i_stride, int scores[3] )
  1091. ;-----------------------------------------------------------------------------
  1092. %macro SAD_X_SSE2 4
  1093. cglobal x264_pixel_sad_x%1_%2x%3_%4, 2+%1,2+%1,9
  1094. %ifdef WIN64
  1095.     %assign i %1+1
  1096.     movsxd r %+ i, r %+ i %+ d
  1097. %endif
  1098.     SAD_X%1_2x%2P_SSE2 1
  1099. %rep %3/2-1
  1100.     SAD_X%1_2x%2P_SSE2 0
  1101. %endrep
  1102.     SAD_X%1_END_SSE2
  1103. %endmacro
  1104. %macro SAD_X_SSE2_MISALIGN 4
  1105. cglobal x264_pixel_sad_x%1_%2x%3_%4_misalign, 2+%1,2+%1,9
  1106. %ifdef WIN64
  1107.     %assign i %1+1
  1108.     movsxd r %+ i, r %+ i %+ d
  1109. %endif
  1110.     SAD_X%1_2x%2P_SSE2_MISALIGN 1
  1111. %rep %3/2-1
  1112.     SAD_X%1_2x%2P_SSE2_MISALIGN 0
  1113. %endrep
  1114.     SAD_X%1_END_SSE2
  1115. %endmacro
  1116. SAD_X_SSE2 3, 16, 16, sse2
  1117. SAD_X_SSE2 3, 16,  8, sse2
  1118. SAD_X_SSE2 3,  8, 16, sse2
  1119. SAD_X_SSE2 3,  8,  8, sse2
  1120. SAD_X_SSE2 3,  8,  4, sse2
  1121. SAD_X_SSE2 4, 16, 16, sse2
  1122. SAD_X_SSE2 4, 16,  8, sse2
  1123. SAD_X_SSE2 4,  8, 16, sse2
  1124. SAD_X_SSE2 4,  8,  8, sse2
  1125. SAD_X_SSE2 4,  8,  4, sse2
  1126. SAD_X_SSE2_MISALIGN 3, 16, 16, sse2
  1127. SAD_X_SSE2_MISALIGN 3, 16,  8, sse2
  1128. SAD_X_SSE2_MISALIGN 4, 16, 16, sse2
  1129. SAD_X_SSE2_MISALIGN 4, 16,  8, sse2
  1130. %define movdqu lddqu
  1131. SAD_X_SSE2 3, 16, 16, sse3
  1132. SAD_X_SSE2 3, 16,  8, sse3
  1133. SAD_X_SSE2 4, 16, 16, sse3
  1134. SAD_X_SSE2 4, 16,  8, sse3
  1135. %undef movdqu
  1136. ;=============================================================================
  1137. ; SAD cacheline split
  1138. ;=============================================================================
  1139. ; Core2 (Conroe) can load unaligned data just as quickly as aligned data...
  1140. ; unless the unaligned data spans the border between 2 cachelines, in which
  1141. ; case it's really slow. The exact numbers may differ, but all Intel cpus prior
  1142. ; to Nehalem have a large penalty for cacheline splits.
  1143. ; (8-byte alignment exactly half way between two cachelines is ok though.)
  1144. ; LDDQU was supposed to fix this, but it only works on Pentium 4.
  1145. ; So in the split case we load aligned data and explicitly perform the
  1146. ; alignment between registers. Like on archs that have only aligned loads,
  1147. ; except complicated by the fact that PALIGNR takes only an immediate, not
  1148. ; a variable alignment.
  1149. ; It is also possible to hoist the realignment to the macroblock level (keep
  1150. ; 2 copies of the reference frame, offset by 32 bytes), but the extra memory
  1151. ; needed for that method makes it often slower.
  1152. ; sad 16x16 costs on Core2:
  1153. ; good offsets: 49 cycles (50/64 of all mvs)
  1154. ; cacheline split: 234 cycles (14/64 of all mvs. ammortized: +40 cycles)
  1155. ; page split: 3600 cycles (14/4096 of all mvs. ammortized: +11.5 cycles)
  1156. ; cache or page split with palignr: 57 cycles (ammortized: +2 cycles)
  1157. ; computed jump assumes this loop is exactly 80 bytes
  1158. %macro SAD16_CACHELINE_LOOP_SSE2 1 ; alignment
  1159. ALIGN 16
  1160. sad_w16_align%1_sse2:
  1161.     movdqa  xmm1, [r2+16]
  1162.     movdqa  xmm2, [r2+r3+16]
  1163.     movdqa  xmm3, [r2]
  1164.     movdqa  xmm4, [r2+r3]
  1165.     pslldq  xmm1, 16-%1
  1166.     pslldq  xmm2, 16-%1
  1167.     psrldq  xmm3, %1
  1168.     psrldq  xmm4, %1
  1169.     por     xmm1, xmm3
  1170.     por     xmm2, xmm4
  1171.     psadbw  xmm1, [r0]
  1172.     psadbw  xmm2, [r0+r1]
  1173.     paddw   xmm0, xmm1
  1174.     paddw   xmm0, xmm2
  1175.     lea     r0,   [r0+2*r1]
  1176.     lea     r2,   [r2+2*r3]
  1177.     dec     r4
  1178.     jg sad_w16_align%1_sse2
  1179.     ret
  1180. %endmacro
  1181. ; computed jump assumes this loop is exactly 64 bytes
  1182. %macro SAD16_CACHELINE_LOOP_SSSE3 1 ; alignment
  1183. ALIGN 16
  1184. sad_w16_align%1_ssse3:
  1185.     movdqa  xmm1, [r2+16]
  1186.     movdqa  xmm2, [r2+r3+16]
  1187.     palignr xmm1, [r2], %1
  1188.     palignr xmm2, [r2+r3], %1
  1189.     psadbw  xmm1, [r0]
  1190.     psadbw  xmm2, [r0+r1]
  1191.     paddw   xmm0, xmm1
  1192.     paddw   xmm0, xmm2
  1193.     lea     r0,   [r0+2*r1]
  1194.     lea     r2,   [r2+2*r3]
  1195.     dec     r4
  1196.     jg sad_w16_align%1_ssse3
  1197.     ret
  1198. %endmacro
  1199. %macro SAD16_CACHELINE_FUNC 2 ; cpu, height
  1200. cglobal x264_pixel_sad_16x%2_cache64_%1
  1201.     mov     eax, r2m
  1202.     and     eax, 0x37
  1203.     cmp     eax, 0x30
  1204.     jle x264_pixel_sad_16x%2_sse2
  1205.     PROLOGUE 4,6
  1206.     mov     r4d, r2d
  1207.     and     r4d, 15
  1208. %ifidn %1, ssse3
  1209.     shl     r4d, 6  ; code size = 64
  1210. %else
  1211.     lea     r4, [r4*5]
  1212.     shl     r4d, 4  ; code size = 80
  1213. %endif
  1214. %define sad_w16_addr (sad_w16_align1_%1 + (sad_w16_align1_%1 - sad_w16_align2_%1))
  1215. %ifdef PIC
  1216.     lea     r5, [sad_w16_addr GLOBAL]
  1217.     add     r5, r4
  1218. %else
  1219.     lea     r5, [sad_w16_addr + r4 GLOBAL]
  1220. %endif
  1221.     and     r2, ~15
  1222.     mov     r4d, %2/2
  1223.     pxor    xmm0, xmm0
  1224.     call    r5
  1225.     movhlps xmm1, xmm0
  1226.     paddw   xmm0, xmm1
  1227.     movd    eax,  xmm0
  1228.     RET
  1229. %endmacro
  1230. %macro SAD_CACHELINE_START_MMX2 4 ; width, height, iterations, cacheline
  1231.     mov    eax, r2m
  1232.     and    eax, 0x17|%1|(%4>>1)
  1233.     cmp    eax, 0x10|%1|(%4>>1)
  1234.     jle x264_pixel_sad_%1x%2_mmxext
  1235.     and    eax, 7
  1236.     shl    eax, 3
  1237.     movd   mm6, [sw_64 GLOBAL]
  1238.     movd   mm7, eax
  1239.     psubw  mm6, mm7
  1240.     PROLOGUE 4,5
  1241.     and    r2, ~7
  1242.     mov    r4d, %3
  1243.     pxor   mm0, mm0
  1244. %endmacro
  1245. %macro SAD16_CACHELINE_FUNC_MMX2 2 ; height, cacheline
  1246. cglobal x264_pixel_sad_16x%1_cache%2_mmxext
  1247.     SAD_CACHELINE_START_MMX2 16, %1, %1, %2
  1248. .loop:
  1249.     movq   mm1, [r2]
  1250.     movq   mm2, [r2+8]
  1251.     movq   mm3, [r2+16]
  1252.     movq   mm4, mm2
  1253.     psrlq  mm1, mm7
  1254.     psllq  mm2, mm6
  1255.     psllq  mm3, mm6
  1256.     psrlq  mm4, mm7
  1257.     por    mm1, mm2
  1258.     por    mm3, mm4
  1259.     psadbw mm1, [r0]
  1260.     psadbw mm3, [r0+8]
  1261.     paddw  mm0, mm1
  1262.     paddw  mm0, mm3
  1263.     add    r2, r3
  1264.     add    r0, r1
  1265.     dec    r4
  1266.     jg .loop
  1267.     movd   eax, mm0
  1268.     RET
  1269. %endmacro
  1270. %macro SAD8_CACHELINE_FUNC_MMX2 2 ; height, cacheline
  1271. cglobal x264_pixel_sad_8x%1_cache%2_mmxext
  1272.     SAD_CACHELINE_START_MMX2 8, %1, %1/2, %2
  1273. .loop:
  1274.     movq   mm1, [r2+8]
  1275.     movq   mm2, [r2+r3+8]
  1276.     movq   mm3, [r2]
  1277.     movq   mm4, [r2+r3]
  1278.     psllq  mm1, mm6
  1279.     psllq  mm2, mm6
  1280.     psrlq  mm3, mm7
  1281.     psrlq  mm4, mm7
  1282.     por    mm1, mm3
  1283.     por    mm2, mm4
  1284.     psadbw mm1, [r0]
  1285.     psadbw mm2, [r0+r1]
  1286.     paddw  mm0, mm1
  1287.     paddw  mm0, mm2
  1288.     lea    r2, [r2+2*r3]
  1289.     lea    r0, [r0+2*r1]
  1290.     dec    r4
  1291.     jg .loop
  1292.     movd   eax, mm0
  1293.     RET
  1294. %endmacro
  1295. ; sad_x3/x4_cache64: check each mv.
  1296. ; if they're all within a cacheline, use normal sad_x3/x4.
  1297. ; otherwise, send them individually to sad_cache64.
  1298. %macro CHECK_SPLIT 3 ; pix, width, cacheline
  1299.     mov  eax, %1
  1300.     and  eax, 0x17|%2|(%3>>1)
  1301.     cmp  eax, 0x10|%2|(%3>>1)
  1302.     jg .split
  1303. %endmacro
  1304. %macro SADX3_CACHELINE_FUNC 6 ; width, height, cacheline, normal_ver, split_ver, name
  1305. cglobal x264_pixel_sad_x3_%1x%2_cache%3_%6
  1306.     CHECK_SPLIT r1m, %1, %3
  1307.     CHECK_SPLIT r2m, %1, %3
  1308.     CHECK_SPLIT r3m, %1, %3
  1309.     jmp x264_pixel_sad_x3_%1x%2_%4
  1310. .split:
  1311. %ifdef ARCH_X86_64
  1312.     PROLOGUE 6,7
  1313. %ifdef WIN64
  1314.     movsxd r4, r4d
  1315.     sub  rsp, 8
  1316. %endif
  1317.     push r3
  1318.     push r2
  1319.     mov  r2, r1
  1320.     mov  r1, FENC_STRIDE
  1321.     mov  r3, r4
  1322.     mov  r10, r0
  1323.     mov  r11, r5
  1324.     call x264_pixel_sad_%1x%2_cache%3_%5
  1325.     mov  [r11], eax
  1326. %ifdef WIN64
  1327.     mov  r2, [rsp]
  1328. %else
  1329.     pop  r2
  1330. %endif
  1331.     mov  r0, r10
  1332.     call x264_pixel_sad_%1x%2_cache%3_%5
  1333.     mov  [r11+4], eax
  1334. %ifdef WIN64
  1335.     mov  r2, [rsp+8]
  1336. %else
  1337.     pop  r2
  1338. %endif
  1339.     mov  r0, r10
  1340.     call x264_pixel_sad_%1x%2_cache%3_%5
  1341.     mov  [r11+8], eax
  1342. %ifdef WIN64
  1343.     add  rsp, 24
  1344. %endif
  1345.     RET
  1346. %else
  1347.     push edi
  1348.     mov  edi, [esp+28]
  1349.     push dword [esp+24]
  1350.     push dword [esp+16]
  1351.     push dword 16
  1352.     push dword [esp+20]
  1353.     call x264_pixel_sad_%1x%2_cache%3_%5
  1354.     mov  ecx, [esp+32]
  1355.     mov  [edi], eax
  1356.     mov  [esp+8], ecx
  1357.     call x264_pixel_sad_%1x%2_cache%3_%5
  1358.     mov  ecx, [esp+36]
  1359.     mov  [edi+4], eax
  1360.     mov  [esp+8], ecx
  1361.     call x264_pixel_sad_%1x%2_cache%3_%5
  1362.     mov  [edi+8], eax
  1363.     add  esp, 16
  1364.     pop  edi
  1365.     ret
  1366. %endif
  1367. %endmacro
  1368. %macro SADX4_CACHELINE_FUNC 6 ; width, height, cacheline, normal_ver, split_ver, name
  1369. cglobal x264_pixel_sad_x4_%1x%2_cache%3_%6
  1370.     CHECK_SPLIT r1m, %1, %3
  1371.     CHECK_SPLIT r2m, %1, %3
  1372.     CHECK_SPLIT r3m, %1, %3
  1373.     CHECK_SPLIT r4m, %1, %3
  1374.     jmp x264_pixel_sad_x4_%1x%2_%4
  1375. .split:
  1376. %ifdef ARCH_X86_64
  1377.     PROLOGUE 6,7
  1378.     mov  r11,  r6mp
  1379. %ifdef WIN64
  1380.     movsxd r5, r5d
  1381. %endif
  1382.     push r4
  1383.     push r3
  1384.     push r2
  1385.     mov  r2, r1
  1386.     mov  r1, FENC_STRIDE
  1387.     mov  r3, r5
  1388.     mov  r10, r0
  1389.     call x264_pixel_sad_%1x%2_cache%3_%5
  1390.     mov  [r11], eax
  1391. %ifdef WIN64
  1392.     mov  r2, [rsp]
  1393. %else
  1394.     pop  r2
  1395. %endif
  1396.     mov  r0, r10
  1397.     call x264_pixel_sad_%1x%2_cache%3_%5
  1398.     mov  [r11+4], eax
  1399. %ifdef WIN64
  1400.     mov  r2, [rsp+8]
  1401. %else
  1402.     pop  r2
  1403. %endif
  1404.     mov  r0, r10
  1405.     call x264_pixel_sad_%1x%2_cache%3_%5
  1406.     mov  [r11+8], eax
  1407. %ifdef WIN64
  1408.     mov  r2, [rsp+16]
  1409. %else
  1410.     pop  r2
  1411. %endif
  1412.     mov  r0, r10
  1413.     call x264_pixel_sad_%1x%2_cache%3_%5
  1414.     mov  [r11+12], eax
  1415. %ifdef WIN64
  1416.     add  rsp, 24
  1417. %endif
  1418.     RET
  1419. %else
  1420.     push edi
  1421.     mov  edi, [esp+32]
  1422.     push dword [esp+28]
  1423.     push dword [esp+16]
  1424.     push dword 16
  1425.     push dword [esp+20]
  1426.     call x264_pixel_sad_%1x%2_cache%3_%5
  1427.     mov  ecx, [esp+32]
  1428.     mov  [edi], eax
  1429.     mov  [esp+8], ecx
  1430.     call x264_pixel_sad_%1x%2_cache%3_%5
  1431.     mov  ecx, [esp+36]
  1432.     mov  [edi+4], eax
  1433.     mov  [esp+8], ecx
  1434.     call x264_pixel_sad_%1x%2_cache%3_%5
  1435.     mov  ecx, [esp+40]
  1436.     mov  [edi+8], eax
  1437.     mov  [esp+8], ecx
  1438.     call x264_pixel_sad_%1x%2_cache%3_%5
  1439.     mov  [edi+12], eax
  1440.     add  esp, 16
  1441.     pop  edi
  1442.     ret
  1443. %endif
  1444. %endmacro
  1445. %macro SADX34_CACHELINE_FUNC 1+
  1446.     SADX3_CACHELINE_FUNC %1
  1447.     SADX4_CACHELINE_FUNC %1
  1448. %endmacro
  1449. ; instantiate the aligned sads
  1450. %ifndef ARCH_X86_64
  1451. SAD16_CACHELINE_FUNC_MMX2  8, 32
  1452. SAD16_CACHELINE_FUNC_MMX2 16, 32
  1453. SAD8_CACHELINE_FUNC_MMX2   4, 32
  1454. SAD8_CACHELINE_FUNC_MMX2   8, 32
  1455. SAD8_CACHELINE_FUNC_MMX2  16, 32
  1456. SAD16_CACHELINE_FUNC_MMX2  8, 64
  1457. SAD16_CACHELINE_FUNC_MMX2 16, 64
  1458. %endif ; !ARCH_X86_64
  1459. SAD8_CACHELINE_FUNC_MMX2   4, 64
  1460. SAD8_CACHELINE_FUNC_MMX2   8, 64
  1461. SAD8_CACHELINE_FUNC_MMX2  16, 64
  1462. %ifndef ARCH_X86_64
  1463. SADX34_CACHELINE_FUNC 16, 16, 32, mmxext, mmxext, mmxext
  1464. SADX34_CACHELINE_FUNC 16,  8, 32, mmxext, mmxext, mmxext
  1465. SADX34_CACHELINE_FUNC  8, 16, 32, mmxext, mmxext, mmxext
  1466. SADX34_CACHELINE_FUNC  8,  8, 32, mmxext, mmxext, mmxext
  1467. SADX34_CACHELINE_FUNC 16, 16, 64, mmxext, mmxext, mmxext
  1468. SADX34_CACHELINE_FUNC 16,  8, 64, mmxext, mmxext, mmxext
  1469. %endif ; !ARCH_X86_64
  1470. SADX34_CACHELINE_FUNC  8, 16, 64, mmxext, mmxext, mmxext
  1471. SADX34_CACHELINE_FUNC  8,  8, 64, mmxext, mmxext, mmxext
  1472. %ifndef ARCH_X86_64
  1473. SAD16_CACHELINE_FUNC sse2, 8
  1474. SAD16_CACHELINE_FUNC sse2, 16
  1475. %assign i 1
  1476. %rep 15
  1477. SAD16_CACHELINE_LOOP_SSE2 i
  1478. %assign i i+1
  1479. %endrep
  1480. SADX34_CACHELINE_FUNC 16, 16, 64, sse2, sse2, sse2
  1481. SADX34_CACHELINE_FUNC 16,  8, 64, sse2, sse2, sse2
  1482. %endif ; !ARCH_X86_64
  1483. SADX34_CACHELINE_FUNC  8, 16, 64, sse2, mmxext, sse2
  1484. SAD16_CACHELINE_FUNC ssse3, 8
  1485. SAD16_CACHELINE_FUNC ssse3, 16
  1486. %assign i 1
  1487. %rep 15
  1488. SAD16_CACHELINE_LOOP_SSSE3 i
  1489. %assign i i+1
  1490. %endrep
  1491. SADX34_CACHELINE_FUNC 16, 16, 64, sse2, ssse3, ssse3
  1492. SADX34_CACHELINE_FUNC 16,  8, 64, sse2, ssse3, ssse3