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

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. ;*****************************************************************************
  2. ;* dct-a.asm: h264 encoder library
  3. ;*****************************************************************************
  4. ;* Copyright (C) 2003-2008 x264 project
  5. ;*
  6. ;* Authors: Holger Lubitz <holger@lubitz.org>
  7. ;*          Loren Merritt <lorenm@u.washington.edu>
  8. ;*          Laurent Aimar <fenrir@via.ecp.fr>
  9. ;*          Min Chen <chenm001.163.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. pw_32_0: times 4 dw 32
  29.          times 4 dw 0
  30. pw_32: times 8 dw 32
  31. pw_8000: times 8 dw 0x8000
  32. hsub_mul: times 8 db 1, -1
  33. pb_sub4frame:   db 0,1,4,8,5,2,3,6,9,12,13,10,7,11,14,15
  34. pb_sub4field:   db 0,4,1,8,12,5,9,13,2,6,10,14,3,7,11,15
  35. pb_subacmask:   dw 0,-1,-1,-1,-1,-1,-1,-1
  36. pb_scan4framea: db 12,13,6,7,14,15,0,1,8,9,2,3,4,5,10,11
  37. pb_scan4frameb: db 0,1,8,9,2,3,4,5,10,11,12,13,6,7,14,15
  38. pb_idctdc_unpack: db 0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3
  39. pb_idctdc_unpack2: db 4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7
  40. pb_1: times 16 db 1
  41. pw_1: times 8 dw 1
  42. SECTION .text
  43. %macro WALSH4_1D 5
  44.     SUMSUB_BADC m%4, m%3, m%2, m%1, m%5
  45.     SUMSUB_BADC m%4, m%2, m%3, m%1, m%5
  46.     SWAP %1, %4, %3
  47. %endmacro
  48. %macro SUMSUB_17BIT 4 ; a, b, tmp, 0x8000
  49.     movq  m%3, m%4
  50.     pxor  m%1, m%4
  51.     psubw m%3, m%2
  52.     pxor  m%2, m%4
  53.     pavgw m%3, m%1
  54.     pavgw m%2, m%1
  55.     pxor  m%3, m%4
  56.     pxor  m%2, m%4
  57.     SWAP %1, %2, %3
  58. %endmacro
  59. INIT_MMX
  60. ;-----------------------------------------------------------------------------
  61. ; void x264_dct4x4dc_mmx( int16_t d[4][4] )
  62. ;-----------------------------------------------------------------------------
  63. cglobal x264_dct4x4dc_mmx, 1,1
  64.     movq   m3, [r0+24]
  65.     movq   m2, [r0+16]
  66.     movq   m1, [r0+ 8]
  67.     movq   m0, [r0+ 0]
  68.     movq   m7, [pw_8000 GLOBAL] ; convert to unsigned and back, so that pavgw works
  69.     WALSH4_1D  0,1,2,3,4
  70.     TRANSPOSE4x4W 0,1,2,3,4
  71.     SUMSUB_BADC m1, m0, m3, m2, m4
  72.     SWAP 0, 1
  73.     SWAP 2, 3
  74.     SUMSUB_17BIT 0,2,4,7
  75.     SUMSUB_17BIT 1,3,5,7
  76.     movq  [r0+0], m0
  77.     movq  [r0+8], m2
  78.     movq [r0+16], m3
  79.     movq [r0+24], m1
  80.     RET
  81. ;-----------------------------------------------------------------------------
  82. ; void x264_idct4x4dc_mmx( int16_t d[4][4] )
  83. ;-----------------------------------------------------------------------------
  84. cglobal x264_idct4x4dc_mmx, 1,1
  85.     movq   m3, [r0+24]
  86.     movq   m2, [r0+16]
  87.     movq   m1, [r0+ 8]
  88.     movq   m0, [r0+ 0]
  89.     WALSH4_1D  0,1,2,3,4
  90.     TRANSPOSE4x4W 0,1,2,3,4
  91.     WALSH4_1D  0,1,2,3,4
  92.     movq  [r0+ 0], m0
  93.     movq  [r0+ 8], m1
  94.     movq  [r0+16], m2
  95.     movq  [r0+24], m3
  96.     RET
  97. %macro SUB_DCT4 1
  98. ;-----------------------------------------------------------------------------
  99. ; void x264_sub4x4_dct_mmx( int16_t dct[4][4], uint8_t *pix1, uint8_t *pix2 )
  100. ;-----------------------------------------------------------------------------
  101. cglobal x264_sub4x4_dct_%1, 3,3
  102. %ifidn %1, mmx
  103. .skip_prologue:
  104.     LOAD_DIFF  m0, m4, m5, [r1+0*FENC_STRIDE], [r2+0*FDEC_STRIDE]
  105.     LOAD_DIFF  m3, m4, m5, [r1+3*FENC_STRIDE], [r2+3*FDEC_STRIDE]
  106.     LOAD_DIFF  m1, m4, m5, [r1+1*FENC_STRIDE], [r2+1*FDEC_STRIDE]
  107.     LOAD_DIFF  m2, m4, m5, [r1+2*FENC_STRIDE], [r2+2*FDEC_STRIDE]
  108. %else
  109.     mova m5, [hsub_mul GLOBAL]
  110.     LOAD_DIFF8x4_SSSE3 0, 3, 1, 2, 4, 5, r1, r2
  111. %endif
  112.     DCT4_1D 0,1,2,3,4
  113.     TRANSPOSE4x4W 0,1,2,3,4
  114.     DCT4_1D 0,1,2,3,4
  115.     movq  [r0+ 0], m0
  116.     movq  [r0+ 8], m1
  117.     movq  [r0+16], m2
  118.     movq  [r0+24], m3
  119.     RET
  120. %endmacro
  121. SUB_DCT4 mmx
  122. SUB_DCT4 ssse3
  123. ;-----------------------------------------------------------------------------
  124. ; void x264_add4x4_idct_mmx( uint8_t *p_dst, int16_t dct[4][4] )
  125. ;-----------------------------------------------------------------------------
  126. cglobal x264_add4x4_idct_mmx, 2,2
  127.     pxor m7, m7
  128. .skip_prologue:
  129.     movq  m1, [r1+ 8]
  130.     movq  m3, [r1+24]
  131.     movq  m2, [r1+16]
  132.     movq  m0, [r1+ 0]
  133.     IDCT4_1D 0,1,2,3,4,5
  134.     TRANSPOSE4x4W 0,1,2,3,4
  135.     paddw m0, [pw_32 GLOBAL]
  136.     IDCT4_1D 0,1,2,3,4,5
  137.     STORE_DIFF  m0, m4, m7, [r0+0*FDEC_STRIDE]
  138.     STORE_DIFF  m1, m4, m7, [r0+1*FDEC_STRIDE]
  139.     STORE_DIFF  m2, m4, m7, [r0+2*FDEC_STRIDE]
  140.     STORE_DIFF  m3, m4, m7, [r0+3*FDEC_STRIDE]
  141.     RET
  142. INIT_XMM
  143. cglobal x264_add4x4_idct_sse4, 2,2,6
  144.     mova      m0, [r1+0x00]     ; row1/row0
  145.     mova      m2, [r1+0x10]     ; row3/row2
  146.     mova      m1, m0            ; row1/row0
  147.     psraw     m0, 1             ; row1>>1/...
  148.     mova      m3, m2            ; row3/row2
  149.     psraw     m2, 1             ; row3>>1/...
  150.     movsd     m0, m1            ; row1>>1/row0
  151.     movsd     m2, m3            ; row3>>1/row2
  152.     psubw     m0, m3            ; row1>>1-row3/row0-2
  153.     paddw     m2, m1            ; row3>>1+row1/row0+2
  154.     SBUTTERFLY2 wd, 0, 2, 1
  155.     SUMSUB_BA m2, m0, m1
  156.     pshuflw   m1, m2, 10110001b
  157.     pshufhw   m2, m2, 10110001b
  158.     punpckldq m1, m0
  159.     punpckhdq m2, m0
  160.     SWAP 0, 1
  161.     mova      m1, [pw_32_0 GLOBAL]
  162.     paddw     m1, m0            ; row1/row0 corrected
  163.     psraw     m0, 1             ; row1>>1/...
  164.     mova      m3, m2            ; row3/row2
  165.     psraw     m2, 1             ; row3>>1/...
  166.     movsd     m0, m1            ; row1>>1/row0
  167.     movsd     m2, m3            ; row3>>1/row2
  168.     psubw     m0, m3            ; row1>>1-row3/row0-2
  169.     paddw     m2, m1            ; row3>>1+row1/row0+2
  170.     SBUTTERFLY2 qdq, 0, 2, 1
  171.     SUMSUB_BA m2, m0, m1
  172.     movd      m4, [r0+FDEC_STRIDE*0]
  173.     movd      m1, [r0+FDEC_STRIDE*1]
  174.     movd      m3, [r0+FDEC_STRIDE*2]
  175.     movd      m5, [r0+FDEC_STRIDE*3]
  176.     punpckldq m1, m4            ; row0/row1
  177.     pxor      m4, m4
  178.     punpckldq m3, m5            ; row3/row2
  179.     punpcklbw m1, m4
  180.     psraw     m2, 6
  181.     punpcklbw m3, m4
  182.     psraw     m0, 6
  183.     paddsw    m2, m1
  184.     paddsw    m0, m3
  185.     packuswb  m0, m2            ; row0/row1/row3/row2
  186.     pextrd   [r0+FDEC_STRIDE*0], m0, 3
  187.     pextrd   [r0+FDEC_STRIDE*1], m0, 2
  188.     movd     [r0+FDEC_STRIDE*2], m0
  189.     pextrd   [r0+FDEC_STRIDE*3], m0, 1
  190.     RET
  191. INIT_MMX
  192. ;-----------------------------------------------------------------------------
  193. ; void x264_sub8x8_dct_mmx( int16_t dct[4][4][4], uint8_t *pix1, uint8_t *pix2 )
  194. ;-----------------------------------------------------------------------------
  195. %macro SUB_NxN_DCT 6
  196. cglobal %1, 3,3,11
  197. %if mmsize == 8
  198.     pxor m7, m7
  199. %else
  200.     add r2, 4*FDEC_STRIDE
  201.     mova m7, [hsub_mul GLOBAL]
  202. %endif
  203. .skip_prologue:
  204. %ifdef WIN64
  205.     sub  rsp, 8
  206. %endif
  207.     call %2
  208.     add  r0, %3
  209.     add  r1, %4-%5-%6*FENC_STRIDE
  210.     add  r2, %4-%5-%6*FDEC_STRIDE
  211.     call %2
  212.     add  r0, %3
  213.     add  r1, (%4-%6)*FENC_STRIDE-%5-%4
  214.     add  r2, (%4-%6)*FDEC_STRIDE-%5-%4
  215.     call %2
  216.     add  r0, %3
  217.     add  r1, %4-%5-%6*FENC_STRIDE
  218.     add  r2, %4-%5-%6*FDEC_STRIDE
  219. %ifdef WIN64
  220.     add  rsp, 8
  221.     call %2
  222.     RET
  223. %else
  224.     jmp  %2
  225. %endif
  226. %endmacro
  227. ;-----------------------------------------------------------------------------
  228. ; void x264_add8x8_idct_mmx( uint8_t *pix, int16_t dct[4][4][4] )
  229. ;-----------------------------------------------------------------------------
  230. %macro ADD_NxN_IDCT 6-7
  231. cglobal %1, 2,2,11
  232.     pxor m7, m7
  233. %if mmsize==16
  234.     add  r0, 4*FDEC_STRIDE
  235. %endif
  236. .skip_prologue:
  237. %ifdef WIN64
  238.     sub  rsp, 8
  239. %endif
  240.     call %2
  241.     add  r0, %4-%5-%6*FDEC_STRIDE
  242.     add  r1, %3
  243.     call %2
  244.     add  r0, (%4-%6)*FDEC_STRIDE-%5-%4
  245.     add  r1, %3
  246.     call %2
  247.     add  r0, %4-%5-%6*FDEC_STRIDE
  248.     add  r1, %3
  249. %ifdef WIN64
  250.     add  rsp, 8
  251.     call %2
  252.     RET
  253. %else
  254.     jmp  %2
  255. %endif
  256. %endmacro
  257. %ifndef ARCH_X86_64
  258. SUB_NxN_DCT  x264_sub8x8_dct_mmx,    x264_sub4x4_dct_mmx.skip_prologue,  32, 4, 0, 0
  259. ADD_NxN_IDCT x264_add8x8_idct_mmx,   x264_add4x4_idct_mmx.skip_prologue, 32, 4, 0, 0
  260. SUB_NxN_DCT  x264_sub16x16_dct_mmx,  x264_sub8x8_dct_mmx.skip_prologue,  32, 8, 4, 4
  261. ADD_NxN_IDCT x264_add16x16_idct_mmx, x264_add8x8_idct_mmx.skip_prologue, 32, 8, 4, 4
  262. cextern x264_sub8x8_dct8_mmx.skip_prologue
  263. cextern x264_add8x8_idct8_mmx.skip_prologue
  264. SUB_NxN_DCT  x264_sub16x16_dct8_mmx,  x264_sub8x8_dct8_mmx.skip_prologue,  128, 8, 0, 0
  265. ADD_NxN_IDCT x264_add16x16_idct8_mmx, x264_add8x8_idct8_mmx.skip_prologue, 128, 8, 0, 0
  266. %endif
  267. INIT_XMM
  268. cextern x264_sub8x8_dct_sse2.skip_prologue
  269. cextern x264_sub8x8_dct_ssse3.skip_prologue
  270. SUB_NxN_DCT  x264_sub16x16_dct_sse2, x264_sub8x8_dct_sse2.skip_prologue, 128, 8, 0, 0
  271. SUB_NxN_DCT  x264_sub16x16_dct_ssse3, x264_sub8x8_dct_ssse3.skip_prologue, 128, 8, 0, 0
  272. cextern x264_add8x8_idct_sse2.skip_prologue
  273. ADD_NxN_IDCT x264_add16x16_idct_sse2, x264_add8x8_idct_sse2.skip_prologue, 2*64, 8, 0, 0
  274. cextern x264_sub8x8_dct8_sse2.skip_prologue
  275. cextern x264_add8x8_idct8_sse2.skip_prologue
  276. SUB_NxN_DCT  x264_sub16x16_dct8_sse2,  x264_sub8x8_dct8_sse2.skip_prologue,  128, 8, 0, 0
  277. ADD_NxN_IDCT x264_add16x16_idct8_sse2, x264_add8x8_idct8_sse2.skip_prologue, 128, 8, 0, 0
  278. cextern x264_sub8x8_dct8_ssse3.skip_prologue
  279. SUB_NxN_DCT  x264_sub16x16_dct8_ssse3,  x264_sub8x8_dct8_ssse3.skip_prologue,  128, 8, 0, 0
  280. ;-----------------------------------------------------------------------------
  281. ; void add8x8_idct_dc( uint8_t *p_dst, int16_t *dct2x2 )
  282. ;-----------------------------------------------------------------------------
  283. %macro ADD_DC 3
  284.     movq      mm4, [%3+FDEC_STRIDE*0]
  285.     movq      mm5, [%3+FDEC_STRIDE*1]
  286.     movq      mm6, [%3+FDEC_STRIDE*2]
  287.     paddusb   mm4, %1
  288.     paddusb   mm5, %1
  289.     paddusb   mm6, %1
  290.     paddusb    %1, [%3+FDEC_STRIDE*3]
  291.     psubusb   mm4, %2
  292.     psubusb   mm5, %2
  293.     psubusb   mm6, %2
  294.     psubusb    %1, %2
  295.     movq      [%3+FDEC_STRIDE*0], mm4
  296.     movq      [%3+FDEC_STRIDE*1], mm5
  297.     movq      [%3+FDEC_STRIDE*2], mm6
  298.     movq      [%3+FDEC_STRIDE*3], %1
  299. %endmacro
  300. cglobal x264_add8x8_idct_dc_mmx, 2,2
  301.     movq      mm0, [r1]
  302.     pxor      mm1, mm1
  303.     add        r0, FDEC_STRIDE*4
  304.     paddw     mm0, [pw_32 GLOBAL]
  305.     psraw     mm0, 6
  306.     psubw     mm1, mm0
  307.     packuswb  mm0, mm0
  308.     packuswb  mm1, mm1
  309.     punpcklbw mm0, mm0
  310.     punpcklbw mm1, mm1
  311.     pshufw    mm2, mm0, 0xFA
  312.     pshufw    mm3, mm1, 0xFA
  313.     punpcklbw mm0, mm0
  314.     punpcklbw mm1, mm1
  315.     ADD_DC    mm0, mm1, r0-FDEC_STRIDE*4
  316.     ADD_DC    mm2, mm3, r0
  317.     RET
  318. cglobal x264_add8x8_idct_dc_ssse3, 2,2
  319.     movq      xmm0, [r1]
  320.     pxor      xmm1, xmm1
  321.     add         r0, FDEC_STRIDE*4
  322.     paddw     xmm0, [pw_32 GLOBAL]
  323.     psraw     xmm0, 6
  324.     psubw     xmm1, xmm0
  325.     movdqa    xmm5, [pb_idctdc_unpack GLOBAL]
  326.     packuswb  xmm0, xmm0
  327.     packuswb  xmm1, xmm1
  328.     pshufb    xmm0, xmm5
  329.     pshufb    xmm1, xmm5
  330.     movq      xmm2, [r0+FDEC_STRIDE*-4]
  331.     movq      xmm3, [r0+FDEC_STRIDE*-3]
  332.     movq      xmm4, [r0+FDEC_STRIDE*-2]
  333.     movq      xmm5, [r0+FDEC_STRIDE*-1]
  334.     movhps    xmm2, [r0+FDEC_STRIDE* 0]
  335.     movhps    xmm3, [r0+FDEC_STRIDE* 1]
  336.     movhps    xmm4, [r0+FDEC_STRIDE* 2]
  337.     movhps    xmm5, [r0+FDEC_STRIDE* 3]
  338.     paddusb   xmm2, xmm0
  339.     paddusb   xmm3, xmm0
  340.     paddusb   xmm4, xmm0
  341.     paddusb   xmm5, xmm0
  342.     psubusb   xmm2, xmm1
  343.     psubusb   xmm3, xmm1
  344.     psubusb   xmm4, xmm1
  345.     psubusb   xmm5, xmm1
  346.     movq      [r0+FDEC_STRIDE*-4], xmm2
  347.     movq      [r0+FDEC_STRIDE*-3], xmm3
  348.     movq      [r0+FDEC_STRIDE*-2], xmm4
  349.     movq      [r0+FDEC_STRIDE*-1], xmm5
  350.     movhps    [r0+FDEC_STRIDE* 0], xmm2
  351.     movhps    [r0+FDEC_STRIDE* 1], xmm3
  352.     movhps    [r0+FDEC_STRIDE* 2], xmm4
  353.     movhps    [r0+FDEC_STRIDE* 3], xmm5
  354.     RET
  355. cglobal x264_add16x16_idct_dc_mmx, 2,3
  356.     mov       r2, 4
  357. .loop:
  358.     movq      mm0, [r1]
  359.     pxor      mm1, mm1
  360.     paddw     mm0, [pw_32 GLOBAL]
  361.     psraw     mm0, 6
  362.     psubw     mm1, mm0
  363.     packuswb  mm0, mm0
  364.     packuswb  mm1, mm1
  365.     punpcklbw mm0, mm0
  366.     punpcklbw mm1, mm1
  367.     pshufw    mm2, mm0, 0xFA
  368.     pshufw    mm3, mm1, 0xFA
  369.     punpcklbw mm0, mm0
  370.     punpcklbw mm1, mm1
  371.     ADD_DC    mm0, mm1, r0
  372.     ADD_DC    mm2, mm3, r0+8
  373.     add       r1, 8
  374.     add       r0, FDEC_STRIDE*4
  375.     dec       r2
  376.     jg .loop
  377.     REP_RET
  378. %macro IDCT_DC_STORE 3
  379.     movdqa    xmm4, [r0+%1+FDEC_STRIDE*0]
  380.     movdqa    xmm5, [r0+%1+FDEC_STRIDE*1]
  381.     movdqa    xmm6, [r0+%1+FDEC_STRIDE*2]
  382.     movdqa    xmm7, [r0+%1+FDEC_STRIDE*3]
  383.     paddusb   xmm4, %2
  384.     paddusb   xmm5, %2
  385.     paddusb   xmm6, %2
  386.     paddusb   xmm7, %2
  387.     psubusb   xmm4, %3
  388.     psubusb   xmm5, %3
  389.     psubusb   xmm6, %3
  390.     psubusb   xmm7, %3
  391.     movdqa    [r0+%1+FDEC_STRIDE*0], xmm4
  392.     movdqa    [r0+%1+FDEC_STRIDE*1], xmm5
  393.     movdqa    [r0+%1+FDEC_STRIDE*2], xmm6
  394.     movdqa    [r0+%1+FDEC_STRIDE*3], xmm7
  395. %endmacro
  396. cglobal x264_add16x16_idct_dc_sse2, 2,2,8
  397.     call .loop
  398.     add       r0, FDEC_STRIDE*4
  399. %ifdef WIN64
  400.     call .loop
  401.     RET
  402. %endif
  403. .loop:
  404.     add       r0, FDEC_STRIDE*4
  405.     movq      xmm0, [r1+0]
  406.     movq      xmm2, [r1+8]
  407.     add       r1, 16
  408.     punpcklwd xmm0, xmm0
  409.     punpcklwd xmm2, xmm2
  410.     pxor      xmm1, xmm1
  411.     pxor      xmm3, xmm3
  412.     paddw     xmm0, [pw_32 GLOBAL]
  413.     paddw     xmm2, [pw_32 GLOBAL]
  414.     psraw     xmm0, 6
  415.     psraw     xmm2, 6
  416.     psubw     xmm1, xmm0
  417.     psubw     xmm3, xmm2
  418.     packuswb  xmm0, xmm1
  419.     packuswb  xmm2, xmm3
  420.     movdqa    xmm1, xmm0
  421.     movdqa    xmm3, xmm2
  422.     punpcklbw xmm0, xmm0
  423.     punpcklbw xmm2, xmm2
  424.     punpckhbw xmm1, xmm1
  425.     punpckhbw xmm3, xmm3
  426.     IDCT_DC_STORE FDEC_STRIDE*-4, xmm0, xmm1
  427.     IDCT_DC_STORE 0, xmm2, xmm3
  428.     ret
  429. cglobal x264_add16x16_idct_dc_ssse3, 2,2,8
  430.     call .loop
  431.     add       r0, FDEC_STRIDE*4
  432. %ifdef WIN64
  433.     call .loop
  434.     RET
  435. %endif
  436. .loop:
  437.     add       r0, FDEC_STRIDE*4
  438.     movdqa    xmm0, [r1]
  439.     add       r1, 16
  440.     pxor      xmm1, xmm1
  441.     paddw     xmm0, [pw_32 GLOBAL]
  442.     psraw     xmm0, 6
  443.     psubw     xmm1, xmm0
  444.     movdqa    xmm5, [ pb_idctdc_unpack GLOBAL]
  445.     movdqa    xmm6, [pb_idctdc_unpack2 GLOBAL]
  446.     packuswb  xmm0, xmm0
  447.     packuswb  xmm1, xmm1
  448.     movdqa    xmm2, xmm0
  449.     movdqa    xmm3, xmm1
  450.     pshufb    xmm0, xmm5
  451.     pshufb    xmm2, xmm6
  452.     pshufb    xmm1, xmm5
  453.     pshufb    xmm3, xmm6
  454.     IDCT_DC_STORE FDEC_STRIDE*-4, xmm0, xmm1
  455.     IDCT_DC_STORE 0, xmm2, xmm3
  456.     ret
  457. ;-----------------------------------------------------------------------------
  458. ; void sub8x8_dct_dc( int16_t dct[2][2], uint8_t *pix1, uint8_t *pix2 )
  459. ;-----------------------------------------------------------------------------
  460. %macro DCTDC_2ROW_MMX 3
  461.     movq      %1, [r1+FENC_STRIDE*(0+%3)]
  462.     movq      m1, [r1+FENC_STRIDE*(1+%3)]
  463.     movq      m2, [r2+FDEC_STRIDE*(0+%3)]
  464.     movq      m3, [r2+FDEC_STRIDE*(1+%3)]
  465.     movq      %2, %1
  466.     punpckldq %1, m1
  467.     punpckhdq %2, m1
  468.     movq      m1, m2
  469.     punpckldq m2, m3
  470.     punpckhdq m1, m3
  471.     psadbw    %1, m7
  472.     psadbw    %2, m7
  473.     psadbw    m2, m7
  474.     psadbw    m1, m7
  475.     psubw     %1, m2
  476.     psubw     %2, m1
  477. %endmacro
  478. INIT_MMX
  479. cglobal x264_sub8x8_dct_dc_mmxext, 3,3
  480.     pxor      m7, m7
  481.     call .loop
  482.     add       r1, FENC_STRIDE*4
  483.     add       r2, FDEC_STRIDE*4
  484.     add       r0, 4
  485. .loop:
  486.     DCTDC_2ROW_MMX m0, m4, 0
  487.     DCTDC_2ROW_MMX m5, m6, 2
  488.     paddw     m0, m5
  489.     paddw     m4, m6
  490.     punpcklwd m0, m4
  491.     movd    [r0], m0
  492.     ret
  493. INIT_XMM
  494. %macro DCTDC_2ROW_SSE2 3
  495.     movq      m0, [r1+FENC_STRIDE*(0+%1)]
  496.     movq      m1, [r1+FENC_STRIDE*(1+%1)]
  497.     movq      m2, [r2+FDEC_STRIDE*(0+%1)]
  498.     movq      m3, [r2+FDEC_STRIDE*(1+%1)]
  499.     punpckldq m0, m1
  500.     punpckldq m2, m3
  501.     psadbw    m0, m7
  502.     psadbw    m2, m7
  503. %if %2
  504.     paddw     %3, m0
  505.     paddw     m6, m2
  506. %else
  507.     SWAP      %3, m0
  508.     SWAP      m6, m2
  509. %endif
  510. %endmacro
  511. cglobal x264_sub8x8_dct_dc_sse2, 3,3,8
  512.     pxor     m7, m7
  513.     DCTDC_2ROW_SSE2 0, 0, m4
  514.     DCTDC_2ROW_SSE2 2, 1, m4
  515.     add      r1, FENC_STRIDE*4
  516.     add      r2, FDEC_STRIDE*4
  517.     psubq    m4, m6
  518.     DCTDC_2ROW_SSE2 0, 0, m5
  519.     DCTDC_2ROW_SSE2 2, 1, m5
  520.     psubq    m5, m6
  521.     packssdw m4, m5
  522.     packssdw m4, m4
  523.     movq   [r0], m4
  524.     RET
  525. ;-----------------------------------------------------------------------------
  526. ; void x264_zigzag_scan_8x8_frame_ssse3( int16_t level[64], int16_t dct[8][8] )
  527. ;-----------------------------------------------------------------------------
  528. %macro SCAN_8x8 1
  529. cglobal x264_zigzag_scan_8x8_frame_%1, 2,2,8
  530.     movdqa    xmm0, [r1]
  531.     movdqa    xmm1, [r1+16]
  532.     movdq2q    mm0, xmm0
  533.     PALIGNR   xmm1, xmm1, 14, xmm2
  534.     movdq2q    mm1, xmm1
  535.     movdqa    xmm2, [r1+32]
  536.     movdqa    xmm3, [r1+48]
  537.     PALIGNR   xmm2, xmm2, 12, xmm4
  538.     movdq2q    mm2, xmm2
  539.     PALIGNR   xmm3, xmm3, 10, xmm4
  540.     movdq2q    mm3, xmm3
  541.     punpckhwd xmm0, xmm1
  542.     punpckhwd xmm2, xmm3
  543.     movq       mm4, mm1
  544.     movq       mm5, mm1
  545.     movq       mm6, mm2
  546.     movq       mm7, mm3
  547.     punpckhwd  mm1, mm0
  548.     psllq      mm0, 16
  549.     psrlq      mm3, 16
  550.     punpckhdq  mm1, mm1
  551.     punpckhdq  mm2, mm0
  552.     punpcklwd  mm0, mm4
  553.     punpckhwd  mm4, mm3
  554.     punpcklwd  mm4, mm2
  555.     punpckhdq  mm0, mm2
  556.     punpcklwd  mm6, mm3
  557.     punpcklwd  mm5, mm7
  558.     punpcklwd  mm5, mm6
  559.     movdqa    xmm4, [r1+64]
  560.     movdqa    xmm5, [r1+80]
  561.     movdqa    xmm6, [r1+96]
  562.     movdqa    xmm7, [r1+112]
  563.     movq [r0+2*00], mm0
  564.     movq [r0+2*04], mm4
  565.     movd [r0+2*08], mm1
  566.     movq [r0+2*36], mm5
  567.     movq [r0+2*46], mm6
  568.     PALIGNR   xmm4, xmm4, 14, xmm3
  569.     movdq2q    mm4, xmm4
  570.     PALIGNR   xmm5, xmm5, 12, xmm3
  571.     movdq2q    mm5, xmm5
  572.     PALIGNR   xmm6, xmm6, 10, xmm3
  573.     movdq2q    mm6, xmm6
  574. %ifidn %1, ssse3
  575.     PALIGNR   xmm7, xmm7, 8, xmm3
  576.     movdq2q    mm7, xmm7
  577. %else
  578.     movhlps   xmm3, xmm7
  579.     punpcklqdq xmm7, xmm7
  580.     movdq2q    mm7, xmm3
  581. %endif
  582.     punpckhwd xmm4, xmm5
  583.     punpckhwd xmm6, xmm7
  584.     movq       mm0, mm4
  585.     movq       mm1, mm5
  586.     movq       mm3, mm7
  587.     punpcklwd  mm7, mm6
  588.     psrlq      mm6, 16
  589.     punpcklwd  mm4, mm6
  590.     punpcklwd  mm5, mm4
  591.     punpckhdq  mm4, mm3
  592.     punpcklwd  mm3, mm6
  593.     punpckhwd  mm3, mm4
  594.     punpckhwd  mm0, mm1
  595.     punpckldq  mm4, mm0
  596.     punpckhdq  mm0, mm6
  597.     pshufw     mm4, mm4, 0x6c
  598.     movq [r0+2*14], mm4
  599.     movq [r0+2*25], mm0
  600.     movd [r0+2*54], mm7
  601.     movq [r0+2*56], mm5
  602.     movq [r0+2*60], mm3
  603.     movdqa    xmm3, xmm0
  604.     movdqa    xmm7, xmm4
  605.     punpckldq xmm0, xmm2
  606.     punpckldq xmm4, xmm6
  607.     punpckhdq xmm3, xmm2
  608.     punpckhdq xmm7, xmm6
  609.     pshufhw   xmm0, xmm0, 0x1b
  610.     pshuflw   xmm4, xmm4, 0x1b
  611.     pshufhw   xmm3, xmm3, 0x1b
  612.     pshuflw   xmm7, xmm7, 0x1b
  613.     movlps [r0+2*10], xmm0
  614.     movhps [r0+2*17], xmm0
  615.     movlps [r0+2*21], xmm3
  616.     movlps [r0+2*28], xmm4
  617.     movhps [r0+2*32], xmm3
  618.     movhps [r0+2*39], xmm4
  619.     movlps [r0+2*43], xmm7
  620.     movhps [r0+2*50], xmm7
  621.     RET
  622. %endmacro
  623. INIT_XMM
  624. %define PALIGNR PALIGNR_MMX
  625. SCAN_8x8 sse2
  626. %define PALIGNR PALIGNR_SSSE3
  627. SCAN_8x8 ssse3
  628. ;-----------------------------------------------------------------------------
  629. ; void x264_zigzag_scan_8x8_frame_mmxext( int16_t level[64], int16_t dct[8][8] )
  630. ;-----------------------------------------------------------------------------
  631. cglobal x264_zigzag_scan_8x8_frame_mmxext, 2,2
  632.     movq       mm0, [r1]
  633.     movq       mm1, [r1+2*8]
  634.     movq       mm2, [r1+2*14]
  635.     movq       mm3, [r1+2*21]
  636.     movq       mm4, [r1+2*28]
  637.     movq       mm5, mm0
  638.     movq       mm6, mm1
  639.     psrlq      mm0, 16
  640.     punpckldq  mm1, mm1
  641.     punpcklwd  mm5, mm6
  642.     punpckhwd  mm1, mm3
  643.     punpckhwd  mm6, mm0
  644.     punpckldq  mm5, mm0
  645.     movq       mm7, [r1+2*52]
  646.     movq       mm0, [r1+2*60]
  647.     punpckhwd  mm1, mm2
  648.     punpcklwd  mm2, mm4
  649.     punpckhwd  mm4, mm3
  650.     punpckldq  mm3, mm3
  651.     punpckhwd  mm3, mm2
  652.     movq      [r0], mm5
  653.     movq  [r0+2*4], mm1
  654.     movq  [r0+2*8], mm6
  655.     punpcklwd  mm6, mm0
  656.     punpcklwd  mm6, mm7
  657.     movq       mm1, [r1+2*32]
  658.     movq       mm5, [r1+2*39]
  659.     movq       mm2, [r1+2*46]
  660.     movq [r0+2*35], mm3
  661.     movq [r0+2*47], mm4
  662.     punpckhwd  mm7, mm0
  663.     psllq      mm0, 16
  664.     movq       mm3, mm5
  665.     punpcklwd  mm5, mm1
  666.     punpckhwd  mm1, mm2
  667.     punpckhdq  mm3, mm3
  668.     movq [r0+2*52], mm6
  669.     movq [r0+2*13], mm5
  670.     movq       mm4, [r1+2*11]
  671.     movq       mm6, [r1+2*25]
  672.     punpcklwd  mm5, mm7
  673.     punpcklwd  mm1, mm3
  674.     punpckhdq  mm0, mm7
  675.     movq       mm3, [r1+2*4]
  676.     movq       mm7, [r1+2*18]
  677.     punpcklwd  mm2, mm5
  678.     movq [r0+2*25], mm1
  679.     movq       mm1, mm4
  680.     movq       mm5, mm6
  681.     punpcklwd  mm4, mm3
  682.     punpcklwd  mm6, mm7
  683.     punpckhwd  mm1, mm3
  684.     punpckhwd  mm5, mm7
  685.     movq       mm3, mm6
  686.     movq       mm7, mm5
  687.     punpckldq  mm6, mm4
  688.     punpckldq  mm5, mm1
  689.     punpckhdq  mm3, mm4
  690.     punpckhdq  mm7, mm1
  691.     movq       mm4, [r1+2*35]
  692.     movq       mm1, [r1+2*49]
  693.     pshufw     mm6, mm6, 0x1b
  694.     pshufw     mm5, mm5, 0x1b
  695.     movq [r0+2*60], mm0
  696.     movq [r0+2*56], mm2
  697.     movq       mm0, [r1+2*42]
  698.     movq       mm2, [r1+2*56]
  699.     movq [r0+2*17], mm3
  700.     movq [r0+2*32], mm7
  701.     movq [r0+2*10], mm6
  702.     movq [r0+2*21], mm5
  703.     movq       mm3, mm0
  704.     movq       mm7, mm2
  705.     punpcklwd  mm0, mm4
  706.     punpcklwd  mm2, mm1
  707.     punpckhwd  mm3, mm4
  708.     punpckhwd  mm7, mm1
  709.     movq       mm4, mm2
  710.     movq       mm1, mm7
  711.     punpckhdq  mm2, mm0
  712.     punpckhdq  mm7, mm3
  713.     punpckldq  mm4, mm0
  714.     punpckldq  mm1, mm3
  715.     pshufw     mm2, mm2, 0x1b
  716.     pshufw     mm7, mm7, 0x1b
  717.     movq [r0+2*28], mm4
  718.     movq [r0+2*43], mm1
  719.     movq [r0+2*39], mm2
  720.     movq [r0+2*50], mm7
  721.     RET
  722. ;-----------------------------------------------------------------------------
  723. ; void x264_zigzag_scan_4x4_frame_mmx( int16_t level[16], int16_t dct[4][4] )
  724. ;-----------------------------------------------------------------------------
  725. cglobal x264_zigzag_scan_4x4_frame_mmx, 2,2
  726.     movq       mm0, [r1]
  727.     movq       mm1, [r1+8]
  728.     movq       mm2, [r1+16]
  729.     movq       mm3, [r1+24]
  730.     movq       mm4, mm0
  731.     movq       mm5, mm1
  732.     movq       mm6, mm2
  733.     movq       mm7, mm3
  734.     psllq      mm3, 16
  735.     psrlq      mm0, 16
  736.     punpckldq  mm2, mm2
  737.     punpckhdq  mm1, mm1
  738.     punpcklwd  mm4, mm5
  739.     punpcklwd  mm5, mm3
  740.     punpckldq  mm4, mm0
  741.     punpckhwd  mm5, mm2
  742.     punpckhwd  mm0, mm6
  743.     punpckhwd  mm6, mm7
  744.     punpcklwd  mm1, mm0
  745.     punpckhdq  mm3, mm6
  746.     movq      [r0], mm4
  747.     movq    [r0+8], mm5
  748.     movq   [r0+16], mm1
  749.     movq   [r0+24], mm3
  750.     RET
  751. ;-----------------------------------------------------------------------------
  752. ; void x264_zigzag_scan_4x4_frame_ssse3( int16_t level[16], int16_t dct[4][4] )
  753. ;-----------------------------------------------------------------------------
  754. cglobal x264_zigzag_scan_4x4_frame_ssse3, 2,2
  755.     movdqa    xmm1, [r1+16]
  756.     movdqa    xmm0, [r1]
  757.     pshufb    xmm1, [pb_scan4frameb GLOBAL]
  758.     pshufb    xmm0, [pb_scan4framea GLOBAL]
  759.     movdqa    xmm2, xmm1
  760.     psrldq    xmm1, 6
  761.     palignr   xmm2, xmm0, 6
  762.     pslldq    xmm0, 10
  763.     palignr   xmm1, xmm0, 10
  764.     movdqa    [r0], xmm2
  765.     movdqa [r0+16], xmm1
  766.     RET
  767. ;-----------------------------------------------------------------------------
  768. ; void x264_zigzag_scan_4x4_field_mmxext( int16_t level[16], int16_t dct[4][4] )
  769. ;-----------------------------------------------------------------------------
  770. ; sse2 is only 1 cycle faster, and ssse3/pshufb is slower on core2
  771. cglobal x264_zigzag_scan_4x4_field_mmxext, 2,3
  772.     pshufw     mm0, [r1+4], 0xd2
  773.     movq       mm1, [r1+16]
  774.     movq       mm2, [r1+24]
  775.     movq    [r0+4], mm0
  776.     movq   [r0+16], mm1
  777.     movq   [r0+24], mm2
  778.     mov        r2d, [r1]
  779.     mov       [r0], r2d
  780.     mov        r2d, [r1+12]
  781.     mov    [r0+12], r2d
  782.     RET
  783. ;-----------------------------------------------------------------------------
  784. ; void x264_zigzag_sub_4x4_frame_ssse3( int16_t level[16], const uint8_t *src, uint8_t *dst )
  785. ;-----------------------------------------------------------------------------
  786. %macro ZIGZAG_SUB_4x4 2
  787. %ifidn %1, ac
  788. cglobal x264_zigzag_sub_4x4%1_%2_ssse3, 4,4,8
  789. %else
  790. cglobal x264_zigzag_sub_4x4%1_%2_ssse3, 3,3,8
  791. %endif
  792.     movd      xmm0, [r1+0*FENC_STRIDE]
  793.     movd      xmm1, [r1+1*FENC_STRIDE]
  794.     movd      xmm2, [r1+2*FENC_STRIDE]
  795.     movd      xmm3, [r1+3*FENC_STRIDE]
  796.     movd      xmm4, [r2+0*FDEC_STRIDE]
  797.     movd      xmm5, [r2+1*FDEC_STRIDE]
  798.     movd      xmm6, [r2+2*FDEC_STRIDE]
  799.     movd      xmm7, [r2+3*FDEC_STRIDE]
  800.     movd      [r2+0*FDEC_STRIDE], xmm0
  801.     movd      [r2+1*FDEC_STRIDE], xmm1
  802.     movd      [r2+2*FDEC_STRIDE], xmm2
  803.     movd      [r2+3*FDEC_STRIDE], xmm3
  804.     punpckldq xmm0, xmm1
  805.     punpckldq xmm2, xmm3
  806.     punpckldq xmm4, xmm5
  807.     punpckldq xmm6, xmm7
  808.     punpcklqdq xmm0, xmm2
  809.     punpcklqdq xmm4, xmm6
  810. %ifidn %2, frame
  811.     movdqa    xmm7, [pb_sub4frame GLOBAL]
  812. %else
  813.     movdqa    xmm7, [pb_sub4field GLOBAL]
  814. %endif
  815.     pshufb    xmm0, xmm7
  816.     pshufb    xmm4, xmm7
  817.     pxor      xmm6, xmm6
  818.     movdqa    xmm1, xmm0
  819.     movdqa    xmm5, xmm4
  820.     punpcklbw xmm0, xmm6
  821.     punpckhbw xmm1, xmm6
  822.     punpcklbw xmm4, xmm6
  823.     punpckhbw xmm5, xmm6
  824.     psubw     xmm0, xmm4
  825.     psubw     xmm1, xmm5
  826. %ifidn %1, ac
  827.     movd       r2d, xmm0
  828.     pand      xmm0, [pb_subacmask GLOBAL]
  829. %endif
  830.     movdqa    [r0], xmm0
  831.     pxor      xmm2, xmm2
  832.     movdqa [r0+16], xmm1
  833.     por       xmm0, xmm1
  834.     pcmpeqb   xmm0, xmm2
  835.     pmovmskb   eax, xmm0
  836. %ifidn %1, ac
  837.     mov       [r3], r2w
  838. %endif
  839.     sub        eax, 0xffff
  840.     shr        eax, 31
  841.     RET
  842. %endmacro
  843. ZIGZAG_SUB_4x4   , frame
  844. ZIGZAG_SUB_4x4 ac, frame
  845. ZIGZAG_SUB_4x4   , field
  846. ZIGZAG_SUB_4x4 ac, field
  847. ;-----------------------------------------------------------------------------
  848. ; void x264_zigzag_interleave_8x8_cavlc_mmx( int16_t *dst, int16_t *src, uint8_t *nnz )
  849. ;-----------------------------------------------------------------------------
  850. %macro INTERLEAVE 1
  851.     movq   m0, [r1+%1*4+ 0]
  852.     movq   m1, [r1+%1*4+ 8]
  853.     movq   m2, [r1+%1*4+16]
  854.     movq   m3, [r1+%1*4+24]
  855.     TRANSPOSE4x4W 0,1,2,3,4
  856.     movq   [r0+%1+ 0], m0
  857.     movq   [r0+%1+32], m1
  858.     movq   [r0+%1+64], m2
  859.     movq   [r0+%1+96], m3
  860. %if %1
  861.     packsswb m0, m1
  862.     por    m6, m2
  863.     por    m7, m3
  864.     por    m5, m0
  865. %else
  866.     packsswb m0, m1
  867.     SWAP   m5, m0
  868.     SWAP   m6, m2
  869.     SWAP   m7, m3
  870. %endif
  871. %endmacro
  872. INIT_MMX
  873. cglobal x264_zigzag_interleave_8x8_cavlc_mmx, 3,3
  874.     INTERLEAVE  0
  875.     INTERLEAVE  8
  876.     INTERLEAVE 16
  877.     INTERLEAVE 24
  878.     packsswb m6, m7
  879.     packsswb m5, m6
  880.     packsswb m5, m5
  881.     pxor     m0, m0
  882.     pcmpeqb  m5, m0
  883.     paddb    m5, [pb_1 GLOBAL]
  884.     movd    r0d, m5
  885.     mov  [r2+0], r0w
  886.     shr     r0d, 16
  887.     mov  [r2+8], r0w
  888.     RET
  889. %macro INTERLEAVE_XMM 1
  890.     mova   m0, [r1+%1*4+ 0]
  891.     mova   m1, [r1+%1*4+16]
  892.     mova   m4, [r1+%1*4+32]
  893.     mova   m5, [r1+%1*4+48]
  894.     SBUTTERFLY wd, 0, 1, 6
  895.     SBUTTERFLY wd, 4, 5, 7
  896.     SBUTTERFLY wd, 0, 1, 6
  897.     SBUTTERFLY wd, 4, 5, 7
  898.     movq   [r0+%1+  0], m0
  899.     movhps [r0+%1+ 32], m0
  900.     movq   [r0+%1+ 64], m1
  901.     movhps [r0+%1+ 96], m1
  902.     movq   [r0+%1+  8], m4
  903.     movhps [r0+%1+ 40], m4
  904.     movq   [r0+%1+ 72], m5
  905.     movhps [r0+%1+104], m5
  906. %if %1
  907.     por    m2, m0
  908.     por    m3, m1
  909.     por    m2, m4
  910.     por    m3, m5
  911. %else
  912.     SWAP 0,2
  913.     SWAP 3,1
  914.     por    m2, m4
  915.     por    m3, m5
  916. %endif
  917. %endmacro
  918. INIT_XMM
  919. cglobal x264_zigzag_interleave_8x8_cavlc_sse2, 3,3,8
  920.     INTERLEAVE_XMM  0
  921.     INTERLEAVE_XMM 16
  922.     packsswb m2, m3
  923.     pxor     m5, m5
  924.     packsswb m2, m2
  925.     packsswb m2, m2
  926.     pcmpeqb  m5, m2
  927.     paddb    m5, [pb_1 GLOBAL]
  928.     movd    r0d, m5
  929.     mov  [r2+0], r0w
  930.     shr     r0d, 16
  931.     mov  [r2+8], r0w
  932.     RET