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

Audio

开发平台:

Visual C++

  1. ;*****************************************************************************
  2. ;* pixel-sse2.asm: h264 encoder library
  3. ;*****************************************************************************
  4. ;* Copyright (C) 2005 x264 project
  5. ;*
  6. ;* Authors: Alex Izvorski <aizvorksi@gmail.com>
  7. ;*
  8. ;* This program is free software; you can redistribute it and/or modify
  9. ;* it under the terms of the GNU General Public License as published by
  10. ;* the Free Software Foundation; either version 2 of the License, or
  11. ;* (at your option) any later version.
  12. ;*
  13. ;* This program is distributed in the hope that it will be useful,
  14. ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. ;* GNU General Public License for more details.
  17. ;*
  18. ;* You should have received a copy of the GNU General Public License
  19. ;* along with this program; if not, write to the Free Software
  20. ;* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  21. ;*****************************************************************************
  22. BITS 64
  23. ;=============================================================================
  24. ; Macros and other preprocessor constants
  25. ;=============================================================================
  26. %include "amd64inc.asm"
  27. SECTION .rodata align=16
  28. pd_0000ffff: times 4 dd 0x0000ffff
  29. SECTION .text
  30. cglobal x264_pixel_sad_16x16_sse2
  31. cglobal x264_pixel_sad_16x8_sse2
  32. cglobal x264_pixel_ssd_16x16_sse2
  33. cglobal x264_pixel_ssd_16x8_sse2
  34. cglobal x264_pixel_satd_8x4_sse2
  35. cglobal x264_pixel_satd_8x8_sse2
  36. cglobal x264_pixel_satd_16x8_sse2
  37. cglobal x264_pixel_satd_8x16_sse2
  38. cglobal x264_pixel_satd_16x16_sse2
  39. %macro SAD_INC_4x16P_SSE2 0
  40.     movdqu  xmm1,   [rdx]
  41.     movdqu  xmm2,   [rdx+rcx]
  42.     lea     rdx,    [rdx+2*rcx]
  43.     movdqu  xmm3,   [rdx]
  44.     movdqu  xmm4,   [rdx+rcx]
  45.     psadbw  xmm1,   [rdi]
  46.     psadbw  xmm2,   [rdi+rsi]
  47.     lea     rdi,    [rdi+2*rsi]
  48.     psadbw  xmm3,   [rdi]
  49.     psadbw  xmm4,   [rdi+rsi]
  50.     lea     rdi,    [rdi+2*rsi]
  51.     lea     rdx,    [rdx+2*rcx]
  52.     paddw   xmm1,   xmm2
  53.     paddw   xmm3,   xmm4
  54.     paddw   xmm0,   xmm1
  55.     paddw   xmm0,   xmm3
  56. %endmacro
  57. %macro SAD_START_SSE2 0
  58. ;   mov     rdi, rdi            ; pix1
  59.     movsxd  rsi, esi            ; stride1
  60. ;   mov     rdx, rdx            ; pix2
  61.     movsxd  rcx, ecx            ; stride2
  62. %endmacro
  63. %macro SAD_END_SSE2 0
  64.     movdqa  xmm1, xmm0
  65.     psrldq  xmm0,  8
  66.     paddw   xmm0, xmm1
  67.     movd    eax,  xmm0
  68.     ret
  69. %endmacro
  70. ALIGN 16
  71. ;-----------------------------------------------------------------------------
  72. ;   int x264_pixel_sad_16x16_sse2 (uint8_t *, int, uint8_t *, int )
  73. ;-----------------------------------------------------------------------------
  74. x264_pixel_sad_16x16_sse2:
  75.     SAD_START_SSE2
  76.     movdqu xmm0, [rdx]
  77.     movdqu xmm1, [rdx+rcx]
  78.     lea    rdx,  [rdx+2*rcx]
  79.     movdqu xmm2, [rdx]
  80.     movdqu xmm3, [rdx+rcx]
  81.     lea    rdx,  [rdx+2*rcx]
  82.     psadbw xmm0, [rdi]
  83.     psadbw xmm1, [rdi+rsi]
  84.     lea    rdi,  [rdi+2*rsi]
  85.     movdqu xmm4, [rdx]
  86.     paddw  xmm0, xmm1
  87.     psadbw xmm2, [rdi]
  88.     psadbw xmm3, [rdi+rsi]
  89.     lea    rdi,  [rdi+2*rsi]
  90.     movdqu xmm5, [rdx+rcx]
  91.     lea    rdx,  [rdx+2*rcx]
  92.     paddw  xmm2, xmm3
  93.     movdqu xmm6, [rdx]
  94.     movdqu xmm7, [rdx+rcx]
  95.     lea    rdx,  [rdx+2*rcx]
  96.     paddw  xmm0, xmm2
  97.     psadbw xmm4, [rdi]
  98.     psadbw xmm5, [rdi+rsi]
  99.     lea    rdi,  [rdi+2*rsi]
  100.     movdqu xmm1, [rdx]
  101.     paddw  xmm4, xmm5
  102.     psadbw xmm6, [rdi]
  103.     psadbw xmm7, [rdi+rsi]
  104.     lea    rdi,  [rdi+2*rsi]
  105.     movdqu xmm2, [rdx+rcx]
  106.     lea    rdx,  [rdx+2*rcx]
  107.     paddw  xmm6, xmm7
  108.     movdqu xmm3, [rdx]
  109.     paddw  xmm0, xmm4
  110.     movdqu xmm4, [rdx+rcx]
  111.     lea    rdx,  [rdx+2*rcx]
  112.     paddw  xmm0, xmm6
  113.     psadbw xmm1, [rdi]
  114.     psadbw xmm2, [rdi+rsi]
  115.     lea    rdi,  [rdi+2*rsi]
  116.     movdqu xmm5, [rdx]
  117.     paddw  xmm1, xmm2
  118.     psadbw xmm3, [rdi]
  119.     psadbw xmm4, [rdi+rsi]
  120.     lea    rdi,  [rdi+2*rsi]
  121.     movdqu xmm6, [rdx+rcx]
  122.     lea    rdx,  [rdx+2*rcx]
  123.     paddw  xmm3, xmm4
  124.     movdqu xmm7, [rdx]
  125.     paddw  xmm0, xmm1
  126.     movdqu xmm1, [rdx+rcx]
  127.     paddw  xmm0, xmm3
  128.     psadbw xmm5, [rdi]
  129.     psadbw xmm6, [rdi+rsi]
  130.     lea    rdi,  [rdi+2*rsi]
  131.     paddw  xmm5, xmm6
  132.     psadbw xmm7, [rdi]
  133.     psadbw xmm1, [rdi+rsi]
  134.     paddw  xmm7, xmm1
  135.     paddw  xmm0, xmm5
  136.     paddw  xmm0, xmm7
  137.     SAD_END_SSE2
  138. ALIGN 16
  139. ;-----------------------------------------------------------------------------
  140. ;   int x264_pixel_sad_16x8_sse2 (uint8_t *, int, uint8_t *, int )
  141. ;-----------------------------------------------------------------------------
  142. x264_pixel_sad_16x8_sse2:
  143.     SAD_START_SSE2
  144.     pxor    xmm0,   xmm0
  145.     SAD_INC_4x16P_SSE2
  146.     SAD_INC_4x16P_SSE2
  147.     SAD_END_SSE2
  148. %macro SSD_INC_2x16P_SSE2 0
  149.     movdqu  xmm1,   [rdi]
  150.     movdqu  xmm2,   [rdx]
  151.     movdqu  xmm3,   [rdi+rsi]
  152.     movdqu  xmm4,   [rdx+rcx]
  153.     movdqa  xmm5,   xmm1
  154.     movdqa  xmm6,   xmm3
  155.     psubusb xmm1,   xmm2
  156.     psubusb xmm3,   xmm4
  157.     psubusb xmm2,   xmm5
  158.     psubusb xmm4,   xmm6
  159.     por     xmm1,   xmm2
  160.     por     xmm3,   xmm4
  161.     movdqa  xmm2,   xmm1
  162.     movdqa  xmm4,   xmm3
  163.     punpcklbw xmm1, xmm7
  164.     punpckhbw xmm2, xmm7
  165.     punpcklbw xmm3, xmm7
  166.     punpckhbw xmm4, xmm7
  167.     pmaddwd xmm1,   xmm1
  168.     pmaddwd xmm2,   xmm2
  169.     pmaddwd xmm3,   xmm3
  170.     pmaddwd xmm4,   xmm4
  171.     lea     rdi,    [rdi+2*rsi]
  172.     lea     rdx,    [rdx+2*rcx]
  173.     paddd   xmm1,   xmm2
  174.     paddd   xmm3,   xmm4
  175.     paddd   xmm0,   xmm1
  176.     paddd   xmm0,   xmm3
  177. %endmacro
  178. %macro SSD_INC_8x16P_SSE2 0
  179.     SSD_INC_2x16P_SSE2
  180.     SSD_INC_2x16P_SSE2
  181.     SSD_INC_2x16P_SSE2
  182.     SSD_INC_2x16P_SSE2
  183. %endmacro
  184. %macro SSD_START_SSE2 0
  185. ;   mov     rdi, rdi            ; pix1
  186.     movsxd  rsi, esi            ; stride1
  187. ;   mov     rdx, rdx            ; pix2
  188.     movsxd  rcx, ecx            ; stride2
  189.     pxor    xmm7,   xmm7        ; zero
  190.     pxor    xmm0,   xmm0        ; mm0 holds the sum
  191. %endmacro
  192. %macro SSD_END_SSE2 0
  193.     movdqa  xmm1,   xmm0
  194.     psrldq  xmm1,    8
  195.     paddd   xmm0,   xmm1
  196.     movdqa  xmm1,   xmm0
  197.     psrldq  xmm1,    4
  198.     paddd   xmm0,   xmm1
  199.     movd    eax,    xmm0
  200.     ret
  201. %endmacro
  202. ALIGN 16
  203. ;-----------------------------------------------------------------------------
  204. ;   int x264_pixel_ssd_16x16_sse2 (uint8_t *, int, uint8_t *, int )
  205. ;-----------------------------------------------------------------------------
  206. x264_pixel_ssd_16x16_sse2:
  207.     SSD_START_SSE2
  208.     SSD_INC_8x16P_SSE2
  209.     SSD_INC_8x16P_SSE2
  210.     SSD_END_SSE2
  211. ALIGN 16
  212. ;-----------------------------------------------------------------------------
  213. ;   int x264_pixel_ssd_16x8_sse2 (uint8_t *, int, uint8_t *, int )
  214. ;-----------------------------------------------------------------------------
  215. x264_pixel_ssd_16x8_sse2:
  216.     SSD_START_SSE2
  217.     SSD_INC_8x16P_SSE2
  218.     SSD_END_SSE2
  219. ; %1=(row2, row0) %2=(row3, row1) %3=junk
  220. ; output in %1=(row3, row0) and %3=(row2, row1)
  221. %macro HADAMARD4x4_SSE2 3
  222.     movdqa     %3, %1
  223.     paddw      %1, %2
  224.     psubw      %3, %2
  225.     movdqa     %2, %1
  226.     punpcklqdq %1, %3
  227.     punpckhqdq %2, %3
  228.     movdqa     %3, %1
  229.     paddw      %1, %2
  230.     psubw      %3, %2
  231. %endmacro
  232. ;;; two HADAMARD4x4_SSE2 running side-by-side
  233. %macro HADAMARD4x4_TWO_SSE2 6    ; a02 a13 junk1 b02 b13 junk2 (1=4 2=5 3=6)
  234.     movdqa     %3, %1
  235.     movdqa     %6, %4
  236.     paddw      %1, %2
  237.     paddw      %4, %5
  238.     psubw      %3, %2
  239.     psubw      %6, %5
  240.     movdqa     %2, %1
  241.     movdqa     %5, %4
  242.     punpcklqdq %1, %3
  243.     punpcklqdq %4, %6
  244.     punpckhqdq %2, %3
  245.     punpckhqdq %5, %6
  246.     movdqa     %3, %1
  247.     movdqa     %6, %4
  248.     paddw      %1, %2
  249.     paddw      %4, %5
  250.     psubw      %3, %2
  251.     psubw      %6, %5
  252. %endmacro
  253. %macro TRANSPOSE4x4_TWIST_SSE2 3    ; %1=(row3, row0) %2=(row2, row1) %3=junk, output in %1 and %2
  254.     movdqa     %3, %1
  255.     punpcklwd  %1, %2
  256.     punpckhwd  %2, %3             ; backwards because the high quadwords are already swapped
  257.     movdqa     %3, %1
  258.     punpckldq  %1, %2
  259.     punpckhdq  %3, %2
  260.     movdqa     %2, %1
  261.     punpcklqdq %1, %3
  262.     punpckhqdq %2, %3
  263. %endmacro
  264. ;;; two TRANSPOSE4x4_TWIST_SSE2 running side-by-side
  265. %macro TRANSPOSE4x4_TWIST_TWO_SSE2 6    ; a02 a13 junk1 b02 b13 junk2 (1=4 2=5 3=6)
  266.     movdqa     %3, %1
  267.     movdqa     %6, %4
  268.     punpcklwd  %1, %2
  269.     punpcklwd  %4, %5
  270.     punpckhwd  %2, %3
  271.     punpckhwd  %5, %6
  272.     movdqa     %3, %1
  273.     movdqa     %6, %4
  274.     punpckldq  %1, %2
  275.     punpckldq  %4, %5
  276.     punpckhdq  %3, %2
  277.     punpckhdq  %6, %5
  278.     movdqa     %2, %1
  279.     movdqa     %5, %4
  280.     punpcklqdq %1, %3
  281.     punpcklqdq %4, %6
  282.     punpckhqdq %2, %3
  283.     punpckhqdq %5, %6
  284. %endmacro
  285. ;;; loads the difference of two 4x4 blocks into xmm0,xmm1 and xmm4,xmm5 in interleaved-row order
  286. ;;; destroys xmm2, 3
  287. ;;; the value in xmm7 doesn't matter: it's only subtracted from itself
  288. %macro LOAD4x8_DIFF_SSE2 0
  289.     movq      xmm0, [rdi]
  290.     movq      xmm4, [rdx]
  291.     punpcklbw xmm0, xmm7
  292.     punpcklbw xmm4, xmm7
  293.     psubw     xmm0, xmm4
  294.     movq      xmm1, [rdi+rsi]
  295.     movq      xmm5, [rdx+rcx]
  296.     lea       rdi,  [rdi+2*rsi]
  297.     lea       rdx,  [rdx+2*rcx]
  298.     punpcklbw xmm1, xmm7
  299.     punpcklbw xmm5, xmm7
  300.     psubw     xmm1, xmm5
  301.     movq       xmm2, [rdi]
  302.     movq       xmm4, [rdx]
  303.     punpcklbw  xmm2, xmm7
  304.     punpcklbw  xmm4, xmm7
  305.     psubw      xmm2, xmm4
  306.     movdqa     xmm4, xmm0
  307.     punpcklqdq xmm0, xmm2        ; rows 0 and 2
  308.     punpckhqdq xmm4, xmm2        ; next 4x4 rows 0 and 2
  309.     movq       xmm3, [rdi+rsi]
  310.     movq       xmm5, [rdx+rcx]
  311.     lea        rdi,  [rdi+2*rsi]
  312.     lea        rdx,  [rdx+2*rcx]
  313.     punpcklbw  xmm3, xmm7
  314.     punpcklbw  xmm5, xmm7
  315.     psubw      xmm3, xmm5
  316.     movdqa     xmm5, xmm1
  317.     punpcklqdq xmm1, xmm3        ; rows 1 and 3
  318.     punpckhqdq xmm5, xmm3        ; next 4x4 rows 1 and 3
  319. %endmacro
  320. %macro SUM4x4_SSE2 4    ; 02 13 junk sum
  321.     pxor    %3, %3
  322.     psubw   %3, %1
  323.     pmaxsw  %1, %3
  324.     pxor    %3, %3
  325.     psubw   %3, %2
  326.     pmaxsw  %2, %3
  327.     paddusw %4, %1
  328.     paddusw %4, %2
  329. %endmacro
  330. ;;; two SUM4x4_SSE2 running side-by-side
  331. %macro SUM4x4_TWO_SSE2 7    ; a02 a13 junk1 b02 b13 junk2 (1=4 2=5 3=6) sum
  332.     pxor    %3, %3
  333.     pxor    %6, %6
  334.     psubw   %3, %1
  335.     psubw   %6, %4
  336.     pmaxsw  %1, %3
  337.     pmaxsw  %4, %6
  338.     pxor    %3, %3
  339.     pxor    %6, %6
  340.     psubw   %3, %2
  341.     psubw   %6, %5
  342.     pmaxsw  %2, %3
  343.     pmaxsw  %5, %6
  344.     paddusw %1, %2
  345.     paddusw %4, %5
  346.     paddusw %7, %1
  347.     paddusw %7, %4
  348. %endmacro
  349. %macro SUM_MM_SSE2 2    ; sum junk
  350.     ; each column sum of SATD is necessarily even, so we don't lose any precision by shifting first.
  351.     psrlw   %1, 1
  352.     movdqa  %2, %1
  353.     psrldq  %1, 2
  354.     paddusw %1, %2
  355.     pand    %1, [pd_0000ffff GLOBAL]
  356.     movdqa  %2, %1
  357.     psrldq  %1, 4
  358.     paddd   %1, %2
  359.     movdqa  %2, %1
  360.     psrldq  %1, 8
  361.     paddd   %1, %2
  362.     movd    eax,%1
  363. %endmacro
  364. %macro SATD_TWO_SSE2 0
  365.     LOAD4x8_DIFF_SSE2
  366.     HADAMARD4x4_TWO_SSE2        xmm0, xmm1, xmm2, xmm4, xmm5, xmm3
  367.     TRANSPOSE4x4_TWIST_TWO_SSE2 xmm0, xmm2, xmm1, xmm4, xmm3, xmm5
  368.     HADAMARD4x4_TWO_SSE2        xmm0, xmm2, xmm1, xmm4, xmm3, xmm5
  369.     SUM4x4_TWO_SSE2             xmm0, xmm1, xmm2, xmm4, xmm5, xmm3, xmm6
  370. %endmacro
  371. %macro SATD_START 0
  372. ;   mov     rdi, rdi            ; pix1
  373.     movsxd  rsi, esi            ; stride1
  374. ;   mov     rdx, rdx            ; pix2
  375.     movsxd  rcx, ecx            ; stride2
  376.     pxor    xmm6, xmm6
  377. %endmacro
  378. %macro SATD_END 0
  379.     SUM_MM_SSE2  xmm6, xmm7
  380.     ret
  381. %endmacro
  382. ALIGN 16
  383. ;-----------------------------------------------------------------------------
  384. ;   int x264_pixel_satd_16x16_sse2 (uint8_t *, int, uint8_t *, int )
  385. ;-----------------------------------------------------------------------------
  386. x264_pixel_satd_16x16_sse2:
  387.     SATD_START
  388.     mov     r8,  rdi
  389.     mov     r9,  rdx
  390.     SATD_TWO_SSE2
  391.     SATD_TWO_SSE2
  392.     SATD_TWO_SSE2
  393.     SATD_TWO_SSE2
  394.     lea     rdi, [r8+8]
  395.     lea     rdx, [r9+8]
  396.     SATD_TWO_SSE2
  397.     SATD_TWO_SSE2
  398.     SATD_TWO_SSE2
  399.     SATD_TWO_SSE2
  400.     SATD_END
  401. ALIGN 16
  402. ;-----------------------------------------------------------------------------
  403. ;   int x264_pixel_satd_8x16_sse2 (uint8_t *, int, uint8_t *, int )
  404. ;-----------------------------------------------------------------------------
  405. x264_pixel_satd_8x16_sse2:
  406.     SATD_START
  407.     SATD_TWO_SSE2
  408.     SATD_TWO_SSE2
  409.     SATD_TWO_SSE2
  410.     SATD_TWO_SSE2
  411.     SATD_END
  412. ALIGN 16
  413. ;-----------------------------------------------------------------------------
  414. ;   int x264_pixel_satd_16x8_sse2 (uint8_t *, int, uint8_t *, int )
  415. ;-----------------------------------------------------------------------------
  416. x264_pixel_satd_16x8_sse2:
  417.     SATD_START
  418.     mov     r8,  rdi
  419.     mov     r9,  rdx
  420.     SATD_TWO_SSE2
  421.     SATD_TWO_SSE2
  422.     lea     rdi, [r8+8]
  423.     lea     rdx, [r9+8]
  424.     SATD_TWO_SSE2
  425.     SATD_TWO_SSE2
  426.     SATD_END
  427. ALIGN 16
  428. ;-----------------------------------------------------------------------------
  429. ;   int x264_pixel_satd_8x8_sse2 (uint8_t *, int, uint8_t *, int )
  430. ;-----------------------------------------------------------------------------
  431. x264_pixel_satd_8x8_sse2:
  432.     SATD_START
  433.     SATD_TWO_SSE2
  434.     SATD_TWO_SSE2
  435.     SATD_END
  436. ALIGN 16
  437. ;-----------------------------------------------------------------------------
  438. ;   int x264_pixel_satd_8x4_sse2 (uint8_t *, int, uint8_t *, int )
  439. ;-----------------------------------------------------------------------------
  440. x264_pixel_satd_8x4_sse2:
  441.     SATD_START
  442.     SATD_TWO_SSE2
  443.     SATD_END