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

Audio

开发平台:

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. ;*          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. pb_3: times 16 db 3
  28. sw_64: dd 64
  29. SECTION .text
  30. ;=============================================================================
  31. ; SAD MMX
  32. ;=============================================================================
  33. %macro SAD_INC_2x16P 0
  34.     movq    mm1,    [r0]
  35.     movq    mm2,    [r0+8]
  36.     movq    mm3,    [r0+r1]
  37.     movq    mm4,    [r0+r1+8]
  38.     psadbw  mm1,    [r2]
  39.     psadbw  mm2,    [r2+8]
  40.     psadbw  mm3,    [r2+r3]
  41.     psadbw  mm4,    [r2+r3+8]
  42.     lea     r0,     [r0+2*r1]
  43.     paddw   mm1,    mm2
  44.     paddw   mm3,    mm4
  45.     lea     r2,     [r2+2*r3]
  46.     paddw   mm0,    mm1
  47.     paddw   mm0,    mm3
  48. %endmacro
  49. %macro SAD_INC_2x8P 0
  50.     movq    mm1,    [r0]
  51.     movq    mm2,    [r0+r1]
  52.     psadbw  mm1,    [r2]
  53.     psadbw  mm2,    [r2+r3]
  54.     lea     r0,     [r0+2*r1]
  55.     paddw   mm0,    mm1
  56.     paddw   mm0,    mm2
  57.     lea     r2,     [r2+2*r3]
  58. %endmacro
  59. %macro SAD_INC_2x4P 0
  60.     movd    mm1,    [r0]
  61.     movd    mm2,    [r2]
  62.     punpckldq mm1,  [r0+r1]
  63.     punpckldq mm2,  [r2+r3]
  64.     psadbw  mm1,    mm2
  65.     paddw   mm0,    mm1
  66.     lea     r0,     [r0+2*r1]
  67.     lea     r2,     [r2+2*r3]
  68. %endmacro
  69. ;-----------------------------------------------------------------------------
  70. ; int x264_pixel_sad_16x16_mmxext (uint8_t *, int, uint8_t *, int )
  71. ;-----------------------------------------------------------------------------
  72. %macro SAD 2
  73. cglobal x264_pixel_sad_%1x%2_mmxext, 4,4
  74.     pxor    mm0, mm0
  75. %rep %2/2
  76.     SAD_INC_2x%1P
  77. %endrep
  78.     movd    eax, mm0
  79.     RET
  80. %endmacro
  81. SAD 16, 16
  82. SAD 16,  8
  83. SAD  8, 16
  84. SAD  8,  8
  85. SAD  8,  4
  86. SAD  4,  8
  87. SAD  4,  4
  88. ;=============================================================================
  89. ; SAD XMM
  90. ;=============================================================================
  91. %macro SAD_END_SSE2 0
  92.     movhlps xmm1, xmm0
  93.     paddw   xmm0, xmm1
  94.     movd    eax,  xmm0
  95.     RET
  96. %endmacro
  97. %macro SAD_W16 1
  98. ;-----------------------------------------------------------------------------
  99. ; int x264_pixel_sad_16x16_sse2 (uint8_t *, int, uint8_t *, int )
  100. ;-----------------------------------------------------------------------------
  101. cglobal x264_pixel_sad_16x16_%1, 4,4
  102.     movdqu  xmm0,   [r2]
  103.     movdqu  xmm1,   [r2+r3]
  104.     lea     r2,     [r2+2*r3]
  105.     movdqu  xmm2,   [r2]
  106.     movdqu  xmm3,   [r2+r3]
  107.     lea     r2,     [r2+2*r3]
  108.     psadbw  xmm0,   [r0]
  109.     psadbw  xmm1,   [r0+r1]
  110.     lea     r0,     [r0+2*r1]
  111.     movdqu  xmm4,   [r2]
  112.     paddw   xmm0,   xmm1
  113.     psadbw  xmm2,   [r0]
  114.     psadbw  xmm3,   [r0+r1]
  115.     lea     r0,     [r0+2*r1]
  116.     movdqu  xmm5,   [r2+r3]
  117.     lea     r2,     [r2+2*r3]
  118.     paddw   xmm2,   xmm3
  119.     movdqu  xmm6,   [r2]
  120.     movdqu  xmm7,   [r2+r3]
  121.     lea     r2,     [r2+2*r3]
  122.     paddw   xmm0,   xmm2
  123.     psadbw  xmm4,   [r0]
  124.     psadbw  xmm5,   [r0+r1]
  125.     lea     r0,     [r0+2*r1]
  126.     movdqu  xmm1,   [r2]
  127.     paddw   xmm4,   xmm5
  128.     psadbw  xmm6,   [r0]
  129.     psadbw  xmm7,   [r0+r1]
  130.     lea     r0,     [r0+2*r1]
  131.     movdqu  xmm2,   [r2+r3]
  132.     lea     r2,     [r2+2*r3]
  133.     paddw   xmm6,   xmm7
  134.     movdqu  xmm3,   [r2]
  135.     paddw   xmm0,   xmm4
  136.     movdqu  xmm4,   [r2+r3]
  137.     lea     r2,     [r2+2*r3]
  138.     paddw   xmm0,   xmm6
  139.     psadbw  xmm1,   [r0]
  140.     psadbw  xmm2,   [r0+r1]
  141.     lea     r0,     [r0+2*r1]
  142.     movdqu  xmm5,   [r2]
  143.     paddw   xmm1,   xmm2
  144.     psadbw  xmm3,   [r0]
  145.     psadbw  xmm4,   [r0+r1]
  146.     lea     r0,     [r0+2*r1]
  147.     movdqu  xmm6,   [r2+r3]
  148.     lea     r2,     [r2+2*r3]
  149.     paddw   xmm3,   xmm4
  150.     movdqu  xmm7,   [r2]
  151.     paddw   xmm0,   xmm1
  152.     movdqu  xmm1,   [r2+r3]
  153.     paddw   xmm0,   xmm3
  154.     psadbw  xmm5,   [r0]
  155.     psadbw  xmm6,   [r0+r1]
  156.     lea     r0,     [r0+2*r1]
  157.     paddw   xmm5,   xmm6
  158.     psadbw  xmm7,   [r0]
  159.     psadbw  xmm1,   [r0+r1]
  160.     paddw   xmm7,   xmm1
  161.     paddw   xmm0,   xmm5
  162.     paddw   xmm0,   xmm7
  163.     SAD_END_SSE2
  164. ;-----------------------------------------------------------------------------
  165. ; int x264_pixel_sad_16x8_sse2 (uint8_t *, int, uint8_t *, int )
  166. ;-----------------------------------------------------------------------------
  167. cglobal x264_pixel_sad_16x8_%1, 4,4
  168.     movdqu  xmm0,   [r2]
  169.     movdqu  xmm2,   [r2+r3]
  170.     lea     r2,     [r2+2*r3]
  171.     movdqu  xmm3,   [r2]
  172.     movdqu  xmm4,   [r2+r3]
  173.     psadbw  xmm0,   [r0]
  174.     psadbw  xmm2,   [r0+r1]
  175.     lea     r0,     [r0+2*r1]
  176.     psadbw  xmm3,   [r0]
  177.     psadbw  xmm4,   [r0+r1]
  178.     lea     r0,     [r0+2*r1]
  179.     lea     r2,     [r2+2*r3]
  180.     paddw   xmm0,   xmm2
  181.     paddw   xmm3,   xmm4
  182.     paddw   xmm0,   xmm3
  183.     movdqu  xmm1,   [r2]
  184.     movdqu  xmm2,   [r2+r3]
  185.     lea     r2,     [r2+2*r3]
  186.     movdqu  xmm3,   [r2]
  187.     movdqu  xmm4,   [r2+r3]
  188.     psadbw  xmm1,   [r0]
  189.     psadbw  xmm2,   [r0+r1]
  190.     lea     r0,     [r0+2*r1]
  191.     psadbw  xmm3,   [r0]
  192.     psadbw  xmm4,   [r0+r1]
  193.     lea     r0,     [r0+2*r1]
  194.     lea     r2,     [r2+2*r3]
  195.     paddw   xmm1,   xmm2
  196.     paddw   xmm3,   xmm4
  197.     paddw   xmm0,   xmm1
  198.     paddw   xmm0,   xmm3
  199.     SAD_END_SSE2
  200. %endmacro
  201. SAD_W16 sse2
  202. %define movdqu lddqu
  203. SAD_W16 sse3
  204. %define movdqu movdqa
  205. SAD_W16 sse2_aligned
  206. %define movdqu movups
  207. ;-----------------------------------------------------------------------------
  208. ; void intra_sad_x3_16x16 ( uint8_t *fenc, uint8_t *fdec, int res[3] );
  209. ;-----------------------------------------------------------------------------
  210. ;xmm7: DC prediction    xmm6: H prediction  xmm5: V prediction
  211. ;xmm4: DC pred score    xmm3: H pred score  xmm2: V pred score
  212. %macro INTRA_SAD16 1
  213. cglobal x264_intra_sad_x3_16x16_%1,3,5
  214.     pxor    mm0, mm0
  215.     pxor    mm1, mm1
  216.     psadbw  mm0, [r1-FDEC_STRIDE+0]
  217.     psadbw  mm1, [r1-FDEC_STRIDE+8]
  218.     paddw   mm0, mm1
  219.     movd    r3d, mm0
  220. %ifidn %1, ssse3
  221.     mova  m1, [pb_3 GLOBAL]
  222. %endif
  223. %assign n 0
  224. %rep 16
  225.     movzx   r4d, byte [r1-1+FDEC_STRIDE*n]
  226.     add     r3d, r4d
  227. %assign n n+1
  228. %endrep
  229.     add     r3d, 16
  230.     shr     r3d, 5
  231.     imul    r3d, 0x01010101
  232.     movd    m7, r3d
  233.     mova    m5, [r1-FDEC_STRIDE]
  234. %if mmsize==16
  235.     pshufd  m7, m7, 0
  236. %else
  237.     mova    m1, [r1-FDEC_STRIDE+8]
  238.     punpckldq m7, m7
  239. %endif
  240.     pxor    m4, m4
  241.     pxor    m3, m3
  242.     pxor    m2, m2
  243.     mov     r3d, 15*FENC_STRIDE
  244. .vloop:
  245.     SPLATB  m6, r1+r3*2-1, m1
  246.     mova    m0, [r0+r3]
  247.     psadbw  m0, m7
  248.     paddw   m4, m0
  249.     mova    m0, [r0+r3]
  250.     psadbw  m0, m5
  251.     paddw   m2, m0
  252. %if mmsize==8
  253.     mova    m0, [r0+r3]
  254.     psadbw  m0, m6
  255.     paddw   m3, m0
  256.     mova    m0, [r0+r3+8]
  257.     psadbw  m0, m7
  258.     paddw   m4, m0
  259.     mova    m0, [r0+r3+8]
  260.     psadbw  m0, m1
  261.     paddw   m2, m0
  262.     psadbw  m6, [r0+r3+8]
  263.     paddw   m3, m6
  264. %else
  265.     psadbw  m6, [r0+r3]
  266.     paddw   m3, m6
  267. %endif
  268.     add     r3d, -FENC_STRIDE
  269.     jge .vloop
  270. %if mmsize==16
  271.     pslldq  m3, 4
  272.     por     m3, m2
  273.     movhlps m1, m3
  274.     paddw   m3, m1
  275.     movq  [r2+0], m3
  276.     movhlps m1, m4
  277.     paddw   m4, m1
  278. %else
  279.     movd  [r2+0], m2
  280.     movd  [r2+4], m3
  281. %endif
  282.     movd  [r2+8], m4
  283.     RET
  284. %endmacro
  285. INIT_MMX
  286. %define SPLATB SPLATB_MMX
  287. INTRA_SAD16 mmxext
  288. INIT_XMM
  289. INTRA_SAD16 sse2
  290. %define SPLATB SPLATB_SSSE3
  291. INTRA_SAD16 ssse3
  292. ;=============================================================================
  293. ; SAD x3/x4 MMX
  294. ;=============================================================================
  295. %macro SAD_X3_START_1x8P 0
  296.     movq    mm3,    [r0]
  297.     movq    mm0,    [r1]
  298.     movq    mm1,    [r2]
  299.     movq    mm2,    [r3]
  300.     psadbw  mm0,    mm3
  301.     psadbw  mm1,    mm3
  302.     psadbw  mm2,    mm3
  303. %endmacro
  304. %macro SAD_X3_1x8P 2
  305.     movq    mm3,    [r0+%1]
  306.     movq    mm4,    [r1+%2]
  307.     movq    mm5,    [r2+%2]
  308.     movq    mm6,    [r3+%2]
  309.     psadbw  mm4,    mm3
  310.     psadbw  mm5,    mm3
  311.     psadbw  mm6,    mm3
  312.     paddw   mm0,    mm4
  313.     paddw   mm1,    mm5
  314.     paddw   mm2,    mm6
  315. %endmacro
  316. %macro SAD_X3_START_2x4P 3
  317.     movd      mm3,  [r0]
  318.     movd      %1,   [r1]
  319.     movd      %2,   [r2]
  320.     movd      %3,   [r3]
  321.     punpckldq mm3,  [r0+FENC_STRIDE]
  322.     punpckldq %1,   [r1+r4]
  323.     punpckldq %2,   [r2+r4]
  324.     punpckldq %3,   [r3+r4]
  325.     psadbw    %1,   mm3
  326.     psadbw    %2,   mm3
  327.     psadbw    %3,   mm3
  328. %endmacro
  329. %macro SAD_X3_2x16P 1
  330. %if %1
  331.     SAD_X3_START_1x8P
  332. %else
  333.     SAD_X3_1x8P 0, 0
  334. %endif
  335.     SAD_X3_1x8P 8, 8
  336.     SAD_X3_1x8P FENC_STRIDE, r4
  337.     SAD_X3_1x8P FENC_STRIDE+8, r4+8
  338.     add     r0, 2*FENC_STRIDE
  339.     lea     r1, [r1+2*r4]
  340.     lea     r2, [r2+2*r4]
  341.     lea     r3, [r3+2*r4]
  342. %endmacro
  343. %macro SAD_X3_2x8P 1
  344. %if %1
  345.     SAD_X3_START_1x8P
  346. %else
  347.     SAD_X3_1x8P 0, 0
  348. %endif
  349.     SAD_X3_1x8P FENC_STRIDE, r4
  350.     add     r0, 2*FENC_STRIDE
  351.     lea     r1, [r1+2*r4]
  352.     lea     r2, [r2+2*r4]
  353.     lea     r3, [r3+2*r4]
  354. %endmacro
  355. %macro SAD_X3_2x4P 1
  356. %if %1
  357.     SAD_X3_START_2x4P mm0, mm1, mm2
  358. %else
  359.     SAD_X3_START_2x4P mm4, mm5, mm6
  360.     paddw     mm0,  mm4
  361.     paddw     mm1,  mm5
  362.     paddw     mm2,  mm6
  363. %endif
  364.     add     r0, 2*FENC_STRIDE
  365.     lea     r1, [r1+2*r4]
  366.     lea     r2, [r2+2*r4]
  367.     lea     r3, [r3+2*r4]
  368. %endmacro
  369. %macro SAD_X4_START_1x8P 0
  370.     movq    mm7,    [r0]
  371.     movq    mm0,    [r1]
  372.     movq    mm1,    [r2]
  373.     movq    mm2,    [r3]
  374.     movq    mm3,    [r4]
  375.     psadbw  mm0,    mm7
  376.     psadbw  mm1,    mm7
  377.     psadbw  mm2,    mm7
  378.     psadbw  mm3,    mm7
  379. %endmacro
  380. %macro SAD_X4_1x8P 2
  381.     movq    mm7,    [r0+%1]
  382.     movq    mm4,    [r1+%2]
  383.     movq    mm5,    [r2+%2]
  384.     movq    mm6,    [r3+%2]
  385.     psadbw  mm4,    mm7
  386.     psadbw  mm5,    mm7
  387.     psadbw  mm6,    mm7
  388.     psadbw  mm7,    [r4+%2]
  389.     paddw   mm0,    mm4
  390.     paddw   mm1,    mm5
  391.     paddw   mm2,    mm6
  392.     paddw   mm3,    mm7
  393. %endmacro
  394. %macro SAD_X4_START_2x4P 0
  395.     movd      mm7,  [r0]
  396.     movd      mm0,  [r1]
  397.     movd      mm1,  [r2]
  398.     movd      mm2,  [r3]
  399.     movd      mm3,  [r4]
  400.     punpckldq mm7,  [r0+FENC_STRIDE]
  401.     punpckldq mm0,  [r1+r5]
  402.     punpckldq mm1,  [r2+r5]
  403.     punpckldq mm2,  [r3+r5]
  404.     punpckldq mm3,  [r4+r5]
  405.     psadbw    mm0,  mm7
  406.     psadbw    mm1,  mm7
  407.     psadbw    mm2,  mm7
  408.     psadbw    mm3,  mm7
  409. %endmacro
  410. %macro SAD_X4_INC_2x4P 0
  411.     movd      mm7,  [r0]
  412.     movd      mm4,  [r1]
  413.     movd      mm5,  [r2]
  414.     punpckldq mm7,  [r0+FENC_STRIDE]
  415.     punpckldq mm4,  [r1+r5]
  416.     punpckldq mm5,  [r2+r5]
  417.     psadbw    mm4,  mm7
  418.     psadbw    mm5,  mm7
  419.     paddw     mm0,  mm4
  420.     paddw     mm1,  mm5
  421.     movd      mm4,  [r3]
  422.     movd      mm5,  [r4]
  423.     punpckldq mm4,  [r3+r5]
  424.     punpckldq mm5,  [r4+r5]
  425.     psadbw    mm4,  mm7
  426.     psadbw    mm5,  mm7
  427.     paddw     mm2,  mm4
  428.     paddw     mm3,  mm5
  429. %endmacro
  430. %macro SAD_X4_2x16P 1
  431. %if %1
  432.     SAD_X4_START_1x8P
  433. %else
  434.     SAD_X4_1x8P 0, 0
  435. %endif
  436.     SAD_X4_1x8P 8, 8
  437.     SAD_X4_1x8P FENC_STRIDE, r5
  438.     SAD_X4_1x8P FENC_STRIDE+8, r5+8
  439.     add     r0, 2*FENC_STRIDE
  440.     lea     r1, [r1+2*r5]
  441.     lea     r2, [r2+2*r5]
  442.     lea     r3, [r3+2*r5]
  443.     lea     r4, [r4+2*r5]
  444. %endmacro
  445. %macro SAD_X4_2x8P 1
  446. %if %1
  447.     SAD_X4_START_1x8P
  448. %else
  449.     SAD_X4_1x8P 0, 0
  450. %endif
  451.     SAD_X4_1x8P FENC_STRIDE, r5
  452.     add     r0, 2*FENC_STRIDE
  453.     lea     r1, [r1+2*r5]
  454.     lea     r2, [r2+2*r5]
  455.     lea     r3, [r3+2*r5]
  456.     lea     r4, [r4+2*r5]
  457. %endmacro
  458. %macro SAD_X4_2x4P 1
  459. %if %1
  460.     SAD_X4_START_2x4P
  461. %else
  462.     SAD_X4_INC_2x4P
  463. %endif
  464.     add     r0, 2*FENC_STRIDE
  465.     lea     r1, [r1+2*r5]
  466.     lea     r2, [r2+2*r5]
  467.     lea     r3, [r3+2*r5]
  468.     lea     r4, [r4+2*r5]
  469. %endmacro
  470. %macro SAD_X3_END 0
  471. %ifdef ARCH_X86_64
  472.     movd    [r5+0], mm0
  473.     movd    [r5+4], mm1
  474.     movd    [r5+8], mm2
  475. %else
  476.     mov     r0, r5m
  477.     movd    [r0+0], mm0
  478.     movd    [r0+4], mm1
  479.     movd    [r0+8], mm2
  480. %endif
  481.     RET
  482. %endmacro
  483. %macro SAD_X4_END 0
  484.     mov     r0, r6m
  485.     movd    [r0+0], mm0
  486.     movd    [r0+4], mm1
  487.     movd    [r0+8], mm2
  488.     movd    [r0+12], mm3
  489.     RET
  490. %endmacro
  491. ;-----------------------------------------------------------------------------
  492. ; void x264_pixel_sad_x3_16x16_mmxext( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1,
  493. ;                                      uint8_t *pix2, int i_stride, int scores[3] )
  494. ;-----------------------------------------------------------------------------
  495. %macro SAD_X 3
  496. cglobal x264_pixel_sad_x%1_%2x%3_mmxext, %1+2, %1+2
  497.     SAD_X%1_2x%2P 1
  498. %rep %3/2-1
  499.     SAD_X%1_2x%2P 0
  500. %endrep
  501.     SAD_X%1_END
  502. %endmacro
  503. SAD_X 3, 16, 16
  504. SAD_X 3, 16,  8
  505. SAD_X 3,  8, 16
  506. SAD_X 3,  8,  8
  507. SAD_X 3,  8,  4
  508. SAD_X 3,  4,  8
  509. SAD_X 3,  4,  4
  510. SAD_X 4, 16, 16
  511. SAD_X 4, 16,  8
  512. SAD_X 4,  8, 16
  513. SAD_X 4,  8,  8
  514. SAD_X 4,  8,  4
  515. SAD_X 4,  4,  8
  516. SAD_X 4,  4,  4
  517. ;=============================================================================
  518. ; SAD x3/x4 XMM
  519. ;=============================================================================
  520. %macro SAD_X3_START_1x16P_SSE2 0
  521.     movdqa xmm3, [r0]
  522.     movdqu xmm0, [r1]
  523.     movdqu xmm1, [r2]
  524.     movdqu xmm2, [r3]
  525.     psadbw xmm0, xmm3
  526.     psadbw xmm1, xmm3
  527.     psadbw xmm2, xmm3
  528. %endmacro
  529. %macro SAD_X3_1x16P_SSE2 2
  530.     movdqa xmm3, [r0+%1]
  531.     movdqu xmm4, [r1+%2]
  532.     movdqu xmm5, [r2+%2]
  533.     movdqu xmm6, [r3+%2]
  534.     psadbw xmm4, xmm3
  535.     psadbw xmm5, xmm3
  536.     psadbw xmm6, xmm3
  537.     paddw  xmm0, xmm4
  538.     paddw  xmm1, xmm5
  539.     paddw  xmm2, xmm6
  540. %endmacro
  541. %macro SAD_X3_2x16P_SSE2 1
  542. %if %1
  543.     SAD_X3_START_1x16P_SSE2
  544. %else
  545.     SAD_X3_1x16P_SSE2 0, 0
  546. %endif
  547.     SAD_X3_1x16P_SSE2 FENC_STRIDE, r4
  548.     add  r0, 2*FENC_STRIDE
  549.     lea  r1, [r1+2*r4]
  550.     lea  r2, [r2+2*r4]
  551.     lea  r3, [r3+2*r4]
  552. %endmacro
  553. %macro SAD_X4_START_1x16P_SSE2 0
  554.     movdqa xmm7, [r0]
  555.     movdqu xmm0, [r1]
  556.     movdqu xmm1, [r2]
  557.     movdqu xmm2, [r3]
  558.     movdqu xmm3, [r4]
  559.     psadbw xmm0, xmm7
  560.     psadbw xmm1, xmm7
  561.     psadbw xmm2, xmm7
  562.     psadbw xmm3, xmm7
  563. %endmacro
  564. %macro SAD_X4_1x16P_SSE2 2
  565.     movdqa xmm7, [r0+%1]
  566.     movdqu xmm4, [r1+%2]
  567.     movdqu xmm5, [r2+%2]
  568.     movdqu xmm6, [r3+%2]
  569. %ifdef ARCH_X86_64
  570.     movdqu xmm8, [r4+%2]
  571.     psadbw xmm4, xmm7
  572.     psadbw xmm5, xmm7
  573.     psadbw xmm6, xmm7
  574.     psadbw xmm8, xmm7
  575.     paddw  xmm0, xmm4
  576.     paddw  xmm1, xmm5
  577.     paddw  xmm2, xmm6
  578.     paddw  xmm3, xmm8
  579. %else
  580.     psadbw xmm4, xmm7
  581.     psadbw xmm5, xmm7
  582.     paddw  xmm0, xmm4
  583.     psadbw xmm6, xmm7
  584.     movdqu xmm4, [r4+%2]
  585.     paddw  xmm1, xmm5
  586.     psadbw xmm4, xmm7
  587.     paddw  xmm2, xmm6
  588.     paddw  xmm3, xmm4
  589. %endif
  590. %endmacro
  591. %macro SAD_X4_2x16P_SSE2 1
  592. %if %1
  593.     SAD_X4_START_1x16P_SSE2
  594. %else
  595.     SAD_X4_1x16P_SSE2 0, 0
  596. %endif
  597.     SAD_X4_1x16P_SSE2 FENC_STRIDE, r5
  598.     add  r0, 2*FENC_STRIDE
  599.     lea  r1, [r1+2*r5]
  600.     lea  r2, [r2+2*r5]
  601.     lea  r3, [r3+2*r5]
  602.     lea  r4, [r4+2*r5]
  603. %endmacro
  604. %macro SAD_X3_END_SSE2 0
  605.     movhlps xmm4, xmm0
  606.     movhlps xmm5, xmm1
  607.     movhlps xmm6, xmm2
  608.     paddw   xmm0, xmm4
  609.     paddw   xmm1, xmm5
  610.     paddw   xmm2, xmm6
  611. %ifdef ARCH_X86_64
  612.     movd [r5+0], xmm0
  613.     movd [r5+4], xmm1
  614.     movd [r5+8], xmm2
  615. %else
  616.     mov      r0, r5m
  617.     movd [r0+0], xmm0
  618.     movd [r0+4], xmm1
  619.     movd [r0+8], xmm2
  620. %endif
  621.     RET
  622. %endmacro
  623. %macro SAD_X4_END_SSE2 0
  624.     mov       r0, r6m
  625.     psllq   xmm1, 32
  626.     psllq   xmm3, 32
  627.     paddw   xmm0, xmm1
  628.     paddw   xmm2, xmm3
  629.     movhlps xmm1, xmm0
  630.     movhlps xmm3, xmm2
  631.     paddw   xmm0, xmm1
  632.     paddw   xmm2, xmm3
  633.     movq  [r0+0], xmm0
  634.     movq  [r0+8], xmm2
  635.     RET
  636. %endmacro
  637. ;-----------------------------------------------------------------------------
  638. ; void x264_pixel_sad_x3_16x16_sse2( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1,
  639. ;                                    uint8_t *pix2, int i_stride, int scores[3] )
  640. ;-----------------------------------------------------------------------------
  641. %macro SAD_X_SSE2 4
  642. cglobal x264_pixel_sad_x%1_%2x%3_%4, 2+%1,2+%1
  643.     SAD_X%1_2x%2P_SSE2 1
  644. %rep %3/2-1
  645.     SAD_X%1_2x%2P_SSE2 0
  646. %endrep
  647.     SAD_X%1_END_SSE2
  648. %endmacro
  649. SAD_X_SSE2 3, 16, 16, sse2
  650. SAD_X_SSE2 3, 16,  8, sse2
  651. SAD_X_SSE2 4, 16, 16, sse2
  652. SAD_X_SSE2 4, 16,  8, sse2
  653. %define movdqu lddqu
  654. SAD_X_SSE2 3, 16, 16, sse3
  655. SAD_X_SSE2 3, 16,  8, sse3
  656. SAD_X_SSE2 4, 16, 16, sse3
  657. SAD_X_SSE2 4, 16,  8, sse3
  658. %undef movdqu
  659. ;=============================================================================
  660. ; SAD cacheline split
  661. ;=============================================================================
  662. ; Core2 (Conroe) can load unaligned data just as quickly as aligned data...
  663. ; unless the unaligned data spans the border between 2 cachelines, in which
  664. ; case it's really slow. The exact numbers may differ, but all Intel cpus
  665. ; have a large penalty for cacheline splits.
  666. ; (8-byte alignment exactly half way between two cachelines is ok though.)
  667. ; LDDQU was supposed to fix this, but it only works on Pentium 4.
  668. ; So in the split case we load aligned data and explicitly perform the
  669. ; alignment between registers. Like on archs that have only aligned loads,
  670. ; except complicated by the fact that PALIGNR takes only an immediate, not
  671. ; a variable alignment.
  672. ; It is also possible to hoist the realignment to the macroblock level (keep
  673. ; 2 copies of the reference frame, offset by 32 bytes), but the extra memory
  674. ; needed for that method makes it often slower.
  675. ; sad 16x16 costs on Core2:
  676. ; good offsets: 49 cycles (50/64 of all mvs)
  677. ; cacheline split: 234 cycles (14/64 of all mvs. ammortized: +40 cycles)
  678. ; page split: 3600 cycles (14/4096 of all mvs. ammortized: +11.5 cycles)
  679. ; cache or page split with palignr: 57 cycles (ammortized: +2 cycles)
  680. ; computed jump assumes this loop is exactly 80 bytes
  681. %macro SAD16_CACHELINE_LOOP_SSE2 1 ; alignment
  682. ALIGN 16
  683. sad_w16_align%1_sse2:
  684.     movdqa  xmm1, [r2+16]
  685.     movdqa  xmm2, [r2+r3+16]
  686.     movdqa  xmm3, [r2]
  687.     movdqa  xmm4, [r2+r3]
  688.     pslldq  xmm1, 16-%1
  689.     pslldq  xmm2, 16-%1
  690.     psrldq  xmm3, %1
  691.     psrldq  xmm4, %1
  692.     por     xmm1, xmm3
  693.     por     xmm2, xmm4
  694.     psadbw  xmm1, [r0]
  695.     psadbw  xmm2, [r0+r1]
  696.     paddw   xmm0, xmm1
  697.     paddw   xmm0, xmm2
  698.     lea     r0,   [r0+2*r1]
  699.     lea     r2,   [r2+2*r3]
  700.     dec     r4
  701.     jg sad_w16_align%1_sse2
  702.     ret
  703. %endmacro
  704. ; computed jump assumes this loop is exactly 64 bytes
  705. %macro SAD16_CACHELINE_LOOP_SSSE3 1 ; alignment
  706. ALIGN 16
  707. sad_w16_align%1_ssse3:
  708.     movdqa  xmm1, [r2+16]
  709.     movdqa  xmm2, [r2+r3+16]
  710.     palignr xmm1, [r2], %1
  711.     palignr xmm2, [r2+r3], %1
  712.     psadbw  xmm1, [r0]
  713.     psadbw  xmm2, [r0+r1]
  714.     paddw   xmm0, xmm1
  715.     paddw   xmm0, xmm2
  716.     lea     r0,   [r0+2*r1]
  717.     lea     r2,   [r2+2*r3]
  718.     dec     r4
  719.     jg sad_w16_align%1_ssse3
  720.     ret
  721. %endmacro
  722. %macro SAD16_CACHELINE_FUNC 2 ; cpu, height
  723. cglobal x264_pixel_sad_16x%2_cache64_%1, 0,0
  724.     mov     eax, r2m
  725.     and     eax, 0x37
  726.     cmp     eax, 0x30
  727.     jle x264_pixel_sad_16x%2_sse2
  728.     PROLOGUE 4,6
  729.     mov     r4d, r2d
  730.     and     r4d, 15
  731. %ifidn %1, ssse3
  732.     shl     r4d, 6  ; code size = 64
  733. %else
  734.     lea     r4, [r4*5]
  735.     shl     r4d, 4  ; code size = 80
  736. %endif
  737. %define sad_w16_addr (sad_w16_align1_%1 + (sad_w16_align1_%1 - sad_w16_align2_%1))
  738. %ifdef PIC
  739.     lea     r5, [sad_w16_addr GLOBAL]
  740.     add     r5, r4
  741. %else
  742.     lea     r5, [sad_w16_addr + r4 GLOBAL]
  743. %endif
  744.     and     r2, ~15
  745.     mov     r4d, %2/2
  746.     pxor    xmm0, xmm0
  747.     call    r5
  748.     movhlps xmm1, xmm0
  749.     paddw   xmm0, xmm1
  750.     movd    eax,  xmm0
  751.     RET
  752. %endmacro
  753. %macro SAD_CACHELINE_START_MMX2 4 ; width, height, iterations, cacheline
  754.     mov    eax, r2m
  755.     and    eax, 0x17|%1|(%4>>1)
  756.     cmp    eax, 0x10|%1|(%4>>1)
  757.     jle x264_pixel_sad_%1x%2_mmxext
  758.     and    eax, 7
  759.     shl    eax, 3
  760.     movd   mm6, [sw_64 GLOBAL]
  761.     movd   mm7, eax
  762.     psubw  mm6, mm7
  763.     PROLOGUE 4,5
  764.     and    r2, ~7
  765.     mov    r4d, %3
  766.     pxor   mm0, mm0
  767. %endmacro
  768. %macro SAD16_CACHELINE_FUNC_MMX2 2 ; height, cacheline
  769. cglobal x264_pixel_sad_16x%1_cache%2_mmxext, 0,0
  770.     SAD_CACHELINE_START_MMX2 16, %1, %1, %2
  771. .loop:
  772.     movq   mm1, [r2]
  773.     movq   mm2, [r2+8]
  774.     movq   mm3, [r2+16]
  775.     movq   mm4, mm2
  776.     psrlq  mm1, mm7
  777.     psllq  mm2, mm6
  778.     psllq  mm3, mm6
  779.     psrlq  mm4, mm7
  780.     por    mm1, mm2
  781.     por    mm3, mm4
  782.     psadbw mm1, [r0]
  783.     psadbw mm3, [r0+8]
  784.     paddw  mm0, mm1
  785.     paddw  mm0, mm3
  786.     add    r2, r3
  787.     add    r0, r1
  788.     dec    r4
  789.     jg .loop
  790.     movd   eax, mm0
  791.     RET
  792. %endmacro
  793. %macro SAD8_CACHELINE_FUNC_MMX2 2 ; height, cacheline
  794. cglobal x264_pixel_sad_8x%1_cache%2_mmxext, 0,0
  795.     SAD_CACHELINE_START_MMX2 8, %1, %1/2, %2
  796. .loop:
  797.     movq   mm1, [r2+8]
  798.     movq   mm2, [r2+r3+8]
  799.     movq   mm3, [r2]
  800.     movq   mm4, [r2+r3]
  801.     psllq  mm1, mm6
  802.     psllq  mm2, mm6
  803.     psrlq  mm3, mm7
  804.     psrlq  mm4, mm7
  805.     por    mm1, mm3
  806.     por    mm2, mm4
  807.     psadbw mm1, [r0]
  808.     psadbw mm2, [r0+r1]
  809.     paddw  mm0, mm1
  810.     paddw  mm0, mm2
  811.     lea    r2, [r2+2*r3]
  812.     lea    r0, [r0+2*r1]
  813.     dec    r4
  814.     jg .loop
  815.     movd   eax, mm0
  816.     RET
  817. %endmacro
  818. ; sad_x3/x4_cache64: check each mv.
  819. ; if they're all within a cacheline, use normal sad_x3/x4.
  820. ; otherwise, send them individually to sad_cache64.
  821. %macro CHECK_SPLIT 3 ; pix, width, cacheline
  822.     mov  eax, %1
  823.     and  eax, 0x17|%2|(%3>>1)
  824.     cmp  eax, 0x10|%2|(%3>>1)
  825.     jg .split
  826. %endmacro
  827. %macro SADX3_CACHELINE_FUNC 5 ; width, height, cacheline, normal_ver, split_ver
  828. cglobal x264_pixel_sad_x3_%1x%2_cache%3_%5, 0,0
  829.     CHECK_SPLIT r1m, %1, %3
  830.     CHECK_SPLIT r2m, %1, %3
  831.     CHECK_SPLIT r3m, %1, %3
  832.     jmp x264_pixel_sad_x3_%1x%2_%4
  833. .split:
  834. %ifdef ARCH_X86_64
  835.     push r3
  836.     push r2
  837.     mov  r2, r1
  838.     mov  r1, FENC_STRIDE
  839.     mov  r3, r4
  840.     mov  r10, r0
  841.     mov  r11, r5
  842.     call x264_pixel_sad_%1x%2_cache%3_%5
  843.     mov  [r11], eax
  844.     pop  r2
  845.     mov  r0, r10
  846.     call x264_pixel_sad_%1x%2_cache%3_%5
  847.     mov  [r11+4], eax
  848.     pop  r2
  849.     mov  r0, r10
  850.     call x264_pixel_sad_%1x%2_cache%3_%5
  851.     mov  [r11+8], eax
  852. %else
  853.     push edi
  854.     mov  edi, [esp+28]
  855.     push dword [esp+24]
  856.     push dword [esp+16]
  857.     push dword 16
  858.     push dword [esp+20]
  859.     call x264_pixel_sad_%1x%2_cache%3_%5
  860.     mov  ecx, [esp+32]
  861.     mov  [edi], eax
  862.     mov  [esp+8], ecx
  863.     call x264_pixel_sad_%1x%2_cache%3_%5
  864.     mov  ecx, [esp+36]
  865.     mov  [edi+4], eax
  866.     mov  [esp+8], ecx
  867.     call x264_pixel_sad_%1x%2_cache%3_%5
  868.     mov  [edi+8], eax
  869.     add  esp, 16
  870.     pop  edi
  871. %endif
  872.     ret
  873. %endmacro
  874. %macro SADX4_CACHELINE_FUNC 5 ; width, height, cacheline, normal_ver, split_ver
  875. cglobal x264_pixel_sad_x4_%1x%2_cache%3_%5, 0,0
  876.     CHECK_SPLIT r1m, %1, %3
  877.     CHECK_SPLIT r2m, %1, %3
  878.     CHECK_SPLIT r3m, %1, %3
  879.     CHECK_SPLIT r4m, %1, %3
  880.     jmp x264_pixel_sad_x4_%1x%2_%4
  881. .split:
  882. %ifdef ARCH_X86_64
  883.     mov  r11, r6m
  884.     push r4
  885.     push r3
  886.     push r2
  887.     mov  r2, r1
  888.     mov  r1, FENC_STRIDE
  889.     mov  r3, r5
  890.     mov  r10, r0
  891.     call x264_pixel_sad_%1x%2_cache%3_%5
  892.     mov  [r11], eax
  893.     pop  r2
  894.     mov  r0, r10
  895.     call x264_pixel_sad_%1x%2_cache%3_%5
  896.     mov  [r11+4], eax
  897.     pop  r2
  898.     mov  r0, r10
  899.     call x264_pixel_sad_%1x%2_cache%3_%5
  900.     mov  [r11+8], eax
  901.     pop  r2
  902.     mov  r0, r10
  903.     call x264_pixel_sad_%1x%2_cache%3_%5
  904.     mov  [r11+12], eax
  905. %else
  906.     push edi
  907.     mov  edi, [esp+32]
  908.     push dword [esp+28]
  909.     push dword [esp+16]
  910.     push dword 16
  911.     push dword [esp+20]
  912.     call x264_pixel_sad_%1x%2_cache%3_%5
  913.     mov  ecx, [esp+32]
  914.     mov  [edi], eax
  915.     mov  [esp+8], ecx
  916.     call x264_pixel_sad_%1x%2_cache%3_%5
  917.     mov  ecx, [esp+36]
  918.     mov  [edi+4], eax
  919.     mov  [esp+8], ecx
  920.     call x264_pixel_sad_%1x%2_cache%3_%5
  921.     mov  ecx, [esp+40]
  922.     mov  [edi+8], eax
  923.     mov  [esp+8], ecx
  924.     call x264_pixel_sad_%1x%2_cache%3_%5
  925.     mov  [edi+12], eax
  926.     add  esp, 16
  927.     pop  edi
  928. %endif
  929.     ret
  930. %endmacro
  931. %macro SADX34_CACHELINE_FUNC 5
  932.     SADX3_CACHELINE_FUNC %1, %2, %3, %4, %5
  933.     SADX4_CACHELINE_FUNC %1, %2, %3, %4, %5
  934. %endmacro
  935. ; instantiate the aligned sads
  936. %ifndef ARCH_X86_64
  937. SAD16_CACHELINE_FUNC_MMX2  8, 32
  938. SAD16_CACHELINE_FUNC_MMX2 16, 32
  939. SAD8_CACHELINE_FUNC_MMX2   4, 32
  940. SAD8_CACHELINE_FUNC_MMX2   8, 32
  941. SAD8_CACHELINE_FUNC_MMX2  16, 32
  942. SAD16_CACHELINE_FUNC_MMX2  8, 64
  943. SAD16_CACHELINE_FUNC_MMX2 16, 64
  944. %endif ; !ARCH_X86_64
  945. SAD8_CACHELINE_FUNC_MMX2   4, 64
  946. SAD8_CACHELINE_FUNC_MMX2   8, 64
  947. SAD8_CACHELINE_FUNC_MMX2  16, 64
  948. %ifndef ARCH_X86_64
  949. SADX34_CACHELINE_FUNC 16, 16, 32, mmxext, mmxext
  950. SADX34_CACHELINE_FUNC 16,  8, 32, mmxext, mmxext
  951. SADX34_CACHELINE_FUNC  8, 16, 32, mmxext, mmxext
  952. SADX34_CACHELINE_FUNC  8,  8, 32, mmxext, mmxext
  953. SADX34_CACHELINE_FUNC 16, 16, 64, mmxext, mmxext
  954. SADX34_CACHELINE_FUNC 16,  8, 64, mmxext, mmxext
  955. %endif ; !ARCH_X86_64
  956. SADX34_CACHELINE_FUNC  8, 16, 64, mmxext, mmxext
  957. SADX34_CACHELINE_FUNC  8,  8, 64, mmxext, mmxext
  958. %ifndef ARCH_X86_64
  959. SAD16_CACHELINE_FUNC sse2, 8
  960. SAD16_CACHELINE_FUNC sse2, 16
  961. %assign i 1
  962. %rep 15
  963. SAD16_CACHELINE_LOOP_SSE2 i
  964. %assign i i+1
  965. %endrep
  966. SADX34_CACHELINE_FUNC 16, 16, 64, sse2, sse2
  967. SADX34_CACHELINE_FUNC 16,  8, 64, sse2, sse2
  968. %endif ; !ARCH_X86_64
  969. SAD16_CACHELINE_FUNC ssse3, 8
  970. SAD16_CACHELINE_FUNC ssse3, 16
  971. %assign i 1
  972. %rep 15
  973. SAD16_CACHELINE_LOOP_SSSE3 i
  974. %assign i i+1
  975. %endrep
  976. SADX34_CACHELINE_FUNC 16, 16, 64, sse2, ssse3
  977. SADX34_CACHELINE_FUNC 16,  8, 64, sse2, ssse3