home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 275 / DPCS0111DVD.ISO / Toolkit / Audio-Visual / VirtualDub / Source / VirtualDub-1.9.10-src.7z / src / Meia / source / mpeg_idct_mmx.asm < prev    next >
Encoding:
Assembly Source File  |  2009-09-14  |  31.8 KB  |  1,330 lines

  1. ;    VirtualDub - Video processing and capture application
  2. ;    Copyright (C) 1998-2001 Avery Lee
  3. ;
  4. ;    This program is free software; you can redistribute it and/or modify
  5. ;    it under the terms of the GNU General Public License as published by
  6. ;    the Free Software Foundation; either version 2 of the License, or
  7. ;    (at your option) any later version.
  8. ;
  9. ;    This program is distributed in the hope that it will be useful,
  10. ;    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. ;    GNU General Public License for more details.
  13. ;
  14. ;    You should have received a copy of the GNU General Public License
  15. ;    along with this program; if not, write to the Free Software
  16. ;    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. %define        PROFILE    0
  19.  
  20. ;This code is based on the fragments from the Intel Application Note AP-922.
  21. ;
  22. ;Apologies to Intel; Adobe Acrobat screws up formatting royally.
  23. ;
  24. ;
  25. ;
  26. ;IEEE-1180 results:
  27. ;    pmse      mse       pme      me
  28. ;1    0.018000, 0.013742, 0.003100,-0.000083
  29. ;2    0.018600, 0.013573, 0.003300, 0.000217
  30. ;3    0.014100, 0.011441, 0.003900, 0.000106
  31. ;4    0.017900, 0.013700, 0.004500, 0.000056
  32. ;5    0.018300, 0.013623, 0.004900,-0.000239
  33. ;6    0.014000, 0.011439, 0.003600,-0.000117
  34.  
  35.  
  36.  
  37. ;=============================================================================
  38. ;
  39. ; These examples contain code fragments for first stage iDCT 8x8
  40. ; (for rows) and first stage DCT 8x8 (for columns)
  41. ;
  42. ;=============================================================================
  43.  
  44. BITS_INV_ACC    equ        4            ; 4 or 5 for IEEE
  45. SHIFT_INV_ROW    equ        16 - BITS_INV_ACC
  46. SHIFT_INV_COL    equ        1 + BITS_INV_ACC
  47. RND_INV_ROW        equ        1024 * (6 - BITS_INV_ACC) ; 1 << (SHIFT_INV_ROW-1)
  48. RND_INV_COL        equ        16 * (BITS_INV_ACC - 3) ; 1 << (SHIFT_INV_COL-1)
  49. RND_INV_CORR    equ        RND_INV_COL - 1 ; correction -1.0 and round
  50.  
  51.     segment    .rdata, align=16
  52.         Align    16
  53.  
  54. rounder        dw    4,4,4,4
  55. one_corr    dw    1, 1, 1, 1
  56. round_inv_row    dd    RND_INV_ROW, RND_INV_ROW
  57. round_inv_col    dw    RND_INV_COL, RND_INV_COL, RND_INV_COL, RND_INV_COL
  58. round_inv_corr    dw    RND_INV_CORR, RND_INV_CORR, RND_INV_CORR, RND_INV_CORR
  59. tg_1_16        dw    13036, 13036, 13036, 13036    ; tg * (2<<16)
  60. tg_2_16        dw    27146, 27146, 27146, 27146    ; tg * (2<<16)
  61. tg_3_16        dw    -21746, -21746, -21746, -21746    ; tg * (2<<16) - 1.0
  62. cos_4_16    dw    -19195, -19195, -19195, -19195    ; cos * (2<<16) - 1.0
  63. ocos_4_16    dw    23170, 23170, 23170, 23170    ; cos * (2<<15) + 0.5
  64. ucos_4_16    dw    46341, 46341, 46341, 46341    ; cos * (2<<16)
  65.  
  66. jump_tab    dd    tail_inter, tail_intra, tail_mjpeg,0
  67.  
  68.         %if PROFILE
  69.         extern _sprintf:near
  70.         extern _OutputDebugStringA@4:near
  71. last_tick    dq    0
  72. total_cnt    dd    65536*16
  73. total_tick    dd    7fffffffh
  74. total_tick2    dd    7fffffffh
  75. profile_str    db    "avg clocks for 1M IDCTs: %d row, %d col",10,0
  76.         Align    16
  77.         %endif
  78.  
  79. ;=============================================================================
  80. ;
  81. ; The first stage iDCT 8x8 - inverse DCTs of rows
  82. ;
  83. ;-----------------------------------------------------------------------------
  84. ; The 8-point inverse DCT direct algorithm
  85. ;-----------------------------------------------------------------------------
  86. ;
  87. ; static const short w[32] = {
  88. ; FIX(cos_4_16), FIX(cos_2_16), FIX(cos_4_16), FIX(cos_6_16),
  89. ; FIX(cos_4_16), FIX(cos_6_16), -FIX(cos_4_16), -FIX(cos_2_16),
  90. ; FIX(cos_4_16), -FIX(cos_6_16), -FIX(cos_4_16), FIX(cos_2_16),
  91. ; FIX(cos_4_16), -FIX(cos_2_16), FIX(cos_4_16), -FIX(cos_6_16),
  92. ; FIX(cos_1_16), FIX(cos_3_16), FIX(cos_5_16), FIX(cos_7_16),
  93. ; FIX(cos_3_16), -FIX(cos_7_16), -FIX(cos_1_16), -FIX(cos_5_16),
  94. ; FIX(cos_5_16), -FIX(cos_1_16), FIX(cos_7_16), FIX(cos_3_16),
  95. ; FIX(cos_7_16), -FIX(cos_5_16), FIX(cos_3_16), -FIX(cos_1_16) };
  96. ;
  97. ; #define DCT_8_INV_ROW(x, y)
  98. ;{
  99. ; int a0, a1, a2, a3, b0, b1, b2, b3;
  100. ;
  101. ; a0 =x[0]*w[0]+x[2]*w[1]+x[4]*w[2]+x[6]*w[3];
  102. ; a1 =x[0]*w[4]+x[2]*w[5]+x[4]*w[6]+x[6]*w[7];
  103. ; a2 = x[0] * w[ 8] + x[2] * w[ 9] + x[4] * w[10] + x[6] * w[11];
  104. ; a3 = x[0] * w[12] + x[2] * w[13] + x[4] * w[14] + x[6] * w[15];
  105. ; b0 = x[1] * w[16] + x[3] * w[17] + x[5] * w[18] + x[7] * w[19];
  106. ; b1 = x[1] * w[20] + x[3] * w[21] + x[5] * w[22] + x[7] * w[23];
  107. ; b2 = x[1] * w[24] + x[3] * w[25] + x[5] * w[26] + x[7] * w[27];
  108. ; b3 = x[1] * w[28] + x[3] * w[29] + x[5] * w[30] + x[7] * w[31];
  109. ;
  110. ; y[0] = SHIFT_ROUND ( a0 + b0 );
  111. ; y[1] = SHIFT_ROUND ( a1 + b1 );
  112. ; y[2] = SHIFT_ROUND ( a2 + b2 );
  113. ; y[3] = SHIFT_ROUND ( a3 + b3 );
  114. ; y[4] = SHIFT_ROUND ( a3 - b3 );
  115. ; y[5] = SHIFT_ROUND ( a2 - b2 );
  116. ; y[6] = SHIFT_ROUND ( a1 - b1 );
  117. ; y[7] = SHIFT_ROUND ( a0 - b0 );
  118. ;}
  119. ;
  120. ;-----------------------------------------------------------------------------
  121. ;
  122. ; In this implementation the outputs of the iDCT-1D are multiplied
  123. ; for rows 0,4 - by cos_4_16,
  124. ; for rows 1,7 - by cos_1_16,
  125. ; for rows 2,6 - by cos_2_16,
  126. ; for rows 3,5 - by cos_3_16
  127. ; and are shifted to the left for better accuracy
  128. ;
  129. ; For the constants used,
  130. ; FIX(float_const) = (short) (float_const * (1<<15) + 0.5)
  131. ;
  132. ;=============================================================================
  133.  
  134.         align 16
  135.  
  136. ; Table for rows 0,4 - constants are multiplied by cos_4_16
  137. ; Table for rows 1,7 - constants are multiplied by cos_1_16
  138. ; Table for rows 2,6 - constants are multiplied by cos_2_16
  139. ; Table for rows 3,5 - constants are multiplied by cos_3_16
  140.  
  141. tab_i_04_short    dw  16384,  21407, 16384,   8867 ; w05 w04 w01 w00
  142.                 dw  16384,  -8867, 16384, -21407 ; w13 w12 w09 w08
  143.                 dw  22725,  19266, 19266,  -4520 ; w21 w20 w17 w16
  144.                 dw  12873, -22725,  4520, -12873 ; w29 w28 w25 w24
  145.  
  146. tab_i_17_short    dw  22725,  29692, 22725,  12299 ; w05 w04 w01 w00
  147.                 dw  22725, -12299, 22725, -29692 ; w13 w12 w09 w08
  148.                 dw  31521,  26722, 26722,  -6270 ; w21 w20 w17 w16
  149.                 dw  17855, -31521,  6270, -17855 ; w29 w28 w25 w24
  150.  
  151. tab_i_26_short    dw  21407,  27969, 21407,  11585 ; w05 w04 w01 w00
  152.                 dw  21407, -11585, 21407, -27969 ; w13 w12 w09 w08
  153.                 dw  29692,  25172, 25172,  -5906 ; w21 w20 w17 w16
  154.                 dw  16819, -29692,  5906, -16819 ; w29 w28 w25 w24
  155.  
  156. tab_i_35_short    dw  19266,  25172, 19266,  10426 ; w05 w04 w01 w00
  157.                 dw  19266, -10426, 19266, -25172 ; w13 w12 w09 w08
  158.                 dw  26722,  22654, 22654,  -5315 ; w21 w20 w17 w16
  159.                 dw  15137, -26722,  5315, -15137 ; w29 w28 w25 w24
  160.  
  161.  
  162.  
  163. ; Table for rows 0,4 - constants are multiplied by cos_4_16
  164.  
  165. tab_i_04    dw  16384,  16384,  16384, -16384 ; w06 w04 w02 w00
  166.             dw  21407,   8867,   8867, -21407 ; w07 w05 w03 w01
  167.             dw  16384, -16384,  16384,  16384 ; w14 w12 w10 w08
  168.             dw  -8867,  21407, -21407,  -8867 ; w15 w13 w11 w09
  169.             dw  22725,  12873,  19266, -22725 ; w22 w20 w18 w16
  170.             dw  19266,   4520,  -4520, -12873 ; w23 w21 w19 w17
  171.             dw  12873,   4520,   4520,  19266 ; w30 w28 w26 w24
  172.             dw -22725,  19266, -12873, -22725 ; w31 w29 w27 w25
  173.  
  174. ; Table for rows 1,7 - constants are multiplied by cos_1_16
  175.  
  176. tab_i_17    dw  22725,  22725,  22725, -22725 ; movq-> w06 w04 w02 w00
  177.             dw  29692,  12299,  12299, -29692 ; w07 w05 w03 w01
  178.             dw  22725, -22725,  22725,  22725 ; w14 w12 w10 w08
  179.             dw -12299,  29692, -29692, -12299 ; w15 w13 w11 w09
  180.             dw  31521,  17855,  26722, -31521 ; w22 w20 w18 w16
  181.             dw  26722,   6270,  -6270, -17855 ; w23 w21 w19 w17
  182.             dw  17855,   6270,   6270,  26722 ; w30 w28 w26 w24
  183.             dw -31521,  26722, -17855, -31521 ; w31 w29 w27 w25
  184.  
  185. ; Table for rows 2,6 - constants are multiplied by cos_2_16
  186.  
  187. tab_i_26    dw  21407,  21407,  21407, -21407 ; movq-> w06 w04 w02 w00
  188.             dw  27969,  11585,  11585, -27969 ; w07 w05 w03 w01
  189.             dw  21407, -21407,  21407,  21407 ; w14 w12 w10 w08
  190.             dw -11585,  27969, -27969, -11585 ; w15 w13 w11 w09
  191.             dw  29692,  16819,  25172, -29692 ; w22 w20 w18 w16
  192.             dw  25172,   5906,  -5906, -16819 ; w23 w21 w19 w17
  193.             dw  16819,   5906,   5906,  25172 ; w30 w28 w26 w24
  194.             dw -29692,  25172, -16819, -29692 ; w31 w29 w27 w25
  195.  
  196. ; Table for rows 3,5 - constants are multiplied by cos_3_16
  197.  
  198. tab_i_35    dw  19266,  19266,  19266, -19266 ; movq-> w06 w04 w02 w00
  199.             dw  25172,  10426,  10426, -25172 ; w07 w05 w03 w01
  200.             dw  19266, -19266,  19266,  19266 ; w14 w12 w10 w08
  201.             dw -10426,  25172, -25172, -10426 ; w15 w13 w11 w09
  202.             dw  26722,  15137,  22654, -26722 ; w22 w20 w18 w16
  203.             dw  22654,   5315,  -5315, -15137 ; w23 w21 w19 w17
  204.             dw  15137,   5315,   5315,  22654 ; w30 w28 w26 w24
  205.             dw -26722,  22654, -15137, -26722 ; w31 w29 w27 w25
  206.  
  207. rowstart_tbl2    dd    dorow_7is
  208.         dd    dorow_6is
  209.         dd    dorow_5is
  210.         dd    dorow_4is
  211.         dd    dorow_3is
  212.         dd    dorow_2is
  213.         dd    dorow_1is
  214.         dd    dorow_0is
  215.         dd    do_dc_isse
  216.  
  217. rowstart_tbl:
  218.         dd    dorow_7
  219.         dd    dorow_6
  220.         dd    dorow_5
  221.         dd    dorow_4
  222.         dd    dorow_3
  223.         dd    dorow_2
  224.         dd    dorow_1
  225.         dd    dorow_0
  226.         dd    do_dc_mmx
  227.  
  228. pos_tab    times     1 db (8*4)        ;pos 0:     DC only
  229.         times     1 db (7*4)        ;pos 1:     1 AC row
  230.         times     1 db (6*4)        ;pos 2:     2 AC rows
  231.         times     6 db (5*4)        ;pos 3-8:   3 AC rows
  232.         times     1 db (4*4)        ;pos 9:     4 AC rows
  233.         times    10 db (3*4)        ;pos 10-19: 5 AC rows
  234.         times     1 db (2*4)        ;pos 20:    6 AC rows
  235.         times    14 db (1*4)        ;pos 21-34:    7 AC rows
  236.         times    29 db (0*4)        ;pos 35-63: 8 AC rows
  237.  
  238. ;-----------------------------------------------------------------------------
  239. %macro    DCT_8_INV_ROW_1 3
  240. .inp    equ        %1
  241. .out    equ        %2
  242. .table    equ        %3
  243.  
  244.         movq        mm0, [.inp+0]        ; x5 x1 x4 x0
  245.  
  246.         movq        mm3, [.table]    ; 3    ; w06 w04 w02 w00
  247.         movq        mm5, mm0        ; 5    ; x5 x1 x4 x0
  248.  
  249.         movq        mm4, [.table+8]    ; 4    ; w07 w05 w03 w01
  250.         punpckldq    mm0, mm0            ; x4 x0 x4 x0
  251.  
  252.         movq        mm2, [.inp+8]    ; 1    ; x7 x3 x6 x2
  253.         pmaddwd        mm3, mm0            ; x4*w06+x0*w04 x4*w02+x0*w00
  254.  
  255.         movq        mm1, [.table+32]    ; 1    ; w22 w20 w18 w16
  256.         movq        mm6, mm2        ; 6    ; x7 x3 x6 x2
  257.  
  258.         punpckldq    mm2, mm2            ; x6 x2 x6 x2
  259.  
  260.         punpckhdq    mm6, mm6            ; x7 x3 x7 x3
  261.         pmaddwd        mm4, mm2            ; x6*w07+x2*w05 x6*w03+x2*w01
  262.  
  263.         pmaddwd        mm0, [.table+16]        ; x4*w14+x0*w12 x4*w10+x0*w08
  264.         punpckhdq    mm5, mm5            ; x5 x1 x5 x1
  265.  
  266.         movq        mm7, [.table+40]    ; 7    ; w23 w21 w19 w17
  267.         pmaddwd        mm1, mm5            ; x5*w22+x1*w20 x5*w18+x1*w16
  268.  
  269.         paddd        mm3, [round_inv_row]    ; +rounder
  270.         pmaddwd        mm7, mm6            ; x7*w23+x3*w21 x7*w19+x3*w17
  271.  
  272.         pmaddwd        mm2, [.table+24]        ; x6*w15+x2*w13 x6*w11+x2*w09
  273.         paddd        mm3, mm4        ; 4    ; a1=sum(even1) a0=sum(even0)
  274.  
  275.         pmaddwd        mm5, [.table+48]        ; x5*w30+x1*w28 x5*w26+x1*w24
  276.         movq        mm4, mm3        ; 4    ; a1 a0
  277.  
  278.         pmaddwd        mm6, [.table+56]        ; x7*w31+x3*w29 x7*w27+x3*w25
  279.         paddd        mm1, mm7        ; 7    ; b1=sum(odd1) b0=sum(odd0)
  280.  
  281.         paddd        mm0, [round_inv_row]    ; +rounder
  282.         psubd        mm3, mm1            ; a1-b1 a0-b0
  283.  
  284.         psrad        mm3, SHIFT_INV_ROW        ; y6=a1-b1 y7=a0-b0
  285.         paddd        mm1, mm4        ; 4    ; a1+b1 a0+b0
  286.  
  287.         paddd        mm0, mm2        ; 2    ; a3=sum(even3) a2=sum(even2)
  288.         psrad        mm1, SHIFT_INV_ROW        ; y1=a1+b1 y0=a0+b0
  289.  
  290.         paddd        mm5, mm6        ; 6    ; b3=sum(odd3) b2=sum(odd2)
  291.         movq        mm4, mm0        ; 4    ; a3 a2
  292.  
  293.         paddd        mm0, mm5            ; a3+b3 a2+b2
  294.         psubd        mm4, mm5        ; 5    ; a3-b3 a2-b2
  295.  
  296.         psrad        mm0, SHIFT_INV_ROW        ; y3=a3+b3 y2=a2+b2
  297.  
  298.         psrad        mm4, SHIFT_INV_ROW        ; y4=a3-b3 y5=a2-b2
  299.  
  300.         packssdw    mm1, mm0        ; 0    ; y3 y2 y1 y0
  301.  
  302.         packssdw    mm4, mm3        ; 3    ; y6 y7 y4 y5
  303.  
  304.         movq        mm7, mm4        ; 7    ; y6 y7 y4 y5
  305.         psrld        mm4, 16                ; 0 y6 0 y4
  306.  
  307.         pslld        mm7, 16                ; y7 0 y5 0
  308.  
  309.         movq        [.out], mm1        ; 1    ; save y3 y2 y1 y0
  310.         por        mm7, mm4        ; 4    ; y7 y6 y5 y4
  311.  
  312.         movq        [.out+8], mm7    ; 7    ; save y7 y6 y5 y4
  313. %endmacro
  314.  
  315.  
  316. %macro DCT_8_INV_ROW_1_ISSE 3
  317. %%inp    equ        %1
  318. %%out    equ        %2
  319. %%table    equ        %3
  320.  
  321.         movq        mm0, [%%inp+0]            ; x5 x1 x4 x0
  322.  
  323.         movq        mm3, [%%table]            ; 3    ; w06 w04 w02 w00
  324.         pshufw        mm5, mm0, 11101110b        ; 5    ; x5 x1 x5 x1
  325.  
  326.         movq        mm4, [%%table+8]            ; 4    ; w07 w05 w03 w01
  327.         punpckldq    mm0, mm0                ; x4 x0 x4 x0
  328.  
  329.         movq        mm2, [%%inp+8]            ; 1    ; x7 x3 x6 x2
  330.         pmaddwd        mm3, mm0                ; x4*w06+x0*w04 x4*w02+x0*w00
  331.  
  332.         movq        mm1, [%%table+32]        ; 1    ; w22 w20 w18 w16
  333.         pshufw        mm6, mm2, 11101110b        ; 6    ; x7 x3 x7 x3
  334.  
  335.         pmaddwd        mm0, [%%table+16]        ; x4*w14+x0*w12 x4*w10+x0*w08
  336.         punpckldq    mm2, mm2                ; x6 x2 x6 x2
  337.  
  338.         pmaddwd        mm4, mm2                ; x6*w07+x2*w05 x6*w03+x2*w01
  339.  
  340.         movq        mm7, [%%table+40]        ; 7    ; w23 w21 w19 w17
  341.         pmaddwd        mm1, mm5                ; x5*w22+x1*w20 x5*w18+x1*w16
  342.  
  343.         paddd        mm3, [round_inv_row]    ; +rounder
  344.         pmaddwd        mm7, mm6                ; x7*w23+x3*w21 x7*w19+x3*w17
  345.  
  346.         pmaddwd        mm2, [%%table+24]        ; x6*w15+x2*w13 x6*w11+x2*w09
  347.         paddd        mm3, mm4                ; 4    ; a1=sum(even1) a0=sum(even0)
  348.  
  349.         pmaddwd        mm5, [%%table+48]        ; x5*w30+x1*w28 x5*w26+x1*w24
  350.         movq        mm4, mm3                ; 4    ; a1 a0
  351.  
  352.         pmaddwd        mm6, [%%table+56]        ; x7*w31+x3*w29 x7*w27+x3*w25
  353.         paddd        mm1, mm7                ; 7    ; b1=sum(odd1) b0=sum(odd0)
  354.  
  355.         paddd        mm0, [round_inv_row]    ; +rounder
  356.         psubd        mm3, mm1                ; a1-b1 a0-b0
  357.  
  358.         psrad        mm3, SHIFT_INV_ROW        ; y6=a1-b1 y7=a0-b0
  359.         paddd        mm1, mm4                ; 4    ; a1+b1 a0+b0
  360.  
  361.         paddd        mm0, mm2                ; 2    ; a3=sum(even3) a2=sum(even2)
  362.         psrad        mm1, SHIFT_INV_ROW        ; y1=a1+b1 y0=a0+b0
  363.  
  364.         paddd        mm5, mm6                ; 6    ; b3=sum(odd3) b2=sum(odd2)
  365.         movq        mm4, mm0                ; 4    ; a3 a2
  366.  
  367.         paddd        mm0, mm5                ; a3+b3 a2+b2
  368.         psubd        mm4, mm5                ; 5    ; a3-b3 a2-b2
  369.  
  370.         psrad        mm0, SHIFT_INV_ROW        ; y3=a3+b3 y2=a2+b2
  371.  
  372.         psrad        mm4, SHIFT_INV_ROW        ; y4=a3-b3 y5=a2-b2
  373.  
  374.         packssdw    mm1, mm0                ; 0    ; y3 y2 y1 y0
  375.  
  376.         packssdw    mm4, mm3                ; 3    ; y6 y7 y4 y5
  377.  
  378.         movq        [%%out], mm1            ; 1    ; save y3 y2 y1 y0
  379.         pshufw        mm4, mm4, 10110001b        ; y7 y6 y5 y4
  380.  
  381.         movq        [%%out+8], mm4        ; 7    ; save y7 y6 y5 y4
  382. %endmacro
  383.  
  384. %macro DCT_8_INV_ROW_1_ISSE_SHORT 3
  385. %%inp    equ        %1
  386. %%out    equ        %2
  387. %%table    equ        %3
  388.  
  389.         movq        mm0, [%%inp+8]            ;     0 x3 0 x2
  390.  
  391.         movq        mm1, [%%table]
  392.         psllq        mm0, 16
  393.  
  394.         por            mm0, [%%inp]                ;      x3 x1 x2 x0
  395.  
  396.         movq        mm2, [%%table+16]
  397.         pshufw        mm3, mm0, 01000100b        ;     x2 x0 x2 x0
  398.  
  399.         pshufw        mm4, mm0, 11101110b        ;     x3 x1 x3 x1
  400.         pmaddwd        mm1, mm3                ;     w05*x2+w04*x0 w01*x2+w00*x0 == a1 a0
  401.  
  402.         movq        mm5, [round_inv_row]
  403.         pmaddwd        mm2, mm4                ;     w21*x3+w20*x1 w17*x3+w16*x1 == b1 b0
  404.  
  405.         pmaddwd        mm3, [%%table+8]            ;     w13*x2+w12*x0 w09*x2+w08*x0 == a3 a2
  406.         ;
  407.  
  408.         pmaddwd        mm4, [%%table+24]        ;     w29*x3+w28*x1 w25*x3+w24*x1 == b3 b2
  409.         paddd        mm1, mm5                ;     a1+r a0+r
  410.  
  411.         movq        mm6, mm1                ; mm6 = a1+r     a0+r
  412.         paddd        mm1, mm2                ; mm1 = a1+b1+r  a0+b0+r
  413.  
  414.         paddd        mm3, mm5                ; mm3 = a3+r     a2+r
  415.         psubd        mm6, mm2                ; mm6 = a1-b1+r  a0-b0+r
  416.  
  417.         movq        mm0, mm3                ; mm0 = a3+r     a2+r
  418.         psrad        mm1, SHIFT_INV_ROW        ; mm1 = y1       y0
  419.  
  420.         paddd        mm3, mm4                ; mm3 = a3+b3+r  a2+b2+r
  421.         psrad        mm6, SHIFT_INV_ROW        ; mm6 = y6       y7
  422.  
  423.         psubd        mm0, mm4                ; mm0 = a3-b3+r  a2-b2+r
  424.         psrad        mm3, SHIFT_INV_ROW        ; mm3 = y3       y2
  425.  
  426.         psrad        mm0, SHIFT_INV_ROW        ; mm0 = y4       y5
  427.  
  428.         packssdw    mm1, mm3                ; mm1 = y3 y2 y1 y0
  429.  
  430.         packssdw    mm6, mm0                ; mm0 = y4 y5 y6 y7
  431.  
  432.         movq        [%%out], mm1
  433.         pshufw        mm6, mm6, 00011011b        ; mm0 = y7 y6 y5 y4
  434.  
  435.         movq        [%%out+8], mm6
  436. %endmacro
  437.  
  438.  
  439. ;=============================================================================
  440. ;
  441. ; The second stage iDCT 8x8 - inverse DCTs of columns
  442. ;
  443. ; The outputs are premultiplied
  444. ; for rows 0,4 - on cos_4_16,
  445. ; for rows 1,7 - on cos_1_16,
  446. ; for rows 2,6 - on cos_2_16,
  447. ; for rows 3,5 - on cos_3_16
  448. ; and are shifted to the left for rise of accuracy
  449. ;
  450. ;-----------------------------------------------------------------------------
  451. ;
  452. ; The 8-point scaled inverse DCT algorithm (26a8m)
  453. ;
  454. ;-----------------------------------------------------------------------------
  455. ;
  456. ;    // Reorder and prescale (implicit)
  457. ;
  458. ;    ev0 = co[0] / 2.0;
  459. ;    ev1 = co[2] / 2.0;
  460. ;    ev2 = co[4] / 2.0;
  461. ;    ev3 = co[6] / 2.0;
  462. ;    od0 = co[1] / 2.0;
  463. ;    od1 = co[3] / 2.0;
  464. ;    od2 = co[5] / 2.0;
  465. ;    od3 = co[7] / 2.0;
  466. ;
  467. ;    // 5) Apply D8T (implicit in row calculation).
  468. ;
  469. ;    tmp[0] = ev0*LAMBDA(4);
  470. ;    tmp[1] = ev2*LAMBDA(4);
  471. ;    tmp[2] = ev1*LAMBDA(2);
  472. ;    tmp[3] = ev3*LAMBDA(2);
  473. ;    tmp[4] = od0*LAMBDA(1);
  474. ;    tmp[5] = od3*LAMBDA(1);
  475. ;    tmp[6] = od1*LAMBDA(3);
  476. ;    tmp[7] = od2*LAMBDA(3);
  477. ;
  478. ;    // 4) Apply B8T.
  479. ;
  480. ;    double x0, x1, x2, x3, y0, y1, y2, y3;
  481. ;
  482. ;    x0 = tmp[0] + tmp[1];
  483. ;    x1 = tmp[0] - tmp[1];
  484. ;    x2 = tmp[2] + TAN(2)*tmp[3];
  485. ;    x3 = tmp[2]*TAN(2) - tmp[3];
  486. ;    y0 = tmp[4] + TAN(1)*tmp[5];
  487. ;    y1 = tmp[4]*TAN(1) - tmp[5];
  488. ;    y2 = tmp[6] + TAN(3)*tmp[7];
  489. ;    y3 = tmp[6]*TAN(3) - tmp[7];
  490. ;
  491. ;    // 3) Apply E8T.
  492. ;    //
  493. ;    //    1  0  1  0
  494. ;    //    0  1  0  1
  495. ;    //    0  1  0 -1
  496. ;    //    1  0 -1  0
  497. ;    //            1  0  1  0
  498. ;    //            1  0 -1  0
  499. ;    //            0  1  0  1
  500. ;    //            0  1  0 -1
  501. ;
  502. ;    double e0, e1, e2, e3, o0, o1, o2, o3;
  503. ;
  504. ;    e0 = x0 + x2;
  505. ;    e1 = x1 + x3;
  506. ;    e2 = x1 - x3;
  507. ;    e3 = x0 - x2;
  508. ;    o0 = y0 + y2;
  509. ;    o1 = y0 - y2;
  510. ;    o2 = y1 + y3;
  511. ;    o3 = y1 - y3;
  512. ;
  513. ;    // 2) Apply F8T.
  514. ;
  515. ;    double a, b;
  516. ;
  517. ;    a = (o1 + o2) * LAMBDA(4);
  518. ;    b = (o1 - o2) * LAMBDA(4);
  519. ;
  520. ;    o1 = a;
  521. ;    o2 = b;
  522. ;
  523. ;    // 6) Apply output butterfly (A8T).
  524. ;    //
  525. ;    // 1 0 0 0  1  0  0  0
  526. ;    // 0 1 0 0  0  1  0  0
  527. ;    // 0 0 1 0  0  0  1  0
  528. ;    // 0 0 0 1  0  0  0  1
  529. ;    // 0 0 0 1  0  0  0 -1
  530. ;    // 0 0 1 0  0  0 -1  0
  531. ;    // 0 1 0 0  0 -1  0  0
  532. ;    // 1 0 0 0 -1  0  0  0
  533. ;
  534. ;    out[0] = e0 + o0;
  535. ;    out[1] = e1 + o1;
  536. ;    out[2] = e2 + o2;
  537. ;    out[3] = e3 + o3;
  538. ;    out[4] = e3 - o3;
  539. ;    out[5] = e2 - o2;
  540. ;    out[6] = e1 - o1;
  541. ;    out[7] = e0 - o0;
  542. ;
  543. ;=============================================================================
  544. %macro DCT_8_INV_COL_4 2
  545. %define    .inp    %1
  546. %define    .out    %2
  547.  
  548. %define .x0    [.inp + 0*16]
  549. %define .x1    [.inp + 1*16]
  550. %define .x2    [.inp + 2*16]
  551. %define .x3    [.inp + 3*16]
  552. %define .x4    [.inp + 4*16]
  553. %define .x5    [.inp + 5*16]
  554. %define .x6    [.inp + 6*16]
  555. %define .x7    [.inp + 7*16]
  556. %define .y0    [.out + 0*16]
  557. %define .y1    [.out + 1*16]
  558. %define .y2    [.out + 2*16]
  559. %define .y3    [.out + 3*16]
  560. %define .y4    [.out + 4*16]
  561. %define .y5    [.out + 5*16]
  562. %define .y6    [.out + 6*16]
  563. %define .y7    [.out + 7*16]
  564.  
  565.     ;======= optimized code
  566.  
  567.     ;ODD ELEMENTS
  568.  
  569.     movq    mm0, [tg_1_16]
  570.  
  571.     movq    mm2, [tg_3_16]
  572.     movq    mm3,mm0
  573.  
  574.     movq    mm1,.x7
  575.     movq    mm6,mm2
  576.  
  577.     movq    mm4,.x5
  578.     pmulhw    mm0,mm1
  579.  
  580.     movq    mm5,.x1
  581.     pmulhw    mm2,mm4
  582.  
  583.     movq    mm7,.x3
  584.     pmulhw    mm3,mm5
  585.  
  586.     pmulhw    mm6,mm7
  587.     paddw    mm0,mm5
  588.  
  589.     paddw    mm2,mm4
  590.     psubw    mm6,mm4
  591.  
  592.     paddw    mm2,mm7
  593.     psubw    mm3,mm1
  594.  
  595.     paddw    mm0, [one_corr]
  596.     paddw    mm6,mm7
  597.  
  598.     ;E8T butterfly - odd elements
  599.  
  600.     movq    mm1,mm0
  601.     movq    mm5,mm3
  602.     paddw    mm0,mm2        ;mm0 = o0 = y0 + y2
  603.     psubw    mm1,mm2        ;mm1 = o1 = y0 - y2
  604.     paddw    mm3,mm6        ;mm3 = o2 = y1 + y3
  605.     psubw    mm5,mm6        ;mm5 = o3 = y1 - y3
  606.  
  607.     ;F8T stage - odd elements
  608.  
  609.     movq    mm2,mm1
  610.     paddw    mm1,mm3            ;[F8T] mm1 = o1 + o2
  611.  
  612.     movq    mm4,.x0            ;[B8T1] mm3 = tmp[0]
  613.     psubw    mm2,mm3            ;[F8T] mm2 = o1 - o2
  614.  
  615.     movq    mm3,.x4
  616.     movq    mm6,mm2            ;[F8T]
  617.  
  618.     pmulhw    mm2, [cos_4_16]    ;[F8T]
  619.     movq    mm7,mm1            ;[F8T]
  620.  
  621.     pmulhw    mm1, [cos_4_16]    ;[F8T]
  622.     paddw    mm3,mm4            ;[B8T1] mm3 = x0 = tmp[0] + tmp[1]
  623.  
  624.     paddw    mm3, [round_inv_corr]    ;[E8T]
  625.     ;<v-pipe>
  626.  
  627.     psubw    mm4,.x4            ;[B8T1] mm4 = x1 = tmp[0] - tmp[1]
  628.     paddw    mm2,mm6            ;[F8T]
  629.  
  630.     por    mm1, [one_corr]    ;[F8T]
  631.     ;<v-pipe>
  632.  
  633.     movq    mm6,.x6            ;[B8T2] mm7 = tmp[3]
  634.     paddw    mm1,mm7            ;[F8T] mm1 = o1' = (o1 + o2)*LAMBDA(4)
  635.  
  636.     pmulhw    mm6, [tg_2_16]    ;mm7 = tmp[3] * TAN(2)
  637.     ;<v-pipe>
  638.  
  639.     movq    mm7, [one_corr]
  640.     ;<v-pipe>
  641.  
  642.     paddw    mm4, [round_inv_col]    ;[out]
  643.     psubw    mm2,mm7            ;[F8T] mm2 = o2' = (o1 - o2)*LAMBDA(4)
  644.  
  645.     paddw    mm6,.x2            ;[B8T2] mm7 = x2 = tmp[2] + tmp[3]*TAN(2)
  646.     paddw    mm7,mm3            ;[E8T]
  647.  
  648.     paddw    mm7,mm6            ;[E8T] mm6 = e0 = x0+x2
  649.     psubw    mm3,mm6            ;[E8T] mm3 = e3 = x0-x2
  650.  
  651.     ;output butterfly - 0 and 3
  652.  
  653.     movq    mm6,mm7        ;mm7 = e0
  654.     paddw    mm7,mm0        ;mm6 = e0 + o0
  655.  
  656.     psubw    mm6,mm0        ;mm7 = e0 - o0
  657.     psraw    mm7,SHIFT_INV_COL
  658.  
  659.     movq    mm0,mm3        ;mm7 = e3 
  660.     psraw    mm6,SHIFT_INV_COL
  661.  
  662.     movq    .y0,mm7
  663.     paddw    mm3,mm5        ;mm6 = e3 + o3
  664.  
  665.     movq    mm7,.x2        ;[B8T] mm6 = tmp[2]
  666.     psubw    mm0,mm5        ;[out] mm7 = e3 - o3
  667.  
  668.     movq    .y7,mm6
  669.     psraw    mm3,SHIFT_INV_COL
  670.  
  671.     pmulhw    mm7, [tg_2_16]        ;[B8T] mm6 = tmp[2] * TAN(2)
  672.     psraw    mm0,SHIFT_INV_COL
  673.  
  674.     movq    .y3,mm3
  675.     movq    mm6,mm4                ;[E8T]
  676.  
  677.     psubw    mm6, [one_corr]
  678.     ;<v-pipe>
  679.  
  680.  
  681.     ;B8T stage - x3 element
  682.     ;
  683.     ;free registers: 03567
  684.  
  685.     psubw    mm7,.x6                ;[B8T] mm6 = x3 = tmp[2]*TAN(2) - tmp[3]
  686.     movq    mm3,mm1
  687.  
  688.     ;E8T stage - x1 and x3 elements
  689.  
  690.     movq    .y4,mm0
  691.     paddw    mm4,mm7                ;[E8T] mm4 = e1 = x1+x3
  692.  
  693.     psubw    mm6,mm7                ;[E8T] mm7 = e2 = x1-x3
  694.     paddw    mm3,mm4                ;mm3 = e1 + o1
  695.  
  696.     psubw    mm4,mm1                ;mm4 = e1 - o1
  697.     psraw    mm3,SHIFT_INV_COL
  698.  
  699.     movq    mm5,mm6                ;mm6 = e2
  700.     psraw    mm4,SHIFT_INV_COL
  701.  
  702.     paddw    mm6,mm2                ;mm7 = e2 + o2
  703.     psubw    mm5,mm2                ;mm6 = e2 - o2
  704.  
  705.     movq    .y1,mm3
  706.     psraw    mm6,SHIFT_INV_COL
  707.  
  708.     movq    .y6,mm4
  709.     psraw    mm5,SHIFT_INV_COL
  710.  
  711.     movq    .y2,mm6
  712.  
  713.     movq    .y5,mm5
  714.  
  715. %endmacro
  716.  
  717. ;-----------------------------------------------------------------------------
  718. ;
  719. ; The half 8-point scaled inverse DCT algorithm (26a8m)
  720. ;
  721. ;-----------------------------------------------------------------------------
  722. ;
  723. ;    // Reorder and prescale (implicit)
  724. ;
  725. ;    ev0 = co[0] / 2.0;
  726. ;    ev1 = co[2] / 2.0;
  727. ;    od0 = co[1] / 2.0;
  728. ;    od1 = co[3] / 2.0;
  729. ;
  730. ;    // 5) Apply D8T (implicit in row calculation).
  731. ;
  732. ;    tmp[0] = ev0*LAMBDA(4);
  733. ;    tmp[2] = ev1*LAMBDA(2);
  734. ;    tmp[4] = od0*LAMBDA(1);
  735. ;    tmp[6] = od1*LAMBDA(3);
  736. ;
  737. ;    // 4) Apply B8T.
  738. ;
  739. ;    double x0, x1, x2, x3, y0, y1, y2, y3;
  740. ;
  741. ;    x0 = tmp[0];
  742. ;    x1 = tmp[0];
  743. ;    x2 = tmp[2];
  744. ;    x3 = tmp[2]*TAN(2);
  745. ;    y0 = tmp[4];
  746. ;    y1 = tmp[4]*TAN(1);
  747. ;    y2 = tmp[6];
  748. ;    y3 = tmp[6]*TAN(3);
  749. ;
  750. ;    // 3) Apply E8T.
  751. ;    //
  752. ;    //    1  0  1  0
  753. ;    //    0  1  0  1
  754. ;    //    0  1  0 -1
  755. ;    //    1  0 -1  0
  756. ;    //            1  0  1  0
  757. ;    //            1  0 -1  0
  758. ;    //            0  1  0  1
  759. ;    //            0  1  0 -1
  760. ;
  761. ;    double e0, e1, e2, e3, o0, o1, o2, o3;
  762. ;
  763. ;    e0 = x0 + x2;
  764. ;    e1 = x1 + x3;
  765. ;    e2 = x1 - x3;
  766. ;    e3 = x0 - x2;
  767. ;    o0 = y0 + y2;
  768. ;    o1 = y0 - y2;
  769. ;    o2 = y1 + y3;
  770. ;    o3 = y1 - y3;
  771. ;
  772. ;    // 2) Apply F8T.
  773. ;
  774. ;    double a, b;
  775. ;
  776. ;    a = (o1 + o2) * LAMBDA(4);
  777. ;    b = (o1 - o2) * LAMBDA(4);
  778. ;
  779. ;    o1 = a;
  780. ;    o2 = b;
  781. ;
  782. ;    // 6) Apply output butterfly (A8T).
  783. ;    //
  784. ;    // 1 0 0 0  1  0  0  0
  785. ;    // 0 1 0 0  0  1  0  0
  786. ;    // 0 0 1 0  0  0  1  0
  787. ;    // 0 0 0 1  0  0  0  1
  788. ;    // 0 0 0 1  0  0  0 -1
  789. ;    // 0 0 1 0  0  0 -1  0
  790. ;    // 0 1 0 0  0 -1  0  0
  791. ;    // 1 0 0 0 -1  0  0  0
  792. ;
  793. ;    out[0] = e0 + o0;
  794. ;    out[1] = e1 + o1;
  795. ;    out[2] = e2 + o2;
  796. ;    out[3] = e3 + o3;
  797. ;    out[4] = e3 - o3;
  798. ;    out[5] = e2 - o2;
  799. ;    out[6] = e1 - o1;
  800. ;    out[7] = e0 - o0;
  801. ;
  802. ;=============================================================================
  803.  
  804. %macro DCT_8_INV_COL_4_SHORT 2
  805. %define    .inp    %1
  806. %define    .out    %2
  807. %define .x0    [.inp + 0*16]
  808. %define .x1    [.inp + 1*16]
  809. %define .x2    [.inp + 2*16]
  810. %define .x3    [.inp + 3*16]
  811. %define .y0    [.out + 0*16]
  812. %define .y1    [.out + 1*16]
  813. %define .y2    [.out + 2*16]
  814. %define .y3    [.out + 3*16]
  815. %define .y4    [.out + 4*16]
  816. %define .y5    [.out + 5*16]
  817. %define .y6    [.out + 6*16]
  818. %define .y7    [.out + 7*16]
  819.  
  820.     ;======= optimized code
  821.  
  822.     ;ODD ELEMENTS
  823.  
  824.     movq    mm3, [tg_1_16]
  825.  
  826.     movq    mm0,.x1
  827.     movq    mm6, [tg_3_16]
  828.  
  829.     movq    mm2,.x3
  830.     pmulhw    mm3,mm0
  831.  
  832.     pmulhw    mm6,mm2
  833.  
  834.     paddw    mm0, [one_corr]
  835.     paddw    mm6,mm2
  836.  
  837.     ;E8T butterfly - odd elements
  838.  
  839.     movq    mm1,mm0
  840.     movq    mm5,mm3
  841.     paddw    mm0,mm2        ;mm0 = o0 = y0 + y2
  842.     psubw    mm1,mm2        ;mm1 = o1 = y0 - y2
  843.     paddw    mm3,mm6        ;mm3 = o2 = y1 + y3
  844.     psubw    mm5,mm6        ;mm5 = o3 = y1 - y3
  845.  
  846.     ;F8T stage - odd elements
  847.  
  848.     movq    mm2,mm1
  849.     paddw    mm1,mm3                    ;[F8T] mm1 = o1 + o2
  850.  
  851.     movq    mm4,.x0                    ;[B8T1] mm4 = x0 = x1 = tmp[0]
  852.     psubw    mm2,mm3                    ;[F8T] mm2 = o1 - o2
  853.  
  854.     movq    mm6,mm2                    ;[F8T]
  855.     movq    mm7,mm1                    ;[F8T]
  856.  
  857.     pmulhw    mm2, [cos_4_16]    ;[F8T]
  858.     movq    mm3,mm4                    ;[B8T1] mm3 = x0 = x1 = tmp[0]
  859.  
  860.     pmulhw    mm1, [cos_4_16]    ;[F8T]
  861.  
  862.     paddw    mm3, [round_inv_corr]    ;[E8T]
  863.     ;<v-pipe>
  864.  
  865.     paddw    mm4, [round_inv_col]    ;[out]
  866.     paddw    mm2,mm6                    ;[F8T]
  867.  
  868.     por        mm1, [one_corr]            ;[F8T]
  869.     ;<v-pipe>
  870.  
  871.     psubw    mm2, [one_corr]            ;[F8T] mm2 = o2' = (o1 - o2)*LAMBDA(4)
  872.     paddw    mm1,mm7                    ;[F8T] mm1 = o1' = (o1 + o2)*LAMBDA(4)
  873.  
  874.     movq    mm6,.x2                    ;[B8T2] mm7 = x2 = tmp[2]
  875.     movq    mm7,mm4                    ;[E8T]
  876.  
  877.     paddw    mm7,mm6                    ;[E8T] mm6 = e0 = x0+x2
  878.     psubw    mm3,mm6                    ;[E8T] mm3 = e3 = x0-x2
  879.  
  880.     ;output butterfly - 0 and 3
  881.  
  882.     movq    mm6,mm7        ;mm7 = e0
  883.     paddw    mm7,mm0        ;mm6 = e0 + o0
  884.  
  885.     psubw    mm6,mm0        ;mm7 = e0 - o0
  886.     psraw    mm7,SHIFT_INV_COL
  887.  
  888.     movq    mm0,mm3        ;mm7 = e3 
  889.     psraw    mm6,SHIFT_INV_COL
  890.  
  891.     movq    .y0,mm7
  892.     paddw    mm3,mm5        ;mm6 = e3 + o3
  893.  
  894.     movq    mm7,.x2        ;[B8T] mm6 = tmp[2]
  895.     psubw    mm0,mm5        ;[out] mm7 = e3 - o3
  896.  
  897.     movq    .y7,mm6
  898.     psraw    mm3,SHIFT_INV_COL
  899.  
  900.     pmulhw    mm7, [tg_2_16]        ;[B8T] mm6 = x3 = tmp[2] * TAN(2)
  901.     psraw    mm0,SHIFT_INV_COL
  902.  
  903.     movq    .y3,mm3
  904.     movq    mm6,mm4                ;[E8T]
  905.  
  906.     psubw    mm6, [one_corr]
  907.     ;<v-pipe>
  908.  
  909.  
  910.     ;B8T stage - x3 element
  911.     ;
  912.     ;free registers: 03567
  913.  
  914.     movq    mm3,mm1
  915.  
  916.     ;E8T stage - x1 and x3 elements
  917.  
  918.     movq    .y4,mm0
  919.     paddw    mm4,mm7                ;[E8T] mm4 = e1 = x1+x3
  920.  
  921.     psubw    mm6,mm7                ;[E8T] mm7 = e2 = x1-x3
  922.     paddw    mm3,mm4                ;mm3 = e1 + o1
  923.  
  924.     psubw    mm4,mm1                ;mm4 = e1 - o1
  925.     psraw    mm3,SHIFT_INV_COL
  926.  
  927.     movq    mm5,mm6                ;mm6 = e2
  928.     psraw    mm4,SHIFT_INV_COL
  929.  
  930.     paddw    mm6,mm2                ;mm7 = e2 + o2
  931.     psubw    mm5,mm2                ;mm6 = e2 - o2
  932.  
  933.     movq    .y1,mm3
  934.     psraw    mm6,SHIFT_INV_COL
  935.  
  936.     movq    .y6,mm4
  937.     psraw    mm5,SHIFT_INV_COL
  938.  
  939.     movq    .y2,mm6
  940.  
  941.     movq    .y5,mm5
  942. %endmacro
  943.  
  944.     segment    .text
  945.  
  946.     align    16
  947. dorow_7:    DCT_8_INV_ROW_1        eax+7*16, eax+7*16, tab_i_17
  948. dorow_6:    DCT_8_INV_ROW_1        eax+6*16, eax+6*16, tab_i_26
  949. dorow_5:    DCT_8_INV_ROW_1        eax+5*16, eax+5*16, tab_i_35
  950. dorow_4:    DCT_8_INV_ROW_1        eax+4*16, eax+4*16, tab_i_04
  951. dorow_3:    DCT_8_INV_ROW_1        eax+3*16, eax+3*16, tab_i_35
  952. dorow_2:    DCT_8_INV_ROW_1        eax+2*16, eax+2*16, tab_i_26
  953. dorow_1:    DCT_8_INV_ROW_1        eax+1*16, eax+1*16, tab_i_17
  954. dorow_0:    DCT_8_INV_ROW_1        eax+0*16, eax+0*16, tab_i_04
  955.  
  956.  
  957.     %if PROFILE
  958.     rdtsc
  959.     sub    eax,dword ptr last_tick
  960.     mov    edx,dword ptr total_tick2
  961.     cmp    eax,edx
  962.     cmovl    edx,eax
  963.     mov    dword ptr total_tick2,edx
  964.     rdtsc
  965.     mov    dword ptr last_tick,eax
  966.     mov    eax,[esp+4]
  967.     %endif
  968.  
  969.     mov    ecx,2
  970. lup:
  971.     DCT_8_INV_COL_4        eax, eax
  972.     add    eax,8
  973.     dec    ecx
  974.     jne    lup
  975.  
  976.     %if PROFILE
  977.     rdtsc
  978.     sub    eax, [last_tick]
  979.     mov    edx, [total_tick]
  980.     cmp    eax,edx
  981.     cmovl    edx,eax
  982.     mov    [total_tick], edx
  983.  
  984.     pushad
  985.     dec    [total_cnt]
  986.     jnz    nodump
  987.     mov    [total_cnt], 65536*16
  988.  
  989.     mov    [total_tick], 07fffffffh
  990.  
  991.     sub    esp,256
  992.     push    edx
  993.  
  994.     mov    eax, [total_tick2]
  995.     mov    [total_tick2], 07fffffffh
  996.  
  997.     push    eax
  998.  
  999.     push    profile_str
  1000.     lea        eax,[esp+20]
  1001.     push    eax
  1002.     call    _sprintf
  1003.     lea        eax,[esp+24]
  1004.     push    eax
  1005.     call    _OutputDebugStringA@4
  1006.     add        esp,256+16
  1007. nodump:
  1008.     popad
  1009.     %endif
  1010.  
  1011.     mov    edx,[esp+16]
  1012.     mov    eax,[esp+4]
  1013.     mov    ecx,[esp+8]
  1014.     jmp    dword [jump_tab + edx*4]
  1015.  
  1016.     global _IDCT_mmx    
  1017. _IDCT_mmx:
  1018.     %if PROFILE
  1019.     rdtsc
  1020.     mov        [last_tick], eax
  1021.     %endif
  1022.  
  1023.     mov        ecx,[esp+20]
  1024.     movzx    ecx,byte [pos_tab+ecx]
  1025.  
  1026.     mov        eax,[esp+4]
  1027.     jmp        dword [rowstart_tbl+ecx]
  1028.  
  1029.  
  1030.  
  1031.  
  1032.     global _IDCT_isse    
  1033. _IDCT_isse:
  1034.     %if PROFILE
  1035.     rdtsc
  1036.     mov        [last_tick], eax
  1037.     %endif
  1038.  
  1039.     mov        ecx,[esp+20]
  1040.     movzx    ecx,byte [pos_tab+ecx]
  1041.  
  1042.     mov    eax,[esp+4]
  1043.     jmp    dword [rowstart_tbl2+ecx]
  1044.  
  1045.     align    16
  1046. dorow_3is:
  1047.     prefetcht0    [tab_i_26_short]
  1048.     prefetcht0    [eax+2*16]
  1049.     DCT_8_INV_ROW_1_ISSE_SHORT    eax+3*16, eax+3*16, tab_i_35_short
  1050. ;    DCT_8_INV_ROW_1_ISSE    eax+3*16, eax+3*16, tab_i_35
  1051. dorow_2is:
  1052.     prefetcht0    [tab_i_17_short]
  1053.     prefetcht0    [eax+1*16]
  1054.     DCT_8_INV_ROW_1_ISSE_SHORT    eax+2*16, eax+2*16, tab_i_26_short
  1055. ;    DCT_8_INV_ROW_1_ISSE    eax+2*16, eax+2*16, tab_i_26
  1056. dorow_1is:
  1057.     prefetcht0    [tab_i_04_short]
  1058.     prefetcht0    [eax+0*16]
  1059.     DCT_8_INV_ROW_1_ISSE_SHORT    eax+1*16, eax+1*16, tab_i_17_short
  1060. ;    DCT_8_INV_ROW_1_ISSE    eax+1*16, eax+1*16, tab_i_17
  1061. dorow_0is:
  1062.     DCT_8_INV_ROW_1_ISSE_SHORT    eax+0*16, eax+0*16, tab_i_04_short
  1063. ;    DCT_8_INV_ROW_1_ISSE    eax+0*16, eax+0*16, tab_i_04
  1064.  
  1065.     mov    ecx,2
  1066. lup3:
  1067.     DCT_8_INV_COL_4_SHORT        eax, eax
  1068.     add    eax,8
  1069.     dec    ecx
  1070.     jne    lup3
  1071.     mov    edx,[esp+16]
  1072.     mov    eax,[esp+4]
  1073.     mov    ecx,[esp+8]
  1074.     jmp    dword [jump_tab + edx*4]
  1075.  
  1076.     align    16
  1077. dorow_7is:
  1078.         prefetcht0    [tab_i_26]
  1079.         prefetcht0    [tab_i_26+63]
  1080.         prefetcht0    [eax+6*16]
  1081.         DCT_8_INV_ROW_1_ISSE    eax+7*16, eax+7*16, tab_i_17
  1082. dorow_6is:
  1083.         prefetcht0    [tab_i_35]
  1084.         prefetcht0    [tab_i_35+63]
  1085.         prefetcht0    [eax+5*16]
  1086.         DCT_8_INV_ROW_1_ISSE    eax+6*16, eax+6*16, tab_i_26
  1087. dorow_5is:
  1088.         prefetcht0    [tab_i_04]
  1089.         prefetcht0    [tab_i_04+63]
  1090.         prefetcht0    [eax+4*16]
  1091.         DCT_8_INV_ROW_1_ISSE    eax+5*16, eax+5*16, tab_i_35
  1092. dorow_4is:
  1093.         prefetcht0    [tab_i_35]
  1094.         prefetcht0    [tab_i_35+63]
  1095.         prefetcht0    [eax+3*16]
  1096.         DCT_8_INV_ROW_1_ISSE    eax+4*16, eax+4*16, tab_i_04
  1097. ;dorow_3is:
  1098.         prefetcht0    [tab_i_26]
  1099.         prefetcht0    [tab_i_26+63]
  1100.         prefetcht0    [eax+2*16]
  1101.         DCT_8_INV_ROW_1_ISSE    eax+3*16, eax+3*16, tab_i_35
  1102. ;dorow_2is:
  1103.         prefetcht0    [tab_i_17]
  1104.         prefetcht0    [tab_i_17+63]
  1105.         prefetcht0    [eax+1*16]
  1106.         DCT_8_INV_ROW_1_ISSE    eax+2*16, eax+2*16, tab_i_26
  1107. ;dorow_1is:
  1108.         prefetcht0    [tab_i_04]
  1109.         prefetcht0    [tab_i_04+63]
  1110.         prefetcht0    [eax+0*16]
  1111.         DCT_8_INV_ROW_1_ISSE    eax+1*16, eax+1*16, tab_i_17
  1112. ;dorow_0is:
  1113.         DCT_8_INV_ROW_1_ISSE    eax+0*16, eax+0*16, tab_i_04
  1114.  
  1115.     %if PROFILE
  1116.         rdtsc
  1117.         sub        eax, [last_tick]
  1118.         mov        edx, [total_tick2]
  1119.         cmp        eax, edx
  1120.         cmovl    edx, eax
  1121.         mov        [total_tick2], edx
  1122.         rdtsc
  1123.         mov        [last_tick], eax
  1124.         mov        eax, [esp+4]
  1125.     %endif
  1126.  
  1127.     mov    ecx,2
  1128. lup2:
  1129.     DCT_8_INV_COL_4        eax, eax
  1130.     add    eax,8
  1131.     dec    ecx
  1132.     jne    lup2
  1133.  
  1134.     %if PROFILE
  1135.         rdtsc
  1136.         sub        eax, [last_tick]
  1137.         mov        edx, [total_tick]
  1138.         cmp        eax,edx
  1139.         cmovl    edx,eax
  1140.         mov        [total_tick], edx
  1141.  
  1142.         pushad
  1143.         dec        [total_cnt]
  1144.         jnz        nodump2
  1145.         mov        [total_cnt], 65536*16
  1146.  
  1147.         mov        [total_tick], 07fffffffh
  1148.  
  1149.         sub        esp,256
  1150.         push    edx
  1151.  
  1152.         mov        eax, [total_tick2]
  1153.         mov        [total_tick2], 07fffffffh
  1154.  
  1155.         push    eax
  1156.  
  1157.         push    offset profile_str
  1158.         lea        eax,[esp+20]
  1159.         push    eax
  1160.         call    _sprintf
  1161.         lea        eax,[esp+24]
  1162.         push    eax
  1163.         call    _OutputDebugStringA@4
  1164.         add        esp,256+16
  1165.     nodump2:
  1166.         popad
  1167.     %endif
  1168.  
  1169.     mov    edx,[esp+16]
  1170.     mov    eax,[esp+4]
  1171.     mov    ecx,[esp+8]
  1172.     jmp    dword [jump_tab + edx*4]
  1173.  
  1174.  
  1175.  
  1176.  
  1177.     align 16
  1178.  
  1179. tail_intra:
  1180.     mov        edx,-8*16
  1181.     pxor        mm7,mm7
  1182. intra_loop:
  1183.     movq        mm0,[eax+edx+8*16]
  1184.     movq        mm1,[eax+edx+8*16+8]
  1185.     packuswb    mm0,mm1
  1186.     movq        [ecx],mm0
  1187.     add        ecx,[esp+12]
  1188.     add        edx,16
  1189.     jne        intra_loop
  1190. tail_mjpeg:
  1191.     ret
  1192.  
  1193.     align        16
  1194. tail_inter:
  1195.     mov        edx,-8*16
  1196.     pxor        mm7,mm7
  1197. inter_loop:
  1198.     movq        mm0,[eax+edx+8*16]
  1199.     movq        mm1,[eax+edx+8*16+8]
  1200.     movq        mm2,[ecx]
  1201.     movq        mm3,mm2
  1202.     punpcklbw    mm2,mm7
  1203.     punpckhbw    mm3,mm7
  1204.     paddw        mm0,mm2
  1205.     paddw        mm1,mm3
  1206.     packuswb    mm0,mm1
  1207.     movq        [ecx],mm0
  1208.     add        ecx,[esp+12]
  1209.     add        edx,16
  1210.     jne        inter_loop
  1211.     ret
  1212.  
  1213. ;--------------------------------------------------------------------------
  1214.  
  1215.     align        16
  1216.  
  1217. do_dc_mmx:
  1218.     movd        mm0,dword [eax]
  1219.     pxor        mm1,mm1
  1220.     mov            edx,[esp+16]
  1221.     punpcklwd    mm0,mm0
  1222.     mov            ecx,[esp+8]        ;ecx = dst
  1223.     punpckldq    mm0,mm0
  1224.     cmp            edx, 1
  1225.     paddw        mm0, [rounder]
  1226.     mov            eax,[esp+12]        ;eax = pitch
  1227.     psraw        mm0,3
  1228.     jb            do_ac_mmx
  1229.     ja            do_dc_mjpeg
  1230.     packuswb    mm0,mm0
  1231.  
  1232.     movq        [ecx],mm0        ;row 0
  1233.     lea            edx,[eax+eax*2]
  1234.     movq        [ecx+eax],mm0        ;row 1
  1235.     add            edx,ecx
  1236.     movq        [ecx+eax*2],mm0        ;row 2
  1237.     lea            ecx,[ecx+eax*2]
  1238.     movq        [edx],mm0        ;row 3
  1239.     movq        [ecx+eax*2],mm0        ;row 4
  1240.     movq        [edx+eax*2],mm0        ;row 5
  1241.     movq        [ecx+eax*4],mm0        ;row 6
  1242.     movq        [edx+eax*4],mm0        ;row 7
  1243.     ret
  1244.  
  1245.     align        16
  1246. do_ac_mmx:
  1247.     psubw        mm1,mm0
  1248.     packuswb    mm0,mm0            ;mm0 = adder
  1249.     packuswb    mm1,mm1            ;mm1 = subtractor
  1250.  
  1251.     mov        edx,8
  1252. do_ac_mmx.loop:
  1253.     movq        mm2,[ecx]
  1254.     paddusb        mm2,mm0
  1255.     psubusb        mm2,mm1
  1256.     movq        [ecx],mm2
  1257.     add        ecx,eax
  1258.     dec        edx
  1259.     jne        do_ac_mmx.loop
  1260.     ret
  1261.  
  1262. ;--------------------------------------------------------------------------
  1263.  
  1264. do_dc_isse:
  1265.     pshufw        mm0,[eax],0
  1266.     pxor        mm1,mm1
  1267.     mov            edx,[esp+16]
  1268.     paddw        mm0, [rounder]
  1269.     mov            ecx,[esp+8]        ;ecx = dst
  1270.     psraw        mm0,3
  1271.     cmp            edx, 1
  1272.     mov            eax,[esp+12]        ;eax = pitch
  1273.     jb            do_ac_isse
  1274.     ja            do_dc_mjpeg
  1275.     packuswb    mm0,mm0
  1276.  
  1277.     movq        [ecx],mm0        ;row 0
  1278.     lea            edx,[eax+eax*2]
  1279.     movq        [ecx+eax],mm0        ;row 1
  1280.     add            edx,ecx
  1281.     movq        [ecx+eax*2],mm0        ;row 2
  1282.     lea            ecx,[ecx+eax*2]
  1283.     movq        [edx],mm0        ;row 3
  1284.     movq        [ecx+eax*2],mm0        ;row 4
  1285.     movq        [edx+eax*2],mm0        ;row 5
  1286.     movq        [ecx+eax*4],mm0        ;row 6
  1287.     movq        [edx+eax*4],mm0        ;row 7
  1288.     ret
  1289.  
  1290.     align        16
  1291. do_ac_isse:
  1292.     psubw        mm1,mm0
  1293.     packuswb    mm0,mm0            ;mm0 = adder
  1294.     packuswb    mm1,mm1            ;mm1 = subtractor
  1295.  
  1296.     mov        edx,8
  1297. do_ac_isse.loop:
  1298.     movq        mm2,[ecx]
  1299.     paddusb        mm2,mm0
  1300.     psubusb        mm2,mm1
  1301.     movq        [ecx],mm2
  1302.     add        ecx,eax
  1303.     dec        edx
  1304.     jne        do_ac_mmx.loop
  1305.     ret
  1306.  
  1307. do_dc_mjpeg:
  1308.     movq        [ecx],mm0        ;row 0
  1309.     movq        [ecx+8],mm0        ;row 0
  1310.     lea        edx,[eax+eax*2]
  1311.     movq        [ecx+eax],mm0        ;row 1
  1312.     movq        [ecx+eax+8],mm0        ;row 1
  1313.     add        edx,ecx
  1314.     movq        [ecx+eax*2],mm0        ;row 2
  1315.     movq        [ecx+eax*2+8],mm0    ;row 2
  1316.     lea        ecx,[ecx+eax*2]
  1317.     movq        [edx],mm0        ;row 3
  1318.     movq        [edx+8],mm0        ;row 3
  1319.     movq        [ecx+eax*2],mm0        ;row 4
  1320.     movq        [ecx+eax*2+8],mm0    ;row 4
  1321.     movq        [edx+eax*2],mm0        ;row 5
  1322.     movq        [edx+eax*2+8],mm0    ;row 5
  1323.     movq        [ecx+eax*4],mm0        ;row 6
  1324.     movq        [ecx+eax*4+8],mm0    ;row 6
  1325.     movq        [edx+eax*4],mm0        ;row 7
  1326.     movq        [edx+eax*4+8],mm0    ;row 7
  1327.     ret
  1328.  
  1329.     end
  1330.