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

Audio

开发平台:

Visual C++

  1. ;*****************************************************************************
  2. ;* dct.asm: h264 encoder library
  3. ;*****************************************************************************
  4. ;* Copyright (C) 2003 x264 project
  5. ;* $Id: dct.asm,v 1.1 2004/06/03 19:27:07 fenrir Exp $
  6. ;*
  7. ;* Authors: Min Chen <chenm001.163.com> (converted to nasm)
  8. ;*          Laurent Aimar <fenrir@via.ecp.fr> (initial version)
  9. ;*          Christian Heine <sennindemokrit@gmx.net> (dct8/idct8 functions)
  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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  24. ;*****************************************************************************
  25. ;*****************************************************************************
  26. ;*                                                                           *
  27. ;*  Revision history:                                                        *
  28. ;*                                                                           *
  29. ;*  2004.04.28  portab all 4x4 function to nasm (CM)                         *
  30. ;*  2005.08.24  added mmxext optimized dct8/idct8 functions (CH)             *
  31. ;*                                                                           *
  32. ;*****************************************************************************
  33. BITS 32
  34. ;=============================================================================
  35. ; Macros and other preprocessor constants
  36. ;=============================================================================
  37. %include "i386inc.asm"
  38. %macro MMX_ZERO 1
  39.     pxor    %1, %1
  40. %endmacro
  41. %macro MMX_LOAD_DIFF_4P 5
  42.     movd        %1, %4
  43.     punpcklbw   %1, %3
  44.     movd        %2, %5
  45.     punpcklbw   %2, %3
  46.     psubw       %1, %2
  47. %endmacro
  48. %macro MMX_SUMSUB_BA 2
  49.     paddw   %1, %2
  50.     paddw   %2, %2
  51.     psubw   %2, %1
  52. %endmacro
  53. %macro MMX_SUMSUB_BADC 4
  54.     paddw   %1, %2
  55.     paddw   %3, %4
  56.     paddw   %2, %2
  57.     paddw   %4, %4
  58.     psubw   %2, %1
  59.     psubw   %4, %3
  60. %endmacro
  61. %macro MMX_SUMSUB2_AB 3
  62.     movq    %3, %1
  63.     paddw   %1, %1
  64.     paddw   %1, %2
  65.     psubw   %3, %2
  66.     psubw   %3, %2
  67. %endmacro
  68. %macro MMX_SUMSUBD2_AB 4
  69.     movq    %4, %1
  70.     movq    %3, %2
  71.     psraw   %2, $1
  72.     psraw   %4, $1
  73.     paddw   %1, %2
  74.     psubw   %4, %3
  75. %endmacro
  76. %macro SBUTTERFLYwd 3
  77.     movq        %3, %1
  78.     punpcklwd   %1, %2
  79.     punpckhwd   %3, %2
  80. %endmacro
  81. %macro SBUTTERFLYdq 3
  82.     movq        %3, %1
  83.     punpckldq   %1, %2
  84.     punpckhdq   %3, %2
  85. %endmacro
  86. ;-----------------------------------------------------------------------------
  87. ; input ABCD output ADTC
  88. ;-----------------------------------------------------------------------------
  89. %macro MMX_TRANSPOSE 5
  90.     SBUTTERFLYwd %1, %2, %5
  91.     SBUTTERFLYwd %3, %4, %2
  92.     SBUTTERFLYdq %1, %3, %4
  93.     SBUTTERFLYdq %5, %2, %3
  94. %endmacro
  95. %macro MMX_STORE_DIFF_4P 5
  96.     paddw       %1, %3
  97.     psraw       %1, $6
  98.     movd        %2, %5
  99.     punpcklbw   %2, %4
  100.     paddsw      %1, %2
  101.     packuswb    %1, %1
  102.     movd        %5, %1
  103. %endmacro
  104. ;=============================================================================
  105. ; Local Data (Read Only)
  106. ;=============================================================================
  107. SECTION_RODATA
  108. ;-----------------------------------------------------------------------------
  109. ; Various memory constants (trigonometric values or rounding values)
  110. ;-----------------------------------------------------------------------------
  111. ALIGN 16
  112. x264_mmx_1:        dw  1,  1,  1,  1
  113. x264_mmx_32:       dw 32, 32, 32, 32
  114. x264_mmx_PPNN:     dw  1,  1, -1, -1
  115. x264_mmx_PNPN:     dw  1, -1,  1, -1 
  116. x264_mmx_PNNP:     dw  1, -1, -1,  1 
  117. x264_mmx_PPPN:     dw  1,  1,  1, -1 
  118. x264_mmx_PPNP:     dw  1,  1, -1,  1 
  119. x264_mmx_2121:     dw  2,  1,  2,  1 
  120. x264_mmx_p2n2p1p1: dw  2, -2,  1,  1
  121. ;=============================================================================
  122. ; Code
  123. ;=============================================================================
  124. SECTION .text
  125. cglobal x264_dct4x4dc_mmxext
  126. ALIGN 16
  127. ;-----------------------------------------------------------------------------
  128. ;   void __cdecl dct4x4dc( int16_t d[4][4] )
  129. ;-----------------------------------------------------------------------------
  130. x264_dct4x4dc_mmxext:
  131.     mov     eax,        [esp+ 4]
  132.     movq    mm0,        [eax+ 0]
  133.     movq    mm1,        [eax+ 8]
  134.     movq    mm2,        [eax+16]
  135.     movq    mm3,        [eax+24]
  136.     picpush ebx
  137.     picgetgot ebx
  138.     MMX_SUMSUB_BADC     mm1, mm0, mm3, mm2          ; mm1=s01  mm0=d01  mm3=s23  mm2=d23
  139.     MMX_SUMSUB_BADC     mm3, mm1, mm2, mm0          ; mm3=s01+s23  mm1=s01-s23  mm2=d01+d23  mm0=d01-d23
  140.     MMX_TRANSPOSE       mm3, mm1, mm0, mm2, mm4     ; in: mm3, mm1, mm0, mm2  out: mm3, mm2, mm4, mm0 
  141.     MMX_SUMSUB_BADC     mm2, mm3, mm0, mm4          ; mm2=s01  mm3=d01  mm0=s23  mm4=d23
  142.     MMX_SUMSUB_BADC     mm0, mm2, mm4, mm3          ; mm0=s01+s23  mm2=s01-s23  mm4=d01+d23  mm3=d01-d23
  143.     MMX_TRANSPOSE       mm0, mm2, mm3, mm4, mm1     ; in: mm0, mm2, mm3, mm4  out: mm0, mm4, mm1, mm3
  144.     movq    mm6,        [x264_mmx_1 GOT_ebx]
  145.     paddw   mm0,        mm6
  146.     paddw   mm4,        mm6
  147.     psraw   mm0,        1
  148.     movq    [eax+ 0],   mm0
  149.     psraw   mm4,        1
  150.     movq    [eax+ 8],   mm4
  151.     paddw   mm1,        mm6
  152.     paddw   mm3,        mm6
  153.     psraw   mm1,        1
  154.     movq    [eax+16],   mm1
  155.     psraw   mm3,        1
  156.     movq    [eax+24],   mm3
  157.     picpop  ebx
  158.     ret
  159. cglobal x264_idct4x4dc_mmxext
  160. ALIGN 16
  161. ;-----------------------------------------------------------------------------
  162. ;   void __cdecl x264_idct4x4dc_mmxext( int16_t d[4][4] )
  163. ;-----------------------------------------------------------------------------
  164. x264_idct4x4dc_mmxext:
  165.     mov     eax, [esp+ 4]
  166.     movq    mm0, [eax+ 0]
  167.     movq    mm1, [eax+ 8]
  168.     movq    mm2, [eax+16]
  169.     movq    mm3, [eax+24]
  170.     MMX_SUMSUB_BADC     mm1, mm0, mm3, mm2          ; mm1=s01  mm0=d01  mm3=s23  mm2=d23
  171.     MMX_SUMSUB_BADC     mm3, mm1, mm2, mm0          ; mm3=s01+s23 mm1=s01-s23 mm2=d01+d23 mm0=d01-d23
  172.     MMX_TRANSPOSE       mm3, mm1, mm0, mm2, mm4     ; in: mm3, mm1, mm0, mm2  out: mm3, mm2, mm4, mm0 
  173.     MMX_SUMSUB_BADC     mm2, mm3, mm0, mm4          ; mm2=s01  mm3=d01  mm0=s23  mm4=d23
  174.     MMX_SUMSUB_BADC     mm0, mm2, mm4, mm3          ; mm0=s01+s23  mm2=s01-s23  mm4=d01+d23  mm3=d01-d23
  175.     MMX_TRANSPOSE       mm0, mm2, mm3, mm4, mm1     ; in: mm0, mm2, mm3, mm4  out: mm0, mm4, mm1, mm3
  176.     movq    [eax+ 0],   mm0
  177.     movq    [eax+ 8],   mm4
  178.     movq    [eax+16],   mm1
  179.     movq    [eax+24],   mm3
  180.     ret
  181. cglobal x264_sub4x4_dct_mmxext
  182. ALIGN 16
  183. ;-----------------------------------------------------------------------------
  184. ;   void __cdecl x264_sub4x4_dct_mmxext( int16_t dct[4][4], uint8_t *pix1, int i_pix1, uint8_t *pix2, int i_pix2 )
  185. ;-----------------------------------------------------------------------------
  186. x264_sub4x4_dct_mmxext:
  187.     push    ebx
  188.     mov     eax, [esp+12]   ; pix1
  189.     mov     ebx, [esp+16]   ; i_pix1
  190.     mov     ecx, [esp+20]   ; pix2
  191.     mov     edx, [esp+24]   ; i_pix2
  192.     MMX_ZERO    mm7
  193.     ; Load 4 lines
  194.     MMX_LOAD_DIFF_4P    mm0, mm6, mm7, [eax      ], [ecx]
  195.     MMX_LOAD_DIFF_4P    mm1, mm6, mm7, [eax+ebx  ], [ecx+edx]
  196.     MMX_LOAD_DIFF_4P    mm2, mm6, mm7, [eax+ebx*2], [ecx+edx*2]
  197.     add     eax, ebx
  198.     add     ecx, edx
  199.     MMX_LOAD_DIFF_4P    mm3, mm6, mm7, [eax+ebx*2], [ecx+edx*2]
  200.     MMX_SUMSUB_BADC     mm3, mm0, mm2, mm1          ; mm3=s03  mm0=d03  mm2=s12  mm1=d12
  201.     MMX_SUMSUB_BA       mm2, mm3                    ; mm2=s03+s12      mm3=s03-s12
  202.     MMX_SUMSUB2_AB      mm0, mm1, mm4               ; mm0=2.d03+d12    mm4=d03-2.d12
  203.     ; transpose in: mm2, mm0, mm3, mm4, out: mm2, mm4, mm1, mm3
  204.     MMX_TRANSPOSE       mm2, mm0, mm3, mm4, mm1
  205.     MMX_SUMSUB_BADC     mm3, mm2, mm1, mm4          ; mm3=s03  mm2=d03  mm1=s12  mm4=d12
  206.     MMX_SUMSUB_BA       mm1, mm3                    ; mm1=s03+s12      mm3=s03-s12
  207.     MMX_SUMSUB2_AB      mm2, mm4, mm0               ; mm2=2.d03+d12    mm0=d03-2.d12
  208.     ; transpose in: mm1, mm2, mm3, mm0, out: mm1, mm0, mm4, mm3
  209.     MMX_TRANSPOSE       mm1, mm2, mm3, mm0, mm4
  210.     mov     eax, [esp+ 8]   ; dct
  211.     movq    [eax+ 0],   mm1
  212.     movq    [eax+ 8],   mm0
  213.     movq    [eax+16],   mm4
  214.     movq    [eax+24],   mm3
  215.     pop     ebx
  216.     ret
  217. cglobal x264_add4x4_idct_mmxext
  218. ALIGN 16
  219. ;-----------------------------------------------------------------------------
  220. ;   void __cdecl x264_add4x4_idct_mmxext( uint8_t *p_dst, int i_dst, int16_t dct[4][4] )
  221. ;-----------------------------------------------------------------------------
  222. x264_add4x4_idct_mmxext:
  223.     ; Load dct coeffs
  224.     mov     eax, [esp+12]   ; dct
  225.     movq    mm0, [eax+ 0]
  226.     movq    mm4, [eax+ 8]
  227.     movq    mm3, [eax+16]
  228.     movq    mm1, [eax+24]
  229.     
  230.     mov     eax, [esp+ 4]   ; p_dst
  231.     mov     ecx, [esp+ 8]   ; i_dst
  232.     lea     edx, [ecx+ecx*2]
  233.     picpush ebx
  234.     picgetgot ebx
  235.     ; out:mm0, mm1, mm2, mm3
  236.     MMX_TRANSPOSE       mm0, mm4, mm3, mm1, mm2
  237.     MMX_SUMSUB_BA       mm2, mm0                        ; mm2=s02  mm0=d02
  238.     MMX_SUMSUBD2_AB     mm1, mm3, mm5, mm4              ; mm1=s13  mm4=d13 ( well 1 + 3>>1 and 1>>1 + 3)
  239.     MMX_SUMSUB_BADC     mm1, mm2, mm4, mm0              ; mm1=s02+s13  mm2=s02-s13  mm4=d02+d13  mm0=d02-d13
  240.     ; in: mm1, mm4, mm0, mm2  out: mm1, mm2, mm3, mm0
  241.     MMX_TRANSPOSE       mm1, mm4, mm0, mm2, mm3
  242.     MMX_SUMSUB_BA       mm3, mm1                        ; mm3=s02  mm1=d02
  243.     MMX_SUMSUBD2_AB     mm2, mm0, mm5, mm4              ; mm2=s13  mm4=d13 ( well 1 + 3>>1 and 1>>1 + 3)
  244.     MMX_SUMSUB_BADC     mm2, mm3, mm4, mm1              ; mm2=s02+s13  mm3=s02-s13  mm4=d02+d13  mm1=d02-d13
  245.     MMX_ZERO            mm7
  246.     movq                mm6, [x264_mmx_32 GOT_ebx]
  247.     
  248.     MMX_STORE_DIFF_4P   mm2, mm0, mm6, mm7, [eax]
  249.     MMX_STORE_DIFF_4P   mm4, mm0, mm6, mm7, [eax+ecx]
  250.     MMX_STORE_DIFF_4P   mm1, mm0, mm6, mm7, [eax+ecx*2]
  251.     MMX_STORE_DIFF_4P   mm3, mm0, mm6, mm7, [eax+edx]
  252.     picpop  ebx
  253.     ret
  254. ; =============================================================================
  255. ; 8x8 Transform
  256. ; =============================================================================
  257. ; -----------------------------------------------------------------------------
  258. ; input 2x8 unsigned bytes (%5,%6), zero (%7) output: difference (%1,%2)
  259. ; -----------------------------------------------------------------------------
  260. %macro MMX_LOAD_DIFF_8P 7
  261.     movq            %1, %5
  262.     movq            %2, %1
  263.     punpcklbw       %1, %7
  264.     punpckhbw       %2, %7
  265.     movq            %3, %6
  266.     movq            %4, %3
  267.     punpcklbw       %3, %7
  268.     punpckhbw       %4, %7
  269.     psubw           %1, %3
  270.     psubw           %2, %4
  271. %endmacro
  272.  
  273. %macro MMX_LOADSUMSUB 4     ; returns %1=%3+%4, %2=%3-%4
  274.     movq            %2, %3
  275.     movq            %1, %4
  276.     MMX_SUMSUB_BA   %1, %2
  277. %endmacro
  278. %macro MMX_STORE_DIFF_8P 6
  279.     movq            %1, %3
  280.     movq            %2, %1
  281.     punpcklbw       %1, %6
  282.     punpckhbw       %2, %6
  283.     paddw           %1, %4
  284.     paddw           %2, %5
  285.     packuswb        %1, %2
  286.     movq            %3, %1
  287. %endmacro
  288. cglobal x264_pixel_sub_8x8_mmx
  289. cglobal x264_xdct8_mmxext
  290. cglobal x264_ydct8_mmx
  291. cglobal x264_xidct8_mmxext
  292. cglobal x264_yidct8_mmx
  293. cglobal x264_pixel_add_8x8_mmx
  294. ALIGN 16
  295. ;-----------------------------------------------------------------------------
  296. ;   void __cdecl x264_pixel_sub_8x8_mmx( int16_t *diff, uint8_t *pix1, int i_pix1, uint8_t *pix2, int i_pix2 );
  297. ;-----------------------------------------------------------------------------
  298. x264_pixel_sub_8x8_mmx:
  299.     push        ebx
  300.     push        ebp
  301.     mov         ebp, [esp+12]           ; diff
  302.     mov         eax, [esp+16]           ; pix1
  303.     mov         ebx, [esp+20]           ; i_pix1
  304.     mov         ecx, [esp+24]           ; pix2
  305.     mov         edx, [esp+28]           ; i_pix2
  306.     MMX_ZERO    mm7
  307.     %assign disp 0
  308.     %rep  8
  309.     MMX_LOAD_DIFF_8P mm0, mm1, mm2, mm3, [eax], [ecx], mm7
  310.     movq        [ebp+disp], mm0
  311.     movq        [ebp+disp+8], mm1
  312.     add         eax, ebx
  313.     add         ecx, edx
  314.     %assign disp disp+16
  315.     %endrep
  316.     pop         ebp
  317.     pop         ebx
  318.     ret
  319. ALIGN 16
  320. ;-----------------------------------------------------------------------------
  321. ;   void __cdecl x264_xdct8_mmxext( int16_t dest[8][8] );
  322. ;-----------------------------------------------------------------------------
  323. x264_xdct8_mmxext:
  324.     mov         eax, [esp+04]           ; dest
  325.     picpush     ebx
  326.     picgetgot   ebx
  327.     movq        mm5, [x264_mmx_PPNN GOT_ebx]
  328.     movq        mm6, [x264_mmx_PNNP GOT_ebx]
  329.     movq        mm4, [x264_mmx_PPPN GOT_ebx]
  330.     movq        mm7, [x264_mmx_PPNP GOT_ebx]
  331.     ;-------------------------------------------------------------------------
  332.     ; horizontal dct ( compute 1 row at a time -> 8 loops )
  333.     ;-------------------------------------------------------------------------
  334.     %assign disp 0
  335.     %rep 8
  336.     
  337.     movq        mm0, [eax+disp]
  338.     movq        mm1, [eax+disp+8]
  339.     pshufw      mm2, mm1, 00011011b
  340.     movq        mm1, mm0
  341.     paddw       mm0, mm2                ; (low)s07/s16/d25/s34(high)
  342.     psubw       mm1, mm2                ; (low)d07/d16/d25/d34(high)
  343.     pshufw      mm2, mm0, 00011011b     ; (low)s34/s25/s16/s07(high)
  344.     pmullw      mm0, mm5                ; (low)s07/s16/-s25/-s34(high)
  345.     paddw       mm0, mm2                ; (low)a0/a1/a3/a2(high)
  346.     movq        mm3, mm1
  347.     psraw       mm1, 1                  ; (low)d07/d16/d25/d34(high) (x>>1)
  348.     pshufw      mm2, mm3, 10110001b     ; (low)d16/d07/d34/d25(high)
  349.     paddw       mm1, mm3                ; (low)d07/d16/d25/d34(high) (x+(x>>1))
  350.     pshufw      mm3, mm2, 00011011b     ; (low)d25/d34/d07/d16(high)
  351.     pmullw      mm2, mm5                ; (low)d16/d07/-d34/-d25(high)
  352.     pmullw      mm1, mm6                ; (low)d07/-d16/-d25/d34(high) (x+(x>>1))
  353.     paddw       mm3, mm2
  354.     paddw       mm1, mm3                ; (low)a4/a6/a5/a7(high)
  355.     pshufw      mm2, mm0, 11001001b     ; (low)a1/a3/a0/a2(high)
  356.     pshufw      mm0, mm0, 10011100b     ; (low)a0/a2/a1/a3(high)
  357.     pmullw      mm2, [x264_mmx_2121 GOT_ebx]
  358.     pmullw      mm0, mm5                ; (low)a0/a2/-a1/-a3(high)
  359.     psraw       mm2, 1                  ; (low)a1/a3>>1/a0/a2>>1(high)
  360.     paddw       mm0, mm2                ; (low)dst0/dst2/dst4/dst6(high)
  361.     pshufw      mm1, mm1, 00100111b     ; (low)a7/a6/a5/a4(high)
  362.     pshufw      mm2, mm1, 00011011b     ; (low)a4/a5/a6/a7(high)
  363.     psraw       mm1, 2                  ; (low)a7>>2/a6>>2/a5>>2/a4>>2(high)
  364.     pmullw      mm2, mm4                ; (low)a4/a5/a6/-a7(high)
  365.     pmullw      mm1, mm7                ; (low)a7>>2/a6>>2/-a5>>2/a4>>2(high)
  366.     paddw       mm1, mm2                ; (low)dst1/dst3/dst5/dst7(high)
  367.     movq        mm2, mm0
  368.     punpcklwd   mm0, mm1                ; (low)dst0/dst1/dst2/dst3(high)
  369.     punpckhwd   mm2, mm1                ; (low)dst4/dst5/dst6/dst7(high)
  370.     movq        [eax+disp], mm0
  371.     movq        [eax+disp+8], mm2
  372.     %assign disp disp+16
  373.     %endrep
  374.     picpop      ebx
  375.     ret
  376. ALIGN 16
  377. ;-----------------------------------------------------------------------------
  378. ;   void __cdecl x264_ydct8_mmx( int16_t dest[8][8] );
  379. ;-----------------------------------------------------------------------------
  380. x264_ydct8_mmx:
  381.     mov         eax, [esp+04]           ; dest
  382.     ;-------------------------------------------------------------------------
  383.     ; vertical dct ( compute 4 columns at a time -> 2 loops )
  384.     ;-------------------------------------------------------------------------
  385.     %assign disp 0
  386.     %rep 2
  387.     
  388.     MMX_LOADSUMSUB  mm2, mm3, [eax+disp+0*16], [eax+disp+7*16] ; mm2 = s07, mm3 = d07
  389.     MMX_LOADSUMSUB  mm1, mm5, [eax+disp+1*16], [eax+disp+6*16] ; mm1 = s16, mm5 = d16
  390.     MMX_LOADSUMSUB  mm0, mm6, [eax+disp+2*16], [eax+disp+5*16] ; mm0 = s25, mm6 = d25
  391.     MMX_LOADSUMSUB  mm4, mm7, [eax+disp+3*16], [eax+disp+4*16] ; mm4 = s34, mm7 = d34
  392.     MMX_SUMSUB_BA   mm4, mm2        ; mm4 = a0, mm2 = a2
  393.     MMX_SUMSUB_BA   mm0, mm1        ; mm0 = a1, mm1 = a3
  394.     MMX_SUMSUB_BA   mm0, mm4        ; mm0 = dst0, mm1 = dst4
  395.     movq    [eax+disp+0*16], mm0
  396.     movq    [eax+disp+4*16], mm4
  397.     movq    mm0, mm1         ; a3
  398.     psraw   mm0, 1           ; a3>>1
  399.     paddw   mm0, mm2         ; a2 + (a3>>1)
  400.     psraw   mm2, 1           ; a2>>1
  401.     psubw   mm2, mm1         ; (a2>>1) - a3
  402.     movq    [eax+disp+2*16], mm0
  403.     movq    [eax+disp+6*16], mm2
  404.     movq    mm0, mm6
  405.     psraw   mm0, 1
  406.     paddw   mm0, mm6         ; d25+(d25>>1)
  407.     movq    mm1, mm3
  408.     psubw   mm1, mm7         ; a5 = d07-d34-(d25+(d25>>1))
  409.     psubw   mm1, mm0
  410.     movq    mm0, mm5
  411.     psraw   mm0, 1
  412.     paddw   mm0, mm5         ; d16+(d16>>1)
  413.     movq    mm2, mm3
  414.     paddw   mm2, mm7         ; a6 = d07+d34-(d16+(d16>>1))
  415.     psubw   mm2, mm0
  416.     movq    mm0, mm3
  417.     psraw   mm0, 1
  418.     paddw   mm0, mm3         ; d07+(d07>>1)
  419.     paddw   mm0, mm5
  420.     paddw   mm0, mm6         ; a4 = d16+d25+(d07+(d07>>1))
  421.     movq    mm3, mm7
  422.     psraw   mm3, 1
  423.     paddw   mm3, mm7         ; d34+(d34>>1)
  424.     paddw   mm3, mm5
  425.     psubw   mm3, mm6         ; a7 = d16-d25+(d34+(d34>>1))
  426.     movq    mm7, mm3
  427.     psraw   mm7, 2
  428.     paddw   mm7, mm0         ; a4 + (a7>>2)
  429.     movq    mm6, mm2
  430.     psraw   mm6, 2
  431.     paddw   mm6, mm1         ; a5 + (a6>>2)
  432.     psraw   mm0, 2
  433.     psraw   mm1, 2
  434.     psubw   mm0, mm3         ; (a4>>2) - a7
  435.     psubw   mm2, mm1         ; a6 - (a5>>2)
  436.     movq    [eax+disp+1*16], mm7
  437.     movq    [eax+disp+3*16], mm6
  438.     movq    [eax+disp+5*16], mm2
  439.     movq    [eax+disp+7*16], mm0
  440.     %assign disp disp+8
  441.     %endrep
  442.     ret
  443. ALIGN 16
  444. ;-----------------------------------------------------------------------------
  445. ;   void __cdecl x264_xidct8_mmxext( int16_t dest[8][8] );
  446. ;-----------------------------------------------------------------------------
  447. x264_xidct8_mmxext:
  448.     mov         eax, [esp+04]           ; dest
  449.     picpush     ebx
  450.     picgetgot   ebx
  451.     movq        mm4, [x264_mmx_PPNN GOT_ebx]
  452.     movq        mm5, [x264_mmx_PNPN GOT_ebx]
  453.     movq        mm6, [x264_mmx_PPNP GOT_ebx]
  454.     movq        mm7, [x264_mmx_PPPN GOT_ebx]
  455.     ;-------------------------------------------------------------------------
  456.     ; horizontal idct ( compute 1 row at a time -> 8 loops )
  457.     ;-------------------------------------------------------------------------
  458.     %assign disp 0
  459.     %rep 8
  460.     pshufw      mm0, [eax+disp], 11011000b      ; (low)d0,d2,d1,d3(high)
  461.     pshufw      mm2, [eax+disp+8], 11011000b    ; (low)d4,d6,d5,d7(high)
  462.     movq        mm1, mm0
  463.     punpcklwd   mm0, mm2                ; (low)d0,d4,d2,d6(high)
  464.     punpckhwd   mm1, mm2                ; (low)d1,d5,d3,d7(high)
  465.     pshufw      mm2, mm0, 10110001b     ; (low)d4,d0,d6,d2(high)
  466.     pmullw      mm0, [x264_mmx_p2n2p1p1 GOT_ebx]; (low)2*d0,-2*d4,d2,d6(high)
  467.     pmullw      mm2, mm6                ; (low)d4,d0,-d6,d2(high)
  468.     psraw       mm0, 1                  ; (low)d0,-d4,d2>>1,d6>>1(high)
  469.     paddw       mm0, mm2                ; (low)e0,e2,e4,e6(high)
  470.     movq        mm3, mm1                ; (low)d1,d5,d3,d7(high)
  471.     psraw       mm1, 1                  ; (low)d1>>1,d5>>1,d3>>1,d7>>1(high)
  472.     pshufw      mm2, mm3, 10110001b     ; (low)d5,d1,d7,d3(high)
  473.     paddw       mm1, mm3                ; (low)d1+(d1>>1),d5+(d5>>1),d3+(d3>>1),d7+(d7>>1)(high)
  474.     pshufw      mm3, mm2, 00011011b     ; (low)d3,d7,d1,d5(high)
  475.     pmullw      mm1, mm4                ; (low)d1+(d1>>1),d5+(d5>>1),-d3-(d3>>1),-d7-(d7>>1)(high)
  476.     pmullw      mm2, mm5                ; (low)d5,-d1,d7,-d3(high)
  477.     paddw       mm1, mm3
  478.     paddw       mm1, mm2                ; (low)e7,e5,e3,e1(high)
  479.     pshufw      mm2, mm0, 00011011b     ; (low)e6,e4,e2,e0(high)
  480.     pmullw      mm0, mm4                ; (low)e0,e2,-e4,-e6(high)
  481.     pshufw      mm3, mm1, 00011011b     ; (low)e1,e3,e5,e7(high)
  482.     psraw       mm1, 2                  ; (low)e7>>2,e5>>2,e3>>2,e1>>2(high)
  483.     pmullw      mm3, mm6                ; (low)e1,e3,-e5,e7(high)
  484.     pmullw      mm1, mm7                ; (low)e7>>2,e5>>2,e3>>2,-e1>>2(high)
  485.     paddw       mm0, mm2                ; (low)f0,f2,f4,f6(high)
  486.     paddw       mm1, mm3                ; (low)f1,f3,f5,f7(high)
  487.     pshufw      mm3, mm0, 00011011b     ; (low)f6,f4,f2,f0(high)
  488.     pshufw      mm2, mm1, 00011011b     ; (low)f7,f5,f3,f1(high)
  489.     psubw       mm3, mm1
  490.     paddw       mm0, mm2
  491.     movq        [eax+disp], mm0
  492.     movq        [eax+disp+8], mm3
  493.     %assign disp disp+16
  494.     %endrep
  495.     picpop      ebx
  496.     ret
  497. ALIGN 16
  498. ;-----------------------------------------------------------------------------
  499. ;   void __cdecl x264_yidct8_mmx( int16_t dest[8][8] );
  500. ;-----------------------------------------------------------------------------
  501. x264_yidct8_mmx:
  502.     mov         eax, [esp+04]           ; dest
  503.     ;-------------------------------------------------------------------------
  504.     ; vertical idct ( compute 4 columns at a time -> 2 loops )
  505.     ;-------------------------------------------------------------------------
  506.     %assign disp 0
  507.     %rep 2
  508.     movq        mm1, [eax+disp+1*16]    ; mm1 = d1
  509.     movq        mm3, [eax+disp+3*16]    ; mm3 = d3
  510.     movq        mm5, [eax+disp+5*16]    ; mm5 = d5
  511.     movq        mm7, [eax+disp+7*16]    ; mm7 = d7
  512.     movq        mm4, mm7
  513.     psraw       mm4, 1
  514.     movq        mm0, mm5
  515.     psubw       mm0, mm7
  516.     psubw       mm0, mm4
  517.     psubw       mm0, mm3                ; mm0 = e1
  518.     movq        mm6, mm3
  519.     psraw       mm6, 1
  520.     movq        mm2, mm7
  521.     psubw       mm2, mm6
  522.     psubw       mm2, mm3
  523.     paddw       mm2, mm1                ; mm2 = e3
  524.     movq        mm4, mm5
  525.     psraw       mm4, 1
  526.     paddw       mm4, mm5
  527.     paddw       mm4, mm7
  528.     psubw       mm4, mm1                ; mm4 = e5
  529.     movq        mm6, mm1
  530.     psraw       mm6, 1
  531.     paddw       mm6, mm1
  532.     paddw       mm6, mm5
  533.     paddw       mm6, mm3                ; mm6 = e7
  534.     movq        mm1, mm0
  535.     movq        mm3, mm4
  536.     movq        mm5, mm2
  537.     movq        mm7, mm6
  538.     psraw       mm6, 2
  539.     psraw       mm3, 2
  540.     psraw       mm5, 2
  541.     psraw       mm0, 2
  542.     paddw       mm1, mm6                ; mm1 = f1
  543.     paddw       mm3, mm2                ; mm3 = f3
  544.     psubw       mm5, mm4                ; mm5 = f5
  545.     psubw       mm7, mm0                ; mm7 = f7
  546.     movq        mm2, [eax+disp+2*16]    ; mm2 = d2
  547.     movq        mm6, [eax+disp+6*16]    ; mm6 = d6
  548.     movq        mm4, mm2
  549.     movq        mm0, mm6
  550.     psraw       mm4, 1
  551.     psraw       mm6, 1
  552.     psubw       mm4, mm0                ; mm4 = a4
  553.     paddw       mm6, mm2                ; mm6 = a6
  554.     movq        mm2, [eax+disp+0*16]    ; mm2 = d0
  555.     movq        mm0, [eax+disp+4*16]    ; mm0 = d4
  556.     MMX_SUMSUB_BA   mm0, mm2                ; mm0 = a0, mm2 = a2
  557.     MMX_SUMSUB_BA   mm6, mm0                ; mm6 = f0, mm0 = f6
  558.     MMX_SUMSUB_BA   mm4, mm2                ; mm4 = f2, mm2 = f4
  559.     MMX_SUMSUB_BA   mm7, mm6                ; mm7 = g0, mm6 = g7
  560.     MMX_SUMSUB_BA   mm5, mm4                ; mm5 = g1, mm4 = g6
  561.     MMX_SUMSUB_BA   mm3, mm2                ; mm3 = g2, mm2 = g5
  562.     MMX_SUMSUB_BA   mm1, mm0                ; mm1 = g3, mm0 = g4
  563.     psraw       mm7, 6
  564.     psraw       mm6, 6
  565.     psraw       mm5, 6
  566.     psraw       mm4, 6
  567.     psraw       mm3, 6
  568.     psraw       mm2, 6
  569.     psraw       mm1, 6
  570.     psraw       mm0, 6
  571.     movq        [eax+disp+0*16], mm7
  572.     movq        [eax+disp+1*16], mm5
  573.     movq        [eax+disp+2*16], mm3
  574.     movq        [eax+disp+3*16], mm1
  575.     movq        [eax+disp+4*16], mm0
  576.     movq        [eax+disp+5*16], mm2
  577.     movq        [eax+disp+6*16], mm4
  578.     movq        [eax+disp+7*16], mm6
  579.     %assign disp disp+8
  580.     %endrep
  581.     ret
  582. ALIGN 16
  583. ;-----------------------------------------------------------------------------
  584. ;   void __cdecl x264_pixel_add_8x8_mmx( unit8_t *dst, int i_dst, int16_t src[8][8] );
  585. ;-----------------------------------------------------------------------------
  586. x264_pixel_add_8x8_mmx:
  587.     mov         eax, [esp+04]       ; dst
  588.     mov         ecx, [esp+08]       ; i_dst
  589.     mov         edx, [esp+12]       ; src
  590.     MMX_ZERO    mm7
  591.     %assign disp 0
  592.     %rep 8
  593.     MMX_STORE_DIFF_8P   mm0, mm1, [eax], [edx+disp], [edx+disp+8], mm7
  594.     add         eax, ecx
  595.     %assign disp disp+16
  596.     %endrep
  597.     ret