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

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. ;*****************************************************************************
  2. ;* dct-32.asm: h264 encoder library
  3. ;*****************************************************************************
  4. ;* Copyright (C) 2003-2008 x264 project
  5. ;*
  6. ;* Authors: Loren Merritt <lorenm@u.washington.edu>
  7. ;*          Holger Lubitz <holger@lubitz.org>
  8. ;*          Laurent Aimar <fenrir@via.ecp.fr>
  9. ;*          Min Chen <chenm001.163.com>
  10. ;*          Christian Heine <sennindemokrit@gmx.net>
  11. ;*
  12. ;* This program is free software; you can redistribute it and/or modify
  13. ;* it under the terms of the GNU General Public License as published by
  14. ;* the Free Software Foundation; either version 2 of the License, or
  15. ;* (at your option) any later version.
  16. ;*
  17. ;* This program is distributed in the hope that it will be useful,
  18. ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20. ;* GNU General Public License for more details.
  21. ;*
  22. ;* You should have received a copy of the GNU General Public License
  23. ;* along with this program; if not, write to the Free Software
  24. ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
  25. ;*****************************************************************************
  26. %include "x86inc.asm"
  27. %include "x86util.asm"
  28. SECTION_RODATA
  29. pw_32: times 8 dw 32
  30. hsub_mul: times 8 db 1, -1
  31. SECTION .text
  32. ; in: m0..m7
  33. ; out: 0,4,6 in mem, rest in regs
  34. %macro DCT8_1D 9
  35.     SUMSUB_BA  m%8, m%1      ; %8 = s07, %1 = d07
  36.     SUMSUB_BA  m%7, m%2      ; %7 = s16, %2 = d16
  37.     SUMSUB_BA  m%6, m%3      ; %6 = s25, %3 = d25
  38.     SUMSUB_BA  m%5, m%4      ; %5 = s34, %4 = d34
  39.     SUMSUB_BA  m%5, m%8      ; %5 = a0,  %8 = a2
  40.     SUMSUB_BA  m%6, m%7      ; %6 = a1,  %7 = a3
  41.     SUMSUB_BA  m%6, m%5      ; %6 = dst0, %5 = dst4
  42.     mova    [%9+0x00], m%6
  43.     mova    [%9+0x40], m%5
  44.     mova    m%6, m%7         ; a3
  45.     psraw   m%6, 1           ; a3>>1
  46.     paddw   m%6, m%8         ; a2 + (a3>>1)
  47.     psraw   m%8, 1           ; a2>>1
  48.     psubw   m%8, m%7         ; (a2>>1) - a3
  49.     mova    [%9+0x60], m%8
  50.     mova    m%5, m%3
  51.     psraw   m%5, 1
  52.     paddw   m%5, m%3         ; d25+(d25>>1)
  53.     mova    m%7, m%1
  54.     psubw   m%7, m%4         ; a5 = d07-d34-(d25+(d25>>1))
  55.     psubw   m%7, m%5
  56.     mova    m%5, m%2
  57.     psraw   m%5, 1
  58.     paddw   m%5, m%2         ; d16+(d16>>1)
  59.     mova    m%8, m%1
  60.     paddw   m%8, m%4
  61.     psubw   m%8, m%5         ; a6 = d07+d34-(d16+(d16>>1))
  62.     mova    m%5, m%1
  63.     psraw   m%5, 1
  64.     paddw   m%5, m%1         ; d07+(d07>>1)
  65.     paddw   m%5, m%2
  66.     paddw   m%5, m%3         ; a4 = d16+d25+(d07+(d07>>1))
  67.     mova    m%1, m%4
  68.     psraw   m%1, 1
  69.     paddw   m%1, m%4         ; d34+(d34>>1)
  70.     paddw   m%1, m%2
  71.     psubw   m%1, m%3         ; a7 = d16-d25+(d34+(d34>>1))
  72.     mova    m%4, m%1
  73.     psraw   m%4, 2
  74.     paddw   m%4, m%5         ; a4 + (a7>>2)
  75.     mova    m%3, m%8
  76.     psraw   m%3, 2
  77.     paddw   m%3, m%7         ; a5 + (a6>>2)
  78.     psraw   m%5, 2
  79.     psraw   m%7, 2
  80.     psubw   m%5, m%1         ; (a4>>2) - a7
  81.     psubw   m%8, m%7         ; a6 - (a5>>2)
  82.     SWAP %2, %4, %3, %6, %8, %5
  83. %endmacro
  84. ; in: 0,4 in mem, rest in regs
  85. ; out: m0..m7
  86. %macro IDCT8_1D 9
  87.     mova      m%1, m%3
  88.     mova      m%5, m%7
  89.     psraw     m%3, 1
  90.     psraw     m%7, 1
  91.     psubw     m%3, m%5
  92.     paddw     m%7, m%1
  93.     mova      m%5, m%2
  94.     psraw     m%5, 1
  95.     paddw     m%5, m%2
  96.     paddw     m%5, m%4
  97.     paddw     m%5, m%6
  98.     mova      m%1, m%6
  99.     psraw     m%1, 1
  100.     paddw     m%1, m%6
  101.     paddw     m%1, m%8
  102.     psubw     m%1, m%2
  103.     psubw     m%2, m%4
  104.     psubw     m%6, m%4
  105.     paddw     m%2, m%8
  106.     psubw     m%6, m%8
  107.     psraw     m%4, 1
  108.     psraw     m%8, 1
  109.     psubw     m%2, m%4
  110.     psubw     m%6, m%8
  111.     mova      m%4, m%5
  112.     mova      m%8, m%1
  113.     psraw     m%4, 2
  114.     psraw     m%8, 2
  115.     paddw     m%4, m%6
  116.     paddw     m%8, m%2
  117.     psraw     m%6, 2
  118.     psraw     m%2, 2
  119.     psubw     m%5, m%6
  120.     psubw     m%2, m%1
  121.     mova      m%1, [%9+0x00]
  122.     mova      m%6, [%9+0x40]
  123.     SUMSUB_BA m%6, m%1
  124.     SUMSUB_BA m%7, m%6
  125.     SUMSUB_BA m%3, m%1
  126.     SUMSUB_BA m%5, m%7
  127.     SUMSUB_BA m%2, m%3
  128.     SUMSUB_BA m%8, m%1
  129.     SUMSUB_BA m%4, m%6
  130.     SWAP %1, %5, %6
  131.     SWAP %3, %8, %7
  132. %endmacro
  133. INIT_MMX
  134. ALIGN 16
  135. load_diff_4x8_mmx:
  136.     LOAD_DIFF m0, m7, none, [r1+0*FENC_STRIDE], [r2+0*FDEC_STRIDE]
  137.     LOAD_DIFF m1, m7, none, [r1+1*FENC_STRIDE], [r2+1*FDEC_STRIDE]
  138.     LOAD_DIFF m2, m7, none, [r1+2*FENC_STRIDE], [r2+2*FDEC_STRIDE]
  139.     LOAD_DIFF m3, m7, none, [r1+3*FENC_STRIDE], [r2+3*FDEC_STRIDE]
  140.     LOAD_DIFF m4, m7, none, [r1+4*FENC_STRIDE], [r2+4*FDEC_STRIDE]
  141.     LOAD_DIFF m5, m7, none, [r1+5*FENC_STRIDE], [r2+5*FDEC_STRIDE]
  142.     movq  [r0], m0
  143.     LOAD_DIFF m6, m7, none, [r1+6*FENC_STRIDE], [r2+6*FDEC_STRIDE]
  144.     LOAD_DIFF m7, m0, none, [r1+7*FENC_STRIDE], [r2+7*FDEC_STRIDE]
  145.     movq  m0, [r0]
  146.     ret
  147. INIT_MMX
  148. ALIGN 16
  149. dct8_mmx:
  150.     DCT8_1D 0,1,2,3,4,5,6,7,r0
  151.     SAVE_MM_PERMUTATION dct8_mmx
  152.     ret
  153. %macro SPILL_SHUFFLE 3-* ; ptr, list of regs, list of memory offsets
  154.     %xdefine %%base %1
  155.     %rep %0/2
  156.     %xdefine %%tmp m%2
  157.     %rotate %0/2
  158.     mova [%%base + %2*16], %%tmp
  159.     %rotate 1-%0/2
  160.     %endrep
  161. %endmacro
  162. %macro UNSPILL_SHUFFLE 3-*
  163.     %xdefine %%base %1
  164.     %rep %0/2
  165.     %xdefine %%tmp m%2
  166.     %rotate %0/2
  167.     mova %%tmp, [%%base + %2*16]
  168.     %rotate 1-%0/2
  169.     %endrep
  170. %endmacro
  171. %macro SPILL 2+ ; assume offsets are the same as reg numbers
  172.     SPILL_SHUFFLE %1, %2, %2
  173. %endmacro
  174. %macro UNSPILL 2+
  175.     UNSPILL_SHUFFLE %1, %2, %2
  176. %endmacro
  177. ;-----------------------------------------------------------------------------
  178. ; void x264_sub8x8_dct8_mmx( int16_t dct[8][8], uint8_t *pix1, uint8_t *pix2 )
  179. ;-----------------------------------------------------------------------------
  180. cglobal x264_sub8x8_dct8_mmx, 3,3
  181. global x264_sub8x8_dct8_mmx.skip_prologue
  182. .skip_prologue:
  183.     INIT_MMX
  184.     call load_diff_4x8_mmx
  185.     call dct8_mmx
  186.     UNSPILL r0, 0
  187.     TRANSPOSE4x4W 0,1,2,3,4
  188.     SPILL r0, 0,1,2,3
  189.     UNSPILL r0, 4,6
  190.     TRANSPOSE4x4W 4,5,6,7,0
  191.     SPILL r0, 4,5,6,7
  192.     INIT_MMX
  193.     add   r1, 4
  194.     add   r2, 4
  195.     add   r0, 8
  196.     call load_diff_4x8_mmx
  197.     sub   r1, 4
  198.     sub   r2, 4
  199.     call dct8_mmx
  200.     sub   r0, 8
  201.     UNSPILL r0+8, 4,6
  202.     TRANSPOSE4x4W 4,5,6,7,0
  203.     SPILL r0+8, 4,5,6,7
  204.     UNSPILL r0+8, 0
  205.     TRANSPOSE4x4W 0,1,2,3,5
  206.     UNSPILL r0, 4,5,6,7
  207.     SPILL_SHUFFLE r0, 0,1,2,3, 4,5,6,7
  208.     movq  mm4, m6 ; depends on the permutation to not produce conflicts
  209.     movq  mm0, m4
  210.     movq  mm1, m5
  211.     movq  mm2, mm4
  212.     movq  mm3, m7
  213.     INIT_MMX
  214.     UNSPILL r0+8, 4,5,6,7
  215.     add   r0, 8
  216.     call dct8_mmx
  217.     sub   r0, 8
  218.     SPILL r0+8, 1,2,3,5,7
  219.     INIT_MMX
  220.     UNSPILL r0, 0,1,2,3,4,5,6,7
  221.     call dct8_mmx
  222.     SPILL r0, 1,2,3,5,7
  223.     ret
  224. INIT_MMX
  225. ALIGN 16
  226. idct8_mmx:
  227.     IDCT8_1D 0,1,2,3,4,5,6,7,r1
  228.     SAVE_MM_PERMUTATION idct8_mmx
  229.     ret
  230. %macro ADD_STORE_ROW 3
  231.     movq  m1, [r0+%1*FDEC_STRIDE]
  232.     movq  m2, m1
  233.     punpcklbw m1, m0
  234.     punpckhbw m2, m0
  235.     paddw m1, %2
  236.     paddw m2, %3
  237.     packuswb m1, m2
  238.     movq  [r0+%1*FDEC_STRIDE], m1
  239. %endmacro
  240. ;-----------------------------------------------------------------------------
  241. ; void x264_add8x8_idct8_mmx( uint8_t *dst, int16_t dct[8][8] )
  242. ;-----------------------------------------------------------------------------
  243. cglobal x264_add8x8_idct8_mmx, 2,2
  244. global x264_add8x8_idct8_mmx.skip_prologue
  245. .skip_prologue:
  246.     INIT_MMX
  247.     add word [r1], 32
  248.     UNSPILL r1, 1,2,3,5,6,7
  249.     call idct8_mmx
  250.     SPILL r1, 7
  251.     TRANSPOSE4x4W 0,1,2,3,7
  252.     SPILL r1, 0,1,2,3
  253.     UNSPILL r1, 7
  254.     TRANSPOSE4x4W 4,5,6,7,0
  255.     SPILL r1, 4,5,6,7
  256.     INIT_MMX
  257.     UNSPILL r1+8, 1,2,3,5,6,7
  258.     add r1, 8
  259.     call idct8_mmx
  260.     sub r1, 8
  261.     SPILL r1+8, 7
  262.     TRANSPOSE4x4W 0,1,2,3,7
  263.     SPILL r1+8, 0,1,2,3
  264.     UNSPILL r1+8, 7
  265.     TRANSPOSE4x4W 4,5,6,7,0
  266.     SPILL r1+8, 4,5,6,7
  267.     INIT_MMX
  268.     movq  m3, [r1+0x08]
  269.     movq  m0, [r1+0x40]
  270.     movq  [r1+0x40], m3
  271.     movq  [r1+0x08], m0
  272.     ; memory layout at this time:
  273.     ; A0------ A1------
  274.     ; B0------ F0------
  275.     ; C0------ G0------
  276.     ; D0------ H0------
  277.     ; E0------ E1------
  278.     ; B1------ F1------
  279.     ; C1------ G1------
  280.     ; D1------ H1------
  281.     UNSPILL_SHUFFLE r1, 1,2,3, 5,6,7
  282.     UNSPILL r1+8, 5,6,7
  283.     add r1, 8
  284.     call idct8_mmx
  285.     sub r1, 8
  286.     psraw m0, 6
  287.     psraw m1, 6
  288.     psraw m2, 6
  289.     psraw m3, 6
  290.     psraw m4, 6
  291.     psraw m5, 6
  292.     psraw m6, 6
  293.     psraw m7, 6
  294.     movq  [r1+0x08], m0 ; mm4
  295.     movq  [r1+0x48], m4 ; mm5
  296.     movq  [r1+0x58], m5 ; mm0
  297.     movq  [r1+0x68], m6 ; mm2
  298.     movq  [r1+0x78], m7 ; mm6
  299.     movq  mm5, [r1+0x18]
  300.     movq  mm6, [r1+0x28]
  301.     movq  [r1+0x18], m1 ; mm1
  302.     movq  [r1+0x28], m2 ; mm7
  303.     movq  mm7, [r1+0x38]
  304.     movq  [r1+0x38], m3 ; mm3
  305.     movq  mm1, [r1+0x10]
  306.     movq  mm2, [r1+0x20]
  307.     movq  mm3, [r1+0x30]
  308.     call idct8_mmx
  309.     psraw m0, 6
  310.     psraw m1, 6
  311.     psraw m2, 6
  312.     psraw m3, 6
  313.     psraw m4, 6
  314.     psraw m5, 6
  315.     psraw m6, 6
  316.     psraw m7, 6
  317.     SPILL r1, 0,1,2
  318.     pxor  m0, m0
  319.     ADD_STORE_ROW 0, [r1+0x00], [r1+0x08]
  320.     ADD_STORE_ROW 1, [r1+0x10], [r1+0x18]
  321.     ADD_STORE_ROW 2, [r1+0x20], [r1+0x28]
  322.     ADD_STORE_ROW 3, m3, [r1+0x38]
  323.     ADD_STORE_ROW 4, m4, [r1+0x48]
  324.     ADD_STORE_ROW 5, m5, [r1+0x58]
  325.     ADD_STORE_ROW 6, m6, [r1+0x68]
  326.     ADD_STORE_ROW 7, m7, [r1+0x78]
  327.     ret
  328. INIT_XMM
  329. %macro DCT_SUB8 1
  330. cglobal x264_sub8x8_dct_%1, 3,3
  331.     add r2, 4*FDEC_STRIDE
  332. global x264_sub8x8_dct_%1.skip_prologue
  333. .skip_prologue:
  334. %ifnidn %1, sse2
  335.     mova m7, [hsub_mul GLOBAL]
  336. %endif
  337.     LOAD_DIFF8x4 0, 1, 2, 3, 6, 7, r1, r2-4*FDEC_STRIDE
  338.     SPILL r0, 1,2
  339.     SWAP 2, 7
  340.     LOAD_DIFF8x4 4, 5, 6, 7, 1, 2, r1, r2-4*FDEC_STRIDE
  341.     UNSPILL r0, 1
  342.     SPILL r0, 7
  343.     SWAP 2, 7
  344.     UNSPILL r0, 2
  345.     DCT4_1D 0, 1, 2, 3, 7
  346.     TRANSPOSE2x4x4W 0, 1, 2, 3, 7
  347.     UNSPILL r0, 7
  348.     SPILL r0, 2
  349.     DCT4_1D 4, 5, 6, 7, 2
  350.     TRANSPOSE2x4x4W 4, 5, 6, 7, 2
  351.     UNSPILL r0, 2
  352.     SPILL r0, 6
  353.     DCT4_1D 0, 1, 2, 3, 6
  354.     UNSPILL r0, 6
  355.     STORE_DCT 0, 1, 2, 3, r0, 0
  356.     DCT4_1D 4, 5, 6, 7, 3
  357.     STORE_DCT 4, 5, 6, 7, r0, 64
  358.     ret
  359. ;-----------------------------------------------------------------------------
  360. ; void x264_sub8x8_dct8_sse2( int16_t dct[8][8], uint8_t *pix1, uint8_t *pix2 )
  361. ;-----------------------------------------------------------------------------
  362. cglobal x264_sub8x8_dct8_%1, 3,3
  363.     add r2, 4*FDEC_STRIDE
  364. global x264_sub8x8_dct8_%1.skip_prologue
  365. .skip_prologue:
  366. %ifidn %1, sse2
  367.     LOAD_DIFF m0, m7, none, [r1+0*FENC_STRIDE], [r2-4*FDEC_STRIDE]
  368.     LOAD_DIFF m1, m7, none, [r1+1*FENC_STRIDE], [r2-3*FDEC_STRIDE]
  369.     LOAD_DIFF m2, m7, none, [r1+2*FENC_STRIDE], [r2-2*FDEC_STRIDE]
  370.     LOAD_DIFF m3, m7, none, [r1+3*FENC_STRIDE], [r2-1*FDEC_STRIDE]
  371.     LOAD_DIFF m4, m7, none, [r1+4*FENC_STRIDE], [r2+0*FDEC_STRIDE]
  372.     LOAD_DIFF m5, m7, none, [r1+5*FENC_STRIDE], [r2+1*FDEC_STRIDE]
  373.     SPILL r0, 0
  374.     LOAD_DIFF m6, m7, none, [r1+6*FENC_STRIDE], [r2+2*FDEC_STRIDE]
  375.     LOAD_DIFF m7, m0, none, [r1+7*FENC_STRIDE], [r2+3*FDEC_STRIDE]
  376.     UNSPILL r0, 0
  377. %else
  378.     mova m7, [hsub_mul GLOBAL]
  379.     LOAD_DIFF8x4 0, 1, 2, 3, 4, 7, r1, r2-4*FDEC_STRIDE
  380.     SPILL r0, 0,1
  381.     SWAP 1, 7
  382.     LOAD_DIFF8x4 4, 5, 6, 7, 0, 1, r1, r2-4*FDEC_STRIDE
  383.     UNSPILL r0, 0,1
  384. %endif
  385.     DCT8_1D 0,1,2,3,4,5,6,7,r0
  386.     UNSPILL r0, 0,4
  387.     TRANSPOSE8x8W 0,1,2,3,4,5,6,7,[r0+0x60],[r0+0x40],1
  388.     UNSPILL r0, 4
  389.     DCT8_1D 0,1,2,3,4,5,6,7,r0
  390.     SPILL r0, 1,2,3,5,7
  391.     ret
  392. %endmacro
  393. %define LOAD_DIFF8x4 LOAD_DIFF8x4_SSE2
  394. %define movdqa movaps
  395. %define punpcklqdq movlhps
  396. DCT_SUB8 sse2
  397. %undef movdqa
  398. %undef punpcklqdq
  399. %define LOAD_DIFF8x4 LOAD_DIFF8x4_SSSE3
  400. DCT_SUB8 ssse3
  401. ;-----------------------------------------------------------------------------
  402. ; void x264_add8x8_idct_sse2( uint8_t *pix, int16_t dct[4][4][4] )
  403. ;-----------------------------------------------------------------------------
  404. cglobal x264_add8x8_idct_sse2, 2,2
  405.     add r0, 4*FDEC_STRIDE
  406. global x264_add8x8_idct_sse2.skip_prologue
  407. .skip_prologue:
  408.     UNSPILL_SHUFFLE r1, 0,2,1,3, 0,1,2,3
  409.     SBUTTERFLY qdq, 0, 1, 4
  410.     SBUTTERFLY qdq, 2, 3, 4
  411.     UNSPILL_SHUFFLE r1, 4,6,5,7, 4,5,6,7
  412.     SPILL r1, 0
  413.     SBUTTERFLY qdq, 4, 5, 0
  414.     SBUTTERFLY qdq, 6, 7, 0
  415.     UNSPILL r1,0
  416.     IDCT4_1D 0,1,2,3,r1
  417.     SPILL r1, 4
  418.     TRANSPOSE2x4x4W 0,1,2,3,4
  419.     UNSPILL r1, 4
  420.     IDCT4_1D 4,5,6,7,r1
  421.     SPILL r1, 0
  422.     TRANSPOSE2x4x4W 4,5,6,7,0
  423.     UNSPILL r1, 0
  424.     paddw m0, [pw_32 GLOBAL]
  425.     IDCT4_1D 0,1,2,3,r1
  426.     paddw m4, [pw_32 GLOBAL]
  427.     IDCT4_1D 4,5,6,7,r1
  428.     SPILL r1, 6,7
  429.     pxor m7, m7
  430.     DIFFx2 m0, m1, m6, m7, [r0-4*FDEC_STRIDE], [r0-3*FDEC_STRIDE]; m5
  431.     DIFFx2 m2, m3, m6, m7, [r0-2*FDEC_STRIDE], [r0-1*FDEC_STRIDE]; m5
  432.     UNSPILL_SHUFFLE r1, 0,2, 6,7
  433.     DIFFx2 m4, m5, m6, m7, [r0+0*FDEC_STRIDE], [r0+1*FDEC_STRIDE]; m5
  434.     DIFFx2 m0, m2, m6, m7, [r0+2*FDEC_STRIDE], [r0+3*FDEC_STRIDE]; m5
  435.     STORE_IDCT m1, m3, m5, m2
  436.     ret
  437. ;-----------------------------------------------------------------------------
  438. ; void x264_add8x8_idct8_sse2( uint8_t *p_dst, int16_t dct[8][8] )
  439. ;-----------------------------------------------------------------------------
  440. cglobal x264_add8x8_idct8_sse2, 2,2
  441.     add r0, 4*FDEC_STRIDE
  442. global x264_add8x8_idct8_sse2.skip_prologue
  443. .skip_prologue:
  444.     UNSPILL r1, 1,2,3,5,6,7
  445.     IDCT8_1D   0,1,2,3,4,5,6,7,r1
  446.     SPILL r1, 6
  447.     TRANSPOSE8x8W 0,1,2,3,4,5,6,7,[r1+0x60],[r1+0x40],1
  448.     paddw      m0, [pw_32 GLOBAL]
  449.     SPILL r1, 0
  450.     IDCT8_1D   0,1,2,3,4,5,6,7,r1
  451.     SPILL r1, 6,7
  452.     pxor       m7, m7
  453.     DIFFx2 m0, m1, m6, m7, [r0-4*FDEC_STRIDE], [r0-3*FDEC_STRIDE]; m5
  454.     DIFFx2 m2, m3, m6, m7, [r0-2*FDEC_STRIDE], [r0-1*FDEC_STRIDE]; m5
  455.     UNSPILL_SHUFFLE r1, 0,2, 6,7
  456.     DIFFx2 m4, m5, m6, m7, [r0+0*FDEC_STRIDE], [r0+1*FDEC_STRIDE]; m5
  457.     DIFFx2 m0, m2, m6, m7, [r0+2*FDEC_STRIDE], [r0+3*FDEC_STRIDE]; m5
  458.     STORE_IDCT m1, m3, m5, m2
  459.     ret