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

Audio

开发平台:

Visual C++

  1. ;*****************************************************************************
  2. ;* quant-a.asm: h264 encoder library
  3. ;*****************************************************************************
  4. ;* Copyright (C) 2005 x264 project
  5. ;*
  6. ;* Authors: Alex Izvorski <aizvorksi@gmail.com>
  7. ;*          Christian Heine <sennindemokrit@gmx.net>
  8. ;*
  9. ;* This program is free software; you can redistribute it and/or modify
  10. ;* it under the terms of the GNU General Public License as published by
  11. ;* the Free Software Foundation; either version 2 of the License, or
  12. ;* (at your option) any later version.
  13. ;*
  14. ;* This program is distributed in the hope that it will be useful,
  15. ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. ;* GNU General Public License for more details.
  18. ;*
  19. ;* You should have received a copy of the GNU General Public License
  20. ;* along with this program; if not, write to the Free Software
  21. ;* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  22. ;*****************************************************************************
  23. ;*****************************************************************************
  24. ;*                                                                           *
  25. ;*  Revision history:                                                        *
  26. ;*                                                                           *
  27. ;*  2005.07.26  quant 4x4 & 8x8 MMX functions (AI)                           *
  28. ;*  2005.09.04  quant MMXEXT (added precision) and DC (CH)                   *
  29. ;*  2005.09.21  faster MMX and added MMXEXT16 (CH)                           *
  30. ;*                                                                           *
  31. ;*****************************************************************************
  32. BITS 32
  33. %include "i386inc.asm"
  34. SECTION_RODATA
  35. pd_1:  times 2 dd 1
  36. SECTION .text
  37. cglobal x264_quant_2x2_dc_core15_mmx
  38. cglobal x264_quant_4x4_dc_core15_mmx
  39. cglobal x264_quant_4x4_core15_mmx
  40. cglobal x264_quant_8x8_core15_mmx
  41. cglobal x264_quant_2x2_dc_core16_mmxext
  42. cglobal x264_quant_4x4_dc_core16_mmxext
  43. cglobal x264_quant_4x4_core16_mmxext
  44. cglobal x264_quant_8x8_core16_mmxext
  45. cglobal x264_quant_2x2_dc_core32_mmxext
  46. cglobal x264_quant_4x4_dc_core32_mmxext
  47. cglobal x264_quant_4x4_core32_mmxext
  48. cglobal x264_quant_8x8_core32_mmxext
  49. cglobal x264_dequant_4x4_mmx
  50. cglobal x264_dequant_8x8_mmx
  51. %macro MMX_QUANT_AC_START 0
  52.     mov         eax, [esp+ 4]   ; &dct[0][0]
  53.     mov         ecx, [esp+ 8]   ; &quant_mf[0][0]
  54.     movd        mm6, [esp+12]   ; i_qbits
  55.     movd        mm7, [esp+16]   ; f
  56.     punpckldq   mm7, mm7        ; f in each dword
  57. %endmacro
  58. %macro MMX_QUANT15_DC_START 0
  59.     mov         eax, [esp+ 4]   ; &dct[0][0]
  60.     movd        mm5, [esp+ 8]   ; i_qmf
  61.     movd        mm6, [esp+12]   ; i_qbits
  62.     movd        mm7, [esp+16]   ; f
  63.     punpcklwd   mm5, mm5
  64.     punpcklwd   mm5, mm5        ; i_qmf in each word
  65.     punpckldq   mm7, mm7        ; f in each dword
  66. %endmacro
  67. %macro MMX_QUANT15_1x4 4
  68. ;;; %1      (m64)       dct[y][x]
  69. ;;; %2      (m64/mmx)   quant_mf[y][x] or quant_mf[0][0] (as int16_t)
  70. ;;; %3      (mmx)       i_qbits in the low doubleword
  71. ;;; %4      (mmx)       f as doublewords
  72. ;;; trashes mm0-mm2,mm4
  73.     movq        mm0, %1     ; load dct coeffs
  74.     pxor        mm4, mm4
  75.     pcmpgtw     mm4, mm0    ; sign(coeff)
  76.     pxor        mm0, mm4
  77.     psubw       mm0, mm4    ; abs(coeff)
  78.     movq        mm2, mm0
  79.     pmullw      mm0, %2
  80.     pmulhw      mm2, %2
  81.     movq        mm1, mm0
  82.     punpcklwd   mm0, mm2
  83.     punpckhwd   mm1, mm2
  84.     paddd       mm0, %4     ; round with f
  85.     paddd       mm1, %4
  86.     psrad       mm0, %3
  87.     psrad       mm1, %3
  88.     packssdw    mm0, mm1    ; pack
  89.     pxor        mm0, mm4    ; restore sign
  90.     psubw       mm0, mm4
  91.     movq        %1, mm0     ; store
  92. %endmacro
  93. ALIGN 16
  94. ;-----------------------------------------------------------------------------
  95. ;   void __cdecl x264_quant_2x2_dc_core15_mmx( int16_t dct[2][2],
  96. ;       int const i_qmf, int const i_qbits, int const f );
  97. ;-----------------------------------------------------------------------------
  98. x264_quant_2x2_dc_core15_mmx:
  99.     MMX_QUANT15_DC_START
  100.     MMX_QUANT15_1x4 [eax], mm5, mm6, mm7
  101.     ret
  102. ALIGN 16
  103. ;-----------------------------------------------------------------------------
  104. ;   void __cdecl x264_quant_4x4_dc_core15_mmx( int16_t dct[4][4],
  105. ;       int const i_qmf, int const i_qbits, int const f );
  106. ;-----------------------------------------------------------------------------
  107. x264_quant_4x4_dc_core15_mmx:
  108.     MMX_QUANT15_DC_START
  109. %rep 4
  110.     MMX_QUANT15_1x4 [eax], mm5, mm6, mm7
  111.     add         eax, byte 8
  112. %endrep
  113.     ret
  114. ALIGN 16
  115. ;-----------------------------------------------------------------------------
  116. ;   void __cdecl x264_quant_4x4_core15_mmx( int16_t dct[4][4],
  117. ;       int const quant_mf[4][4], int const i_qbits, int const f );
  118. ;-----------------------------------------------------------------------------
  119. x264_quant_4x4_core15_mmx:
  120.     MMX_QUANT_AC_START
  121. %rep 4
  122.     movq        mm5, [ecx]
  123.     packssdw    mm5, [ecx+8]
  124.     MMX_QUANT15_1x4 [eax], mm5, mm6, mm7
  125.     add         ecx, byte 16
  126.     add         eax, byte 8
  127. %endrep
  128.     ret
  129. ALIGN 16
  130. ;-----------------------------------------------------------------------------
  131. ;   void __cdecl x264_quant_8x8_core15_mmx( int16_t dct[8][8],
  132. ;       int const quant_mf[8][8], int const i_qbits, int const f );
  133. ;-----------------------------------------------------------------------------
  134. x264_quant_8x8_core15_mmx:
  135.     MMX_QUANT_AC_START
  136. %rep 16
  137.     movq        mm5, [ecx]
  138.     packssdw    mm5, [ecx+8]
  139.     MMX_QUANT15_1x4 [eax], mm5, mm6, mm7
  140.     add         ecx, byte 16
  141.     add         eax, byte 8
  142. %endrep
  143.     ret
  144. ; ============================================================================
  145. %macro MMXEXT_QUANT16_DC_START 0
  146.     mov         eax, [esp+ 4]   ; &dct[0][0]
  147.     movd        mm5, [esp+ 8]   ; i_qmf
  148.     movd        mm6, [esp+12]   ; i_qbits
  149.     movd        mm7, [esp+16]   ; f
  150.     pshufw      mm5, mm5, 0     ; i_qmf in each word
  151.     punpckldq   mm7, mm7        ; f in each dword
  152. %endmacro
  153. %macro MMXEXT_QUANT16_1x4 4
  154. ;;; %1      (m64)       dct[y][x]
  155. ;;; %2      (m64/mmx)   quant_mf[y][x] or quant_mf[0][0] (as uint16_t)
  156. ;;; %3      (mmx)       i_qbits in the low doubleword
  157. ;;; %4      (mmx)       f as doublewords
  158. ;;; trashes mm0-mm2,mm4
  159.     movq        mm0, %1     ; load dct coeffs
  160.     pxor        mm4, mm4
  161.     pcmpgtw     mm4, mm0    ; sign(coeff)
  162.     pxor        mm0, mm4
  163.     psubw       mm0, mm4    ; abs(coeff)
  164.     movq        mm2, mm0
  165.     pmullw      mm0, %2
  166.     pmulhuw     mm2, %2
  167.     movq        mm1, mm0
  168.     punpcklwd   mm0, mm2
  169.     punpckhwd   mm1, mm2
  170.     paddd       mm0, %4     ; round with f
  171.     paddd       mm1, %4
  172.     psrad       mm0, %3
  173.     psrad       mm1, %3
  174.     packssdw    mm0, mm1    ; pack
  175.     pxor        mm0, mm4    ; restore sign
  176.     psubw       mm0, mm4
  177.     movq        %1, mm0     ; store
  178. %endmacro
  179. ALIGN 16
  180. ;-----------------------------------------------------------------------------
  181. ;   void __cdecl x264_quant_2x2_dc_core16_mmxext( int16_t dct[2][2],
  182. ;       int const i_qmf, int const i_qbits, int const f );
  183. ;-----------------------------------------------------------------------------
  184. x264_quant_2x2_dc_core16_mmxext:
  185.     MMXEXT_QUANT16_DC_START
  186.     MMXEXT_QUANT16_1x4 [eax], mm5, mm6, mm7
  187.     ret
  188. ALIGN 16
  189. ;-----------------------------------------------------------------------------
  190. ;   void __cdecl x264_quant_4x4_dc_core16_mmxext( int16_t dct[4][4],
  191. ;       int const i_qmf, int const i_qbits, int const f );
  192. ;-----------------------------------------------------------------------------
  193. x264_quant_4x4_dc_core16_mmxext:
  194.     MMXEXT_QUANT16_DC_START
  195. %rep 4
  196.     MMXEXT_QUANT16_1x4 [eax], mm5, mm6, mm7
  197.     add         eax, byte 8
  198. %endrep
  199.     ret
  200. ALIGN 16
  201. ;-----------------------------------------------------------------------------
  202. ;   void __cdecl x264_quant_4x4_core16_mmxext( int16_t dct[4][4],
  203. ;       int const quant_mf[4][4], int const i_qbits, int const f );
  204. ;-----------------------------------------------------------------------------
  205. x264_quant_4x4_core16_mmxext:
  206.     MMX_QUANT_AC_START
  207. %rep 4
  208.     pshufw      mm5, [ecx], 10110001b
  209.     paddw       mm5, [ecx+8]
  210.     pshufw      mm5, mm5, 10001101b
  211.     MMXEXT_QUANT16_1x4 [eax], mm5, mm6, mm7
  212.     add         ecx, byte 16
  213.     add         eax, byte 8
  214. %endrep
  215.     ret
  216. ALIGN 16
  217. ;-----------------------------------------------------------------------------
  218. ;   void __cdecl x264_quant_8x8_core16_mmxext( int16_t dct[8][8],
  219. ;       int const quant_mf[8][8], int const i_qbits, int const f );
  220. ;-----------------------------------------------------------------------------
  221. x264_quant_8x8_core16_mmxext:
  222.     MMX_QUANT_AC_START
  223. %rep 16
  224.     pshufw      mm5, [ecx], 10110001b
  225.     paddw       mm5, [ecx+8]
  226.     pshufw      mm5, mm5, 10001101b
  227.     MMXEXT_QUANT16_1x4 [eax], mm5, mm6, mm7
  228.     add         ecx, byte 16
  229.     add         eax, byte 8
  230. %endrep
  231.     ret
  232. %macro MMX_QUANT32_DC_START 0
  233.     mov         eax, [esp+ 4]   ; &dct[0][0]
  234.     movd        mm5, [esp+ 8]   ; i_qmf
  235.     movd        mm6, [esp+12]   ; i_qbits
  236.     movd        mm7, [esp+16]   ; f
  237.     punpckldq   mm5, mm5        ; i_qmf in each dword
  238.     punpckldq   mm7, mm7        ; f in each dword
  239. %endmacro
  240. %macro MMXEXT_QUANT32_1x4 5
  241. ;;; %1      (m64)       dct[y][x]
  242. ;;; %2,%3   (m64/mmx)   quant_mf[y][x] or quant_mf[0][0] (as int16_t)
  243. ;;; %4      (mmx)       i_qbits in the low quadword
  244. ;;; %5      (mmx)       f as doublewords
  245. ;;; trashes mm0-mm4
  246.     movq        mm0, %1     ; load dct coeffs
  247.     pxor        mm4, mm4
  248.     pcmpgtw     mm4, mm0    ; sign(mm0)
  249.     pxor        mm0, mm4
  250.     psubw       mm0, mm4    ; abs(mm0)
  251.     movq        mm1, mm0
  252.     punpcklwd   mm0, mm0    ; duplicate the words for the upcomming
  253.     punpckhwd   mm1, mm1    ; 32 bit multiplication
  254.     movq        mm2, mm0    ; like in school ...
  255.     movq        mm3, mm1
  256.     pmulhuw     mm0, %2     ; ... multiply the parts ...
  257.     pmulhuw     mm1, %3
  258.     pmullw      mm2, %2
  259.     pmullw      mm3, %3
  260.     pslld       mm0, 16     ; ... shift ...
  261.     pslld       mm1, 16
  262.     paddd       mm0, mm2    ; ... and add them
  263.     paddd       mm1, mm3
  264.     paddd       mm0, %5     ; round with f
  265.     paddd       mm1, %5
  266.     psrad       mm0, %4
  267.     psrad       mm1, %4
  268.     packssdw    mm0, mm1    ; pack to int16_t
  269.     pxor        mm0, mm4    ; restore sign
  270.     psubw       mm0, mm4
  271.     movq        %1, mm0     ; store
  272. %endmacro
  273. ALIGN 16
  274. ;-----------------------------------------------------------------------------
  275. ;   void __cdecl x264_quant_2x2_dc_core32_mmxext( int16_t dct[2][2],
  276. ;       int const i_qmf, int const i_qbits, int const f );
  277. ;-----------------------------------------------------------------------------
  278. x264_quant_2x2_dc_core32_mmxext:
  279.     MMX_QUANT32_DC_START
  280.     MMXEXT_QUANT32_1x4 [eax], mm5, mm5, mm6, mm7
  281.     ret
  282. ALIGN 16
  283. ;-----------------------------------------------------------------------------
  284. ;   void __cdecl x264_quant_4x4_dc_core32_mmxext( int16_t dct[4][4],
  285. ;       int const i_qmf, int const i_qbits, int const f );
  286. ;-----------------------------------------------------------------------------
  287. x264_quant_4x4_dc_core32_mmxext:
  288.     MMX_QUANT32_DC_START
  289. %rep 4
  290.     MMXEXT_QUANT32_1x4 [eax], mm5, mm5, mm6, mm7
  291.     add         eax, byte 8
  292. %endrep
  293.     ret
  294. ALIGN 16
  295. ;-----------------------------------------------------------------------------
  296. ;   void __cdecl x264_quant_4x4_core32_mmxext( int16_t dct[4][4],
  297. ;       int const quant_mf[4][4], int const i_qbits, int const f );
  298. ;-----------------------------------------------------------------------------
  299. x264_quant_4x4_core32_mmxext:
  300.     MMX_QUANT_AC_START
  301. %rep 4
  302.     MMXEXT_QUANT32_1x4 [eax], [ecx], [ecx+8], mm6, mm7
  303.     add         eax, byte 8
  304.     add         ecx, byte 16
  305. %endrep
  306.     ret
  307. ALIGN 16
  308. ;-----------------------------------------------------------------------------
  309. ;   void __cdecl x264_quant_8x8_core32_mmxext( int16_t dct[8][8],
  310. ;       int const quant_mf[8][8], int const i_qbits, int const f );
  311. ;-----------------------------------------------------------------------------
  312. x264_quant_8x8_core32_mmxext:
  313.     MMX_QUANT_AC_START
  314. %rep 16
  315.     MMXEXT_QUANT32_1x4 [eax], [ecx], [ecx+8], mm6, mm7
  316.     add         eax, byte 8
  317.     add         ecx, byte 16
  318. %endrep
  319.     ret
  320. ;=============================================================================
  321. ; dequant
  322. ;=============================================================================
  323. %macro DEQUANT16_L_1x4 3
  324. ;;; %1      dct[y][x]
  325. ;;; %2,%3   dequant_mf[i_mf][y][x]
  326. ;;; mm5     i_qbits
  327.     movq     mm1, %2
  328.     movq     mm2, %3
  329.     movq     mm0, %1
  330.     packssdw mm1, mm2
  331.     pmullw   mm0, mm1
  332.     psllw    mm0, mm5
  333.     movq     %1,  mm0
  334. %endmacro
  335. %macro DEQUANT16_R_1x4 3
  336. ;;; %1      dct[y][x]
  337. ;;; %2,%3   dequant_mf[i_mf][y][x]
  338. ;;; mm5     -i_qbits
  339. ;;; mm6     f as words
  340.     movq     mm1, %2
  341.     movq     mm2, %3
  342.     movq     mm0, %1
  343.     packssdw mm1, mm2
  344.     pmullw   mm0, mm1
  345.     paddw    mm0, mm6
  346.     psraw    mm0, mm5
  347.     movq     %1,  mm0
  348. %endmacro
  349. %macro DEQUANT32_R_1x4 3
  350. ;;; %1      dct[y][x]
  351. ;;; %2,%3   dequant_mf[i_mf][y][x]
  352. ;;; mm5     -i_qbits
  353. ;;; mm6     f as dwords
  354. ;;; mm7     0
  355.     movq      mm0, %1
  356.     movq      mm1, mm0
  357.     punpcklwd mm0, mm0
  358.     punpckhwd mm1, mm1
  359.     movq      mm2, mm0
  360.     movq      mm3, mm1
  361.     pmulhw    mm0, %2
  362.     pmulhw    mm1, %3
  363.     pmullw    mm2, %2
  364.     pmullw    mm3, %3
  365.     pslld     mm0, 16
  366.     pslld     mm1, 16
  367.     paddd     mm0, mm2
  368.     paddd     mm1, mm3
  369.     paddd     mm0, mm6
  370.     paddd     mm1, mm6
  371.     psrad     mm0, mm5
  372.     psrad     mm1, mm5
  373.     packssdw  mm0, mm1
  374.     movq      %1,  mm0
  375. %endmacro
  376. %macro DEQUANT_WxH 3
  377. ALIGN 16
  378. ;;; void x264_dequant_4x4_mmx( int16_t dct[4][4], int dequant_mf[6][4][4], int i_qp )
  379. %1:
  380.     mov  edx, [esp+12] ; i_qp
  381.     imul eax, edx, 0x2b
  382.     shr  eax, 8       ; i_qbits = i_qp / 6
  383.     lea  ecx, [eax+eax*2]
  384.     sub  edx, ecx
  385.     sub  edx, ecx     ; i_mf = i_qp % 6
  386.     shl  edx, %3+2
  387.     add  edx, [esp+8] ; dequant_mf[i_mf]
  388.     mov  ecx, [esp+4] ; dct
  389.     sub  eax, %3
  390.     jl   .rshift32    ; negative qbits => rightshift
  391. .lshift:
  392.     movd mm5, eax
  393.     mov  eax, 8*(%2-1)
  394. .loopl16:
  395. %rep 2
  396.     DEQUANT16_L_1x4 [ecx+eax], [edx+eax*2], [edx+eax*2+8]
  397.     sub  eax, byte 8
  398. %endrep
  399.     jge  .loopl16
  400.     nop
  401.     ret
  402. .rshift32:
  403.     neg   eax
  404.     picpush ebx
  405.     picgetgot ebx
  406.     movq  mm6, [pd_1 GOT_ebx]
  407.     picpop ebx
  408.     movd  mm5, eax
  409.     pxor  mm7, mm7
  410.     pslld mm6, mm5
  411.     psrld mm6, 1
  412.     mov  eax, 8*(%2-1)
  413. .loopr32:
  414. %rep 2
  415.     DEQUANT32_R_1x4 [ecx+eax], [edx+eax*2], [edx+eax*2+8]
  416.     sub  eax, byte 8
  417. %endrep
  418.     jge  .loopr32
  419.     nop
  420.     ret
  421. %endmacro
  422. DEQUANT_WxH x264_dequant_4x4_mmx, 4, 4
  423. DEQUANT_WxH x264_dequant_8x8_mmx, 16, 6