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 / a64_idct_sse2.asm < prev    next >
Encoding:
Assembly Source File  |  2009-09-14  |  24.6 KB  |  891 lines

  1. ;    VirtualDub - Video processing and capture application
  2. ;    Copyright (C) 1998-2004 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. ;This code is based on the fragments from the Intel Application Note AP-922.
  19. ;
  20. ;Apologies to Intel; Adobe Acrobat screws up formatting royally.
  21. ;
  22. ;
  23. ;
  24. ;IEEE-1180 results:
  25. ;    pmse      mse       pme      me
  26. ;1    0.018000, 0.013742, 0.003100,-0.000083
  27. ;2    0.018600, 0.013573, 0.003300, 0.000217
  28. ;3    0.014100, 0.011441, 0.003900, 0.000106
  29. ;4    0.017900, 0.013700, 0.004500, 0.000056
  30. ;5    0.018300, 0.013623, 0.004900,-0.000239
  31. ;6    0.014000, 0.011439, 0.003600,-0.000117
  32.  
  33.     default rel
  34.  
  35. ;=============================================================================
  36. ;
  37. ; These examples contain code fragments for first stage iDCT 8x8
  38. ; (for rows) and first stage DCT 8x8 (for columns)
  39. ;
  40. ;=============================================================================
  41.  
  42. BITS_INV_ACC    equ 4            ; 4 or 5 for IEEE
  43. SHIFT_INV_ROW    equ 16 - BITS_INV_ACC
  44. SHIFT_INV_COL    equ 1 + BITS_INV_ACC
  45. RND_INV_ROW        equ 1024 * (6 - BITS_INV_ACC) ; 1 << (SHIFT_INV_ROW-1)
  46. RND_INV_COL        equ 16 * (BITS_INV_ACC - 3) ; 1 << (SHIFT_INV_COL-1)
  47. RND_INV_CORR    equ RND_INV_COL - 1 ; correction -1.0 and round
  48.  
  49.     segment    .rdata, align=16
  50.         Align    16
  51.  
  52. rounder            dw    4, 4, 4, 4
  53.                 dw    0,0,0,0
  54. round_inv_row    dd    RND_INV_ROW, RND_INV_ROW, RND_INV_ROW, RND_INV_ROW
  55. one_corr        dw    1, 1, 1, 1, 1, 1, 1, 1
  56.  
  57. round_inv_col    dw    RND_INV_COL, RND_INV_COL, RND_INV_COL, RND_INV_COL, 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, RND_INV_CORR, RND_INV_CORR, RND_INV_CORR, RND_INV_CORR
  59. tg_1_16        dw    13036, 13036, 13036, 13036, 13036, 13036, 13036, 13036    ; tg * (2<<16)
  60. tg_2_16        dw    27146, 27146, 27146, 27146, 27146, 27146, 27146, 27146    ; tg * (2<<16)
  61. tg_3_16        dw    -21746, -21746, -21746, -21746, -21746, -21746, -21746, -21746    ; tg * (2<<16) - 1.0
  62. cos_4_16    dw    -19195, -19195, -19195, -19195, -19195, -19195, -19195, -19195    ; cos * (2<<16) - 1.0
  63. ocos_4_16    dw    23170, 23170, 23170, 23170, 23170, 23170, 23170, 23170    ; cos * (2<<15) + 0.5
  64. ucos_4_16    dw    46341, 46341, 46341, 46341, 46341, 46341, 46341, 46341    ; cos * (2<<16)
  65.  
  66. jump_tab    dq    tail_inter, tail_intra, tail_mjpeg,0
  67.  
  68.  
  69. ;=============================================================================
  70. ;
  71. ; The first stage iDCT 8x8 - inverse DCTs of rows
  72. ;
  73. ;-----------------------------------------------------------------------------
  74. ; The 8-point inverse DCT direct algorithm
  75. ;-----------------------------------------------------------------------------
  76. ;
  77. ; static const short w[32] = {
  78. ; FIX(cos_4_16), FIX(cos_2_16), FIX(cos_4_16), FIX(cos_6_16),
  79. ; FIX(cos_4_16), FIX(cos_6_16), -FIX(cos_4_16), -FIX(cos_2_16),
  80. ; FIX(cos_4_16), -FIX(cos_6_16), -FIX(cos_4_16), FIX(cos_2_16),
  81. ; FIX(cos_4_16), -FIX(cos_2_16), FIX(cos_4_16), -FIX(cos_6_16),
  82. ; FIX(cos_1_16), FIX(cos_3_16), FIX(cos_5_16), FIX(cos_7_16),
  83. ; FIX(cos_3_16), -FIX(cos_7_16), -FIX(cos_1_16), -FIX(cos_5_16),
  84. ; FIX(cos_5_16), -FIX(cos_1_16), FIX(cos_7_16), FIX(cos_3_16),
  85. ; FIX(cos_7_16), -FIX(cos_5_16), FIX(cos_3_16), -FIX(cos_1_16) };
  86. ;
  87. ; #define DCT_8_INV_ROW(x, y)
  88. ;{
  89. ; int a0, a1, a2, a3, b0, b1, b2, b3;
  90. ;
  91. ; a0 =x[0]*w[0]+x[2]*w[1]+x[4]*w[2]+x[6]*w[3];
  92. ; a1 =x[0]*w[4]+x[2]*w[5]+x[4]*w[6]+x[6]*w[7];
  93. ; a2 = x[0] * w[ 8] + x[2] * w[ 9] + x[4] * w[10] + x[6] * w[11];
  94. ; a3 = x[0] * w[12] + x[2] * w[13] + x[4] * w[14] + x[6] * w[15];
  95. ; b0 = x[1] * w[16] + x[3] * w[17] + x[5] * w[18] + x[7] * w[19];
  96. ; b1 = x[1] * w[20] + x[3] * w[21] + x[5] * w[22] + x[7] * w[23];
  97. ; b2 = x[1] * w[24] + x[3] * w[25] + x[5] * w[26] + x[7] * w[27];
  98. ; b3 = x[1] * w[28] + x[3] * w[29] + x[5] * w[30] + x[7] * w[31];
  99. ;
  100. ; y[0] = SHIFT_ROUND ( a0 + b0 );
  101. ; y[1] = SHIFT_ROUND ( a1 + b1 );
  102. ; y[2] = SHIFT_ROUND ( a2 + b2 );
  103. ; y[3] = SHIFT_ROUND ( a3 + b3 );
  104. ; y[4] = SHIFT_ROUND ( a3 - b3 );
  105. ; y[5] = SHIFT_ROUND ( a2 - b2 );
  106. ; y[6] = SHIFT_ROUND ( a1 - b1 );
  107. ; y[7] = SHIFT_ROUND ( a0 - b0 );
  108. ;}
  109. ;
  110. ;-----------------------------------------------------------------------------
  111. ;
  112. ; In this implementation the outputs of the iDCT-1D are multiplied
  113. ; for rows 0,4 - by cos_4_16,
  114. ; for rows 1,7 - by cos_1_16,
  115. ; for rows 2,6 - by cos_2_16,
  116. ; for rows 3,5 - by cos_3_16
  117. ; and are shifted to the left for better accuracy
  118. ;
  119. ; For the constants used,
  120. ; FIX(float_const) = (short) (float_const * (1<<15) + 0.5)
  121. ;
  122. ;=============================================================================
  123.  
  124.         align 16
  125.  
  126. ; Table for rows 0,4 - constants are multiplied by cos_4_16
  127. ; Table for rows 1,7 - constants are multiplied by cos_1_16
  128. ; Table for rows 2,6 - constants are multiplied by cos_2_16
  129. ; Table for rows 3,5 - constants are multiplied by cos_3_16
  130.  
  131. tabbase:
  132. tab_i_04_short    dw  16384,  21407,  16384,   8864,  16384,  -8867,  16384, -21407    ; w00 w01 w04 w05 w08 w09 w12 w13
  133.                 dw  22725,  19266,  19266,  -4525,  12873, -22725,   4520, -12873    ; w16 w17 w20 w21 w24 w25 w28 w29
  134. tab_i_17_short    dw  22725,  29692,  22725,  12295,  22725, -12299,  22725, -29692    ; w00 w01 w04 w05 w08 w09 w12 w13
  135.                 dw  31521,  26722,  26722,  -6271,  17855, -31521,   6270, -17855    ; w16 w17 w20 w21 w24 w25 w28 w29
  136. tab_i_26_short    dw  21407,  27969,  21407,  11587,  21407, -11585,  21407, -27969    ; w00 w01 w04 w05 w08 w09 w12 w13
  137.                 dw  29692,  25172,  25172,  -5902,  16819, -29692,   5906, -16819    ; w16 w17 w20 w21 w24 w25 w28 w29
  138. tab_i_35_short    dw  19266,  25172,  19266,  10426,  19266, -10426,  19266, -25172    ; w00 w01 w04 w05 w08 w09 w12 w13
  139.                 dw  26722,  22654,  22654,  -5312,  15137, -26722,   5315, -15137    ; w16 w17 w20 w21 w24 w25 w28 w29
  140.  
  141.  
  142. ; Table for rows 0,4 - constants are multiplied by cos_4_16
  143. ; Table for rows 1,7 - constants are multiplied by cos_1_16
  144. ; Table for rows 2,6 - constants are multiplied by cos_2_16
  145. ; Table for rows 3,5 - constants are multiplied by cos_3_16
  146.  
  147. tab_i_04    dw  16384,  21407, -16387, -21407,  16384,  -8867,  16384,  -8867    ; w00 w01 w06 w07 w08 w09 w14 w15
  148.             dw  16384,   8867,  16384,   8864, -16384,  21407,  16384, -21407    ; w02 w03 w04 w05 w10 w11 w12 w13
  149.             dw  22725,  19266, -22720, -12873,  12873, -22725,  19266, -22725    ; w16 w17 w22 w23 w24 w25 w30 w31
  150.             dw  12873,   4520,  19266,  -4525,   4520,  19266,   4520, -12873    ; w18 w19 w20 w21 w26 w27 w28 w29
  151. tab_i_17    dw  22725,  29692, -22729, -29692,  22725, -12299,  22725, -12299    ; w00 w01 w06 w07 w08 w09 w14 w15
  152.             dw  22725,  12299,  22725,  12295, -22725,  29692,  22725, -29692    ; w02 w03 w04 w05 w10 w11 w12 w13
  153.             dw  31521,  26722, -31520, -17855,  17855, -31521,  26722, -31521    ; w16 w17 w22 w23 w24 w25 w30 w31
  154.             dw  17855,   6270,  26722,  -6271,   6270,  26722,   6270, -17855    ; w18 w19 w20 w21 w26 w27 w28 w29
  155. tab_i_26    dw  21407,  27969, -21405, -27969,  21407, -11585,  21407, -11585    ; w00 w01 w06 w07 w08 w09 w14 w15
  156.             dw  21407,  11585,  21407,  11587, -21407,  27969,  21407, -27969    ; w02 w03 w04 w05 w10 w11 w12 w13
  157.             dw  29692,  25172, -29696, -16819,  16819, -29692,  25172, -29692    ; w16 w17 w22 w23 w24 w25 w30 w31
  158.             dw  16819,   5906,  25172,  -5902,   5906,  25172,   5906, -16819    ; w18 w19 w20 w21 w26 w27 w28 w29
  159. tab_i_35    dw  19266,  25172, -19266, -25172,  19266, -10426,  19266, -10426    ; w00 w01 w06 w07 w08 w09 w14 w15
  160.             dw  19266,  10426,  19266,  10426, -19266,  25172,  19266, -25172    ; w02 w03 w04 w05 w10 w11 w12 w13
  161.             dw  26722,  22654, -26725, -15137,  15137, -26722,  22654, -26722    ; w16 w17 w22 w23 w24 w25 w30 w31
  162.             dw  15137,   5315,  22654,  -5312,   5315,  22654,   5315, -15137    ; w18 w19 w20 w21 w26 w27 w28 w29
  163.  
  164. rowstart_tbl2    dq    dorow_7is
  165.         dq    dorow_6is
  166.         dq    dorow_5is
  167.         dq    dorow_4is
  168.         dq    dorow_3is
  169.         dq    dorow_2is
  170.         dq    dorow_1is
  171.         dq    dorow_0is
  172.         dq    do_dc_sse2
  173.  
  174. pos_tab    times     1 db (8*8)        ;pos 0:     DC only
  175.         times     1 db (7*8)        ;pos 1:     1 AC row
  176.         times     1 db (6*8)        ;pos 2:     2 AC rows
  177.         times     6 db (5*8)        ;pos 3-8:   3 AC rows
  178.         times     1 db (4*8)        ;pos 9:     4 AC rows
  179.         times    10 db (3*8)        ;pos 10-19: 5 AC rows
  180.         times     1 db (2*8)        ;pos 20:    6 AC rows
  181.         times    14 db (1*8)        ;pos 21-34:    7 AC rows
  182.         times    29 db (0*8)        ;pos 35-63: 8 AC rows
  183.  
  184.  
  185. ;-----------------------------------------------------------------------------
  186.  
  187. %macro DCT_8_INV_ROW_1_SSE2 3
  188. %define %%inp %1
  189. %define %%out %2
  190. %define %%table %3
  191.         movdqa        xmm0, [%%inp]    ;xmm0 = x7 x5 x3 x1 x6 x4 x2 x0
  192.         pshufd        xmm1, xmm0, 00010001b    ;xmm1 = x2 x0 x6 x4 x2 x0 x6 x4
  193.         pshufd        xmm2, xmm0, 11101110b    ;xmm2 = x7 x5 x3 x1 x7 x5 x3 x1
  194.         pshufd        xmm3, xmm0, 10111011b    ;xmm3 = x3 x1 x7 x5 x3 x1 x7 x5
  195.         pshufd        xmm0, xmm0, 01000100b    ;xmm0 = x6 x4 x2 x0 x6 x4 x2 x0
  196.  
  197.         pmaddwd        xmm0, [%%table+00h]
  198.         pmaddwd        xmm1, [%%table+10h]
  199.         pmaddwd        xmm2, [%%table+20h]
  200.         pmaddwd        xmm3, [%%table+30h]
  201.  
  202.         paddd        xmm0, [rax + (round_inv_row - tabbase)]
  203.         paddd        xmm0, xmm1                ;xmm0 = y3 y2 y1 y0
  204.         paddd        xmm2, xmm3                ;xmm2 = y4 y5 y6 y7
  205.         movdqa        xmm1, xmm0
  206.         paddd        xmm0, xmm2                ;xmm0 = z3 z2 z1 z0
  207.         psubd        xmm1, xmm2                ;xmm1 = z4 z5 z6 z7
  208.         psrad        xmm0, SHIFT_INV_ROW
  209.         psrad        xmm1, SHIFT_INV_ROW
  210.         packssdw    xmm0, xmm1
  211.         pshufhw        xmm0, xmm0, 00011011b
  212.  
  213.         movdqa        [%%out], xmm0
  214. %endmacro
  215.  
  216. %macro DCT_8_INV_ROW_1_SSE2_SHORT 3
  217. %define %%inp %1
  218. %define %%out %2
  219. %define %%table %3
  220.         movdqa        xmm0, [%%inp]        ;xmm0 = -- -- x3 x1 -- -- x2 x0
  221.         pshufd        xmm2, xmm0, 10101010b    ;xmm2 = x3 x1 x3 x1 x3 x1 x3 x1
  222.         pshufd        xmm0, xmm0, 00000000b    ;xmm0 = x2 x0 x2 x0 x2 x0 x2 x0
  223.         pmaddwd        xmm0, [%%table+00h]    ;xmm0 = y3 y2 y1 y0
  224.         pmaddwd        xmm2, [%%table+10h]    ;xmm2 = y4 y5 y6 y7
  225.         paddd        xmm0, [rax + (round_inv_row - tabbase)]
  226.         movdqa        xmm1, xmm0
  227.         paddd        xmm0, xmm2                ;xmm0 = z3 z2 z1 z0
  228.         psubd        xmm1, xmm2                ;xmm1 = z4 z5 z6 z7
  229.         psrad        xmm0, SHIFT_INV_ROW
  230.         psrad        xmm1, SHIFT_INV_ROW
  231.         packssdw    xmm0, xmm1
  232.         pshufhw        xmm0, xmm0, 00011011b
  233.  
  234.         movdqa        [%%out], xmm0
  235. %endmacro
  236.  
  237.  
  238. ;=============================================================================
  239. ;
  240. ; The second stage iDCT 8x8 - inverse DCTs of columns
  241. ;
  242. ; The outputs are premultiplied
  243. ; for rows 0,4 - on cos_4_16,
  244. ; for rows 1,7 - on cos_1_16,
  245. ; for rows 2,6 - on cos_2_16,
  246. ; for rows 3,5 - on cos_3_16
  247. ; and are shifted to the left for rise of accuracy
  248. ;
  249. ;-----------------------------------------------------------------------------
  250. ;
  251. ; The 8-point scaled inverse DCT algorithm (26a8m)
  252. ;
  253. ;-----------------------------------------------------------------------------
  254. ;
  255. ;    // Reorder and prescale (implicit)
  256. ;
  257. ;    ev0 = co[0] / 2.0;
  258. ;    ev1 = co[2] / 2.0;
  259. ;    ev2 = co[4] / 2.0;
  260. ;    ev3 = co[6] / 2.0;
  261. ;    od0 = co[1] / 2.0;
  262. ;    od1 = co[3] / 2.0;
  263. ;    od2 = co[5] / 2.0;
  264. ;    od3 = co[7] / 2.0;
  265. ;
  266. ;    // 5) Apply D8T (implicit in row calculation).
  267. ;
  268. ;    tmp[0] = ev0*LAMBDA(4);
  269. ;    tmp[1] = ev2*LAMBDA(4);
  270. ;    tmp[2] = ev1*LAMBDA(2);
  271. ;    tmp[3] = ev3*LAMBDA(2);
  272. ;    tmp[4] = od0*LAMBDA(1);
  273. ;    tmp[5] = od3*LAMBDA(1);
  274. ;    tmp[6] = od1*LAMBDA(3);
  275. ;    tmp[7] = od2*LAMBDA(3);
  276. ;
  277. ;    // 4) Apply B8T.
  278. ;
  279. ;    double x0, x1, x2, x3, y0, y1, y2, y3;
  280. ;
  281. ;    x0 = tmp[0] + tmp[1];
  282. ;    x1 = tmp[0] - tmp[1];
  283. ;    x2 = tmp[2] + TAN(2)*tmp[3];
  284. ;    x3 = tmp[2]*TAN(2) - tmp[3];
  285. ;    y0 = tmp[4] + TAN(1)*tmp[5];
  286. ;    y1 = tmp[4]*TAN(1) - tmp[5];
  287. ;    y2 = tmp[6] + TAN(3)*tmp[7];
  288. ;    y3 = tmp[6]*TAN(3) - tmp[7];
  289. ;
  290. ;    // 3) Apply E8T.
  291. ;    //
  292. ;    //    1  0  1  0
  293. ;    //    0  1  0  1
  294. ;    //    0  1  0 -1
  295. ;    //    1  0 -1  0
  296. ;    //            1  0  1  0
  297. ;    //            1  0 -1  0
  298. ;    //            0  1  0  1
  299. ;    //            0  1  0 -1
  300. ;
  301. ;    double e0, e1, e2, e3, o0, o1, o2, o3;
  302. ;
  303. ;    e0 = x0 + x2;
  304. ;    e1 = x1 + x3;
  305. ;    e2 = x1 - x3;
  306. ;    e3 = x0 - x2;
  307. ;    o0 = y0 + y2;
  308. ;    o1 = y0 - y2;
  309. ;    o2 = y1 + y3;
  310. ;    o3 = y1 - y3;
  311. ;
  312. ;    // 2) Apply F8T.
  313. ;
  314. ;    double a, b;
  315. ;
  316. ;    a = (o1 + o2) * LAMBDA(4);
  317. ;    b = (o1 - o2) * LAMBDA(4);
  318. ;
  319. ;    o1 = a;
  320. ;    o2 = b;
  321. ;
  322. ;    // 6) Apply output butterfly (A8T).
  323. ;    //
  324. ;    // 1 0 0 0  1  0  0  0
  325. ;    // 0 1 0 0  0  1  0  0
  326. ;    // 0 0 1 0  0  0  1  0
  327. ;    // 0 0 0 1  0  0  0  1
  328. ;    // 0 0 0 1  0  0  0 -1
  329. ;    // 0 0 1 0  0  0 -1  0
  330. ;    // 0 1 0 0  0 -1  0  0
  331. ;    // 1 0 0 0 -1  0  0  0
  332. ;
  333. ;    out[0] = e0 + o0;
  334. ;    out[1] = e1 + o1;
  335. ;    out[2] = e2 + o2;
  336. ;    out[3] = e3 + o3;
  337. ;    out[4] = e3 - o3;
  338. ;    out[5] = e2 - o2;
  339. ;    out[6] = e1 - o1;
  340. ;    out[7] = e0 - o0;
  341. ;
  342. ;=============================================================================
  343. %macro DCT_8_INV_COL 2
  344. %define %%inp %1
  345. %define %%out %2
  346.  
  347. %define    %%x0    [%%inp + 0*16]
  348. %define    %%x1    [%%inp + 1*16]
  349. %define    %%x2    [%%inp + 2*16]
  350. %define    %%x3    [%%inp + 3*16]
  351. %define    %%x4    [%%inp + 4*16]
  352. %define    %%x5    [%%inp + 5*16]
  353. %define    %%x6    [%%inp + 6*16]
  354. %define    %%x7    [%%inp + 7*16]
  355. %define    %%y0    [%%out + 0*16]
  356. %define    %%y1    [%%out + 1*16]
  357. %define    %%y2    [%%out + 2*16]
  358. %define    %%y3    [%%out + 3*16]
  359. %define    %%y4    [%%out + 4*16]
  360. %define    %%y5    [%%out + 5*16]
  361. %define    %%y6    [%%out + 6*16]
  362. %define    %%y7    [%%out + 7*16]
  363.  
  364.     ;======= optimized    segment    .text
  365.  
  366.     ;ODD ELEMENTS
  367.  
  368.     movdqa    xmm0, [rax + (tg_1_16 - tabbase)]
  369.  
  370.     movdqa    xmm2, [rax + (tg_3_16 - tabbase)]
  371.     movdqa    xmm3,xmm0
  372.  
  373.     movdqa    xmm1,%%x7
  374.     movdqa    xmm6,xmm2
  375.  
  376.     movdqa    xmm4,%%x5
  377.     pmulhw    xmm0,xmm1
  378.  
  379.     movdqa    xmm5,%%x1
  380.     pmulhw    xmm2,xmm4
  381.  
  382.     movdqa    xmm7,%%x3
  383.     pmulhw    xmm3,xmm5
  384.  
  385.     pmulhw    xmm6,xmm7
  386.     paddw    xmm0,xmm5
  387.  
  388.     paddw    xmm2,xmm4
  389.     psubw    xmm6,xmm4
  390.  
  391.     paddw    xmm2,xmm7
  392.     psubw    xmm3,xmm1
  393.  
  394.     paddw    xmm0, [rax + (one_corr - tabbase)]
  395.     paddw    xmm6,xmm7
  396.  
  397.     ;E8T butterfly - odd elements
  398.  
  399.     movdqa    xmm1,xmm0
  400.     movdqa    xmm5,xmm3
  401.     paddw    xmm0,xmm2        ;xmm0 = o0 = y0 + y2
  402.     psubw    xmm1,xmm2        ;xmm1 = o1 = y0 - y2
  403.     paddw    xmm3,xmm6        ;xmm3 = o2 = y1 + y3
  404.     psubw    xmm5,xmm6        ;xmm5 = o3 = y1 - y3
  405.  
  406.     ;F8T stage - odd elements
  407.  
  408.     movdqa    xmm2,xmm1
  409.     paddw    xmm1,xmm3            ;[F8T] xmm1 = o1 + o2
  410.  
  411.     movdqa    xmm4,%%x0            ;[B8T1] xmm3 = tmp[0]
  412.     psubw    xmm2,xmm3            ;[F8T] xmm2 = o1 - o2
  413.  
  414.     movdqa    xmm3,%%x4
  415.     movdqa    xmm6,xmm2            ;[F8T]
  416.  
  417.     pmulhw    xmm2, [rax + (cos_4_16 - tabbase)]    ;[F8T]
  418.     movdqa    xmm7,xmm1            ;[F8T]
  419.  
  420.     pmulhw    xmm1, [rax + (cos_4_16 - tabbase)]    ;[F8T]
  421.     paddw    xmm3,xmm4            ;[B8T1] xmm3 = x0 = tmp[0] + tmp[1]
  422.  
  423.     paddw    xmm3, [rax + (round_inv_corr - tabbase)]    ;[E8T]
  424.     ;<v-pipe>
  425.  
  426.     psubw    xmm4,%%x4            ;[B8T1] xmm4 = x1 = tmp[0] - tmp[1]
  427.     paddw    xmm2,xmm6            ;[F8T]
  428.  
  429.     por    xmm1,oword [one_corr]    ;[F8T]
  430.     ;<v-pipe>
  431.  
  432.     movdqa    xmm6,%%x6            ;[B8T2] xmm7 = tmp[3]
  433.     paddw    xmm1,xmm7            ;[F8T] xmm1 = o1' = (o1 + o2)*LAMBDA(4)
  434.  
  435.     pmulhw    xmm6, [rax + (tg_2_16 - tabbase)]    ;xmm7 = tmp[3] * TAN(2)
  436.     ;<v-pipe>
  437.  
  438.     movdqa    xmm7, [rax + (one_corr - tabbase)]
  439.     ;<v-pipe>
  440.  
  441.     paddw    xmm4, [rax + (round_inv_col - tabbase)]    ;[out]
  442.     psubw    xmm2,xmm7            ;[F8T] xmm2 = o2' = (o1 - o2)*LAMBDA(4)
  443.  
  444.     paddw    xmm6,%%x2            ;[B8T2] xmm7 = x2 = tmp[2] + tmp[3]*TAN(2)
  445.     paddw    xmm7,xmm3            ;[E8T]
  446.  
  447.     paddw    xmm7,xmm6            ;[E8T] xmm6 = e0 = x0+x2
  448.     psubw    xmm3,xmm6            ;[E8T] xmm3 = e3 = x0-x2
  449.  
  450.     ;output butterfly - 0 and 3
  451.  
  452.     movdqa    xmm6,xmm7        ;xmm7 = e0
  453.     paddw    xmm7,xmm0        ;xmm6 = e0 + o0
  454.  
  455.     psubw    xmm6,xmm0        ;xmm7 = e0 - o0
  456.     psraw    xmm7,SHIFT_INV_COL
  457.  
  458.     movdqa    xmm0,xmm3        ;xmm7 = e3 
  459.     psraw    xmm6,SHIFT_INV_COL
  460.  
  461.     movdqa    %%y0,xmm7
  462.     paddw    xmm3,xmm5        ;xmm6 = e3 + o3
  463.  
  464.     movdqa    xmm7,%%x2        ;[B8T] xmm6 = tmp[2]
  465.     psubw    xmm0,xmm5        ;[out] xmm7 = e3 - o3
  466.  
  467.     movdqa    %%y7,xmm6
  468.     psraw    xmm3,SHIFT_INV_COL
  469.  
  470.     pmulhw    xmm7, [rax + (tg_2_16 - tabbase)]        ;[B8T] xmm6 = tmp[2] * TAN(2)
  471.     psraw    xmm0,SHIFT_INV_COL
  472.  
  473.     movdqa    %%y3,xmm3
  474.     movdqa    xmm6,xmm4                ;[E8T]
  475.  
  476.     psubw    xmm6, [rax + (one_corr - tabbase)]
  477.     ;<v-pipe>
  478.  
  479.  
  480.     ;B8T stage - x3 element
  481.     ;
  482.     ;free registers: 03567
  483.  
  484.     psubw    xmm7,%%x6                ;[B8T] xmm6 = x3 = tmp[2]*TAN(2) - tmp[3]
  485.     movdqa    xmm3,xmm1
  486.  
  487.     ;E8T stage - x1 and x3 elements
  488.  
  489.     movdqa    %%y4,xmm0
  490.     paddw    xmm4,xmm7                ;[E8T] xmm4 = e1 = x1+x3
  491.  
  492.     psubw    xmm6,xmm7                ;[E8T] xmm7 = e2 = x1-x3
  493.     paddw    xmm3,xmm4                ;xmm3 = e1 + o1
  494.  
  495.     psubw    xmm4,xmm1                ;xmm4 = e1 - o1
  496.     psraw    xmm3,SHIFT_INV_COL
  497.  
  498.     movdqa    xmm5,xmm6                ;xmm6 = e2
  499.     psraw    xmm4,SHIFT_INV_COL
  500.  
  501.     paddw    xmm6,xmm2                ;xmm7 = e2 + o2
  502.     psubw    xmm5,xmm2                ;xmm6 = e2 - o2
  503.  
  504.     movdqa    %%y1,xmm3
  505.     psraw    xmm6,SHIFT_INV_COL
  506.  
  507.     movdqa    %%y6,xmm4
  508.     psraw    xmm5,SHIFT_INV_COL
  509.  
  510.     movdqa    %%y2,xmm6
  511.  
  512.     movdqa    %%y5,xmm5
  513.  
  514. %endmacro
  515.  
  516. ;-----------------------------------------------------------------------------
  517. ;
  518. ; The half 8-point scaled inverse DCT algorithm (26a8m)
  519. ;
  520. ;-----------------------------------------------------------------------------
  521. ;
  522. ;    // Reorder and prescale (implicit)
  523. ;
  524. ;    ev0 = co[0] / 2.0;
  525. ;    ev1 = co[2] / 2.0;
  526. ;    od0 = co[1] / 2.0;
  527. ;    od1 = co[3] / 2.0;
  528. ;
  529. ;    // 5) Apply D8T (implicit in row calculation).
  530. ;
  531. ;    tmp[0] = ev0*LAMBDA(4);
  532. ;    tmp[2] = ev1*LAMBDA(2);
  533. ;    tmp[4] = od0*LAMBDA(1);
  534. ;    tmp[6] = od1*LAMBDA(3);
  535. ;
  536. ;    // 4) Apply B8T.
  537. ;
  538. ;    double x0, x1, x2, x3, y0, y1, y2, y3;
  539. ;
  540. ;    x0 = tmp[0];
  541. ;    x1 = tmp[0];
  542. ;    x2 = tmp[2];
  543. ;    x3 = tmp[2]*TAN(2);
  544. ;    y0 = tmp[4];
  545. ;    y1 = tmp[4]*TAN(1);
  546. ;    y2 = tmp[6];
  547. ;    y3 = tmp[6]*TAN(3);
  548. ;
  549. ;    // 3) Apply E8T.
  550. ;    //
  551. ;    //    1  0  1  0
  552. ;    //    0  1  0  1
  553. ;    //    0  1  0 -1
  554. ;    //    1  0 -1  0
  555. ;    //            1  0  1  0
  556. ;    //            1  0 -1  0
  557. ;    //            0  1  0  1
  558. ;    //            0  1  0 -1
  559. ;
  560. ;    double e0, e1, e2, e3, o0, o1, o2, o3;
  561. ;
  562. ;    e0 = x0 + x2;
  563. ;    e1 = x1 + x3;
  564. ;    e2 = x1 - x3;
  565. ;    e3 = x0 - x2;
  566. ;    o0 = y0 + y2;
  567. ;    o1 = y0 - y2;
  568. ;    o2 = y1 + y3;
  569. ;    o3 = y1 - y3;
  570. ;
  571. ;    // 2) Apply F8T.
  572. ;
  573. ;    double a, b;
  574. ;
  575. ;    a = (o1 + o2) * LAMBDA(4);
  576. ;    b = (o1 - o2) * LAMBDA(4);
  577. ;
  578. ;    o1 = a;
  579. ;    o2 = b;
  580. ;
  581. ;    // 6) Apply output butterfly (A8T).
  582. ;    //
  583. ;    // 1 0 0 0  1  0  0  0
  584. ;    // 0 1 0 0  0  1  0  0
  585. ;    // 0 0 1 0  0  0  1  0
  586. ;    // 0 0 0 1  0  0  0  1
  587. ;    // 0 0 0 1  0  0  0 -1
  588. ;    // 0 0 1 0  0  0 -1  0
  589. ;    // 0 1 0 0  0 -1  0  0
  590. ;    // 1 0 0 0 -1  0  0  0
  591. ;
  592. ;    out[0] = e0 + o0;
  593. ;    out[1] = e1 + o1;
  594. ;    out[2] = e2 + o2;
  595. ;    out[3] = e3 + o3;
  596. ;    out[4] = e3 - o3;
  597. ;    out[5] = e2 - o2;
  598. ;    out[6] = e1 - o1;
  599. ;    out[7] = e0 - o0;
  600. ;
  601. ;=============================================================================
  602.  
  603. %macro DCT_8_INV_COL_SHORT  2
  604. %define %%inp    %1
  605. %define %%out    %2
  606.  
  607. %define    %%x0    [%%inp + 0*16]
  608. %define    %%x1    [%%inp + 1*16]
  609. %define    %%x2    [%%inp + 2*16]
  610. %define    %%x3    [%%inp + 3*16]
  611. %define    %%y0    [%%out + 0*16]
  612. %define    %%y1    [%%out + 1*16]
  613. %define    %%y2    [%%out + 2*16]
  614. %define    %%y3    [%%out + 3*16]
  615. %define    %%y4    [%%out + 4*16]
  616. %define    %%y5    [%%out + 5*16]
  617. %define    %%y6    [%%out + 6*16]
  618. %define    %%y7    [%%out + 7*16]
  619.  
  620.     ;======= optimized    segment    .text
  621.  
  622.     ;ODD ELEMENTS
  623.  
  624.     movdqa    xmm3, [rax + (tg_1_16 - tabbase)]
  625.  
  626.     movdqa    xmm0,%%x1
  627.     movdqa    xmm6, [rax + (tg_3_16 - tabbase)]
  628.  
  629.     movdqa    xmm2,%%x3
  630.     pmulhw    xmm3,xmm0
  631.  
  632.     pmulhw    xmm6,xmm2
  633.  
  634.     paddw    xmm0, [rax + (one_corr - tabbase)]
  635.     paddw    xmm6,xmm2
  636.  
  637.     ;E8T butterfly - odd elements
  638.  
  639.     movdqa    xmm1,xmm0
  640.     movdqa    xmm5,xmm3
  641.     paddw    xmm0,xmm2        ;xmm0 = o0 = y0 + y2
  642.     psubw    xmm1,xmm2        ;xmm1 = o1 = y0 - y2
  643.     paddw    xmm3,xmm6        ;xmm3 = o2 = y1 + y3
  644.     psubw    xmm5,xmm6        ;xmm5 = o3 = y1 - y3
  645.  
  646.     ;F8T stage - odd elements
  647.  
  648.     movdqa    xmm2,xmm1
  649.     paddw    xmm1,xmm3                    ;[F8T] xmm1 = o1 + o2
  650.  
  651.     movdqa    xmm4,%%x0                    ;[B8T1] xmm4 = x0 = x1 = tmp[0]
  652.     psubw    xmm2,xmm3                    ;[F8T] xmm2 = o1 - o2
  653.  
  654.     movdqa    xmm6,xmm2                    ;[F8T]
  655.     movdqa    xmm7,xmm1                    ;[F8T]
  656.  
  657.     pmulhw    xmm2, [rax + (cos_4_16 - tabbase)]    ;[F8T]
  658.     movdqa    xmm3,xmm4                    ;[B8T1] xmm3 = x0 = x1 = tmp[0]
  659.  
  660.     pmulhw    xmm1, [rax + (cos_4_16 - tabbase)]    ;[F8T]
  661.  
  662.     paddw    xmm3, [rax + (round_inv_corr - tabbase)]    ;[E8T]
  663.     ;<v-pipe>
  664.  
  665.     paddw    xmm4, [rax + (round_inv_col - tabbase)]    ;[out]
  666.     paddw    xmm2,xmm6                    ;[F8T]
  667.  
  668.     por        xmm1, [rax + (one_corr - tabbase)]    ;[F8T]
  669.     ;<v-pipe>
  670.  
  671.     psubw    xmm2, [rax + (one_corr - tabbase)]        ;[F8T] xmm2 = o2' = (o1 - o2)*LAMBDA(4)
  672.     paddw    xmm1,xmm7                    ;[F8T] xmm1 = o1' = (o1 + o2)*LAMBDA(4)
  673.  
  674.     movdqa    xmm6,%%x2                    ;[B8T2] xmm7 = x2 = tmp[2]
  675.     movdqa    xmm7,xmm4                    ;[E8T]
  676.  
  677.     paddw    xmm7,xmm6                    ;[E8T] xmm6 = e0 = x0+x2
  678.     psubw    xmm3,xmm6                    ;[E8T] xmm3 = e3 = x0-x2
  679.  
  680.     ;output butterfly - 0 and 3
  681.  
  682.     movdqa    xmm6,xmm7        ;xmm7 = e0
  683.     paddw    xmm7,xmm0        ;xmm6 = e0 + o0
  684.  
  685.     psubw    xmm6,xmm0        ;xmm7 = e0 - o0
  686.     psraw    xmm7,SHIFT_INV_COL
  687.  
  688.     movdqa    xmm0,xmm3        ;xmm7 = e3 
  689.     psraw    xmm6,SHIFT_INV_COL
  690.  
  691.     movdqa    %%y0,xmm7
  692.     paddw    xmm3,xmm5        ;xmm6 = e3 + o3
  693.  
  694.     movdqa    xmm7,%%x2        ;[B8T] xmm6 = tmp[2]
  695.     psubw    xmm0,xmm5        ;[out] xmm7 = e3 - o3
  696.  
  697.     movdqa    %%y7,xmm6
  698.     psraw    xmm3,SHIFT_INV_COL
  699.  
  700.     pmulhw    xmm7, [rax + (tg_2_16 - tabbase)]        ;[B8T] xmm6 = x3 = tmp[2] * TAN(2)
  701.     psraw    xmm0,SHIFT_INV_COL
  702.  
  703.     movdqa    %%y3,xmm3
  704.     movdqa    xmm6,xmm4                ;[E8T]
  705.  
  706.     psubw    xmm6, [rax + (one_corr - tabbase)]
  707.     ;<v-pipe>
  708.  
  709.  
  710.     ;B8T stage - x3 element
  711.     ;
  712.     ;free registers: 03567
  713.  
  714.     movdqa    xmm3,xmm1
  715.  
  716.     ;E8T stage - x1 and x3 elements
  717.  
  718.     movdqa    %%y4,xmm0
  719.     paddw    xmm4,xmm7                ;[E8T] xmm4 = e1 = x1+x3
  720.  
  721.     psubw    xmm6,xmm7                ;[E8T] xmm7 = e2 = x1-x3
  722.     paddw    xmm3,xmm4                ;xmm3 = e1 + o1
  723.  
  724.     psubw    xmm4,xmm1                ;xmm4 = e1 - o1
  725.     psraw    xmm3,SHIFT_INV_COL
  726.  
  727.     movdqa    xmm5,xmm6                ;xmm6 = e2
  728.     psraw    xmm4,SHIFT_INV_COL
  729.  
  730.     paddw    xmm6,xmm2                ;xmm7 = e2 + o2
  731.     psubw    xmm5,xmm2                ;xmm6 = e2 - o2
  732.  
  733.     movdqa    %%y1,xmm3
  734.     psraw    xmm6,SHIFT_INV_COL
  735.  
  736.     movdqa    %%y6,xmm4
  737.     psraw    xmm5,SHIFT_INV_COL
  738.  
  739.     movdqa    %%y2,xmm6
  740.  
  741.     movdqa    %%y5,xmm5
  742. %endmacro
  743.  
  744. ;==========================================================================
  745.  
  746.     segment    .text
  747.  
  748.     global IDCT_sse2    
  749.  
  750.  
  751. IDCT_sse2:
  752.     movlhps    xmm14, xmm6
  753.     movlhps    xmm15, xmm7
  754.     movsxd    r9, r9d
  755.     movsxd    r10, dword [rsp+40]
  756.     lea        rax, [tabbase]
  757.     movzx    r11, byte [rax+r10+(pos_tab - tabbase)]
  758.  
  759.     jmp    qword [rax+r11+(rowstart_tbl2 - tabbase)]
  760.  
  761.     align    16
  762. dorow_3is:
  763.     DCT_8_INV_ROW_1_SSE2_SHORT    rcx+3*16, rcx+3*16, rax + (tab_i_35_short - tabbase)
  764. dorow_2is:
  765.     DCT_8_INV_ROW_1_SSE2_SHORT    rcx+2*16, rcx+2*16, rax + (tab_i_26_short - tabbase)
  766. dorow_1is:
  767.     DCT_8_INV_ROW_1_SSE2_SHORT    rcx+1*16, rcx+1*16, rax + (tab_i_17_short - tabbase)
  768. dorow_0is:
  769.     DCT_8_INV_ROW_1_SSE2_SHORT    rcx+0*16, rcx+0*16, rax + (tab_i_04_short - tabbase)
  770.  
  771.     DCT_8_INV_COL_SHORT        rcx, rcx
  772.  
  773.     movhlps    xmm6, xmm14
  774.     movhlps    xmm7, xmm15
  775.     jmp    qword [rax + (jump_tab - tabbase) + r9*8]
  776.  
  777.     align    16
  778. dorow_7is:
  779.         DCT_8_INV_ROW_1_SSE2    rcx+7*16, rcx+7*16, rax + (tab_i_17 - tabbase)
  780. dorow_6is:
  781.         DCT_8_INV_ROW_1_SSE2    rcx+6*16, rcx+6*16, rax + (tab_i_26 - tabbase)
  782. dorow_5is:
  783.         DCT_8_INV_ROW_1_SSE2    rcx+5*16, rcx+5*16, rax + (tab_i_35 - tabbase)
  784. dorow_4is:
  785.         DCT_8_INV_ROW_1_SSE2    rcx+4*16, rcx+4*16, rax + (tab_i_04 - tabbase)
  786.         DCT_8_INV_ROW_1_SSE2    rcx+3*16, rcx+3*16, rax + (tab_i_35 - tabbase)
  787.         DCT_8_INV_ROW_1_SSE2    rcx+2*16, rcx+2*16, rax + (tab_i_26 - tabbase)
  788.         DCT_8_INV_ROW_1_SSE2    rcx+1*16, rcx+1*16, rax + (tab_i_17 - tabbase)
  789.         DCT_8_INV_ROW_1_SSE2    rcx+0*16, rcx+0*16, rax + (tab_i_04 - tabbase)
  790.  
  791.     DCT_8_INV_COL        rcx, rcx
  792.  
  793.     movhlps    xmm6, xmm14
  794.     movhlps    xmm7, xmm15
  795.     jmp    qword [rax + (jump_tab - tabbase) + r9*8]
  796.  
  797.  
  798.  
  799.  
  800.     align 16
  801.  
  802. tail_intra:
  803.     xor            rax,rax
  804.     sub            rax,8*16                ;ml64 truncates all constants on mov rax,imm64 to 32-bit unsigned... f*cking useless assembler
  805. intra_loop:
  806.     movdqa        xmm0,[rcx+rax+8*16]
  807.     packuswb    xmm0,xmm0
  808.     movq        qword [rdx],xmm0
  809.     add            rdx, r8
  810.     add            rax, 16
  811.     jne            intra_loop
  812. tail_mjpeg:
  813.     ret
  814.  
  815.     align        16
  816. tail_inter:
  817.     xor            rax,rax
  818.     sub            rax,8*16
  819.     pxor        xmm4, xmm4
  820. inter_loop:
  821.     movdqa        xmm0, [rcx+rax+8*16]
  822.     movq        xmm2, qword [rdx]
  823.     punpcklbw    xmm2, xmm4
  824.     paddw        xmm0, xmm2
  825.     packuswb    xmm0, xmm0
  826.     movq        qword [rdx], xmm0
  827.     add            rdx, r8
  828.     add            rax, 16
  829.     jne            inter_loop
  830.     ret
  831.  
  832. ;--------------------------------------------------------------------------
  833.  
  834. do_dc_sse2:
  835.     pshuflw        xmm0, [rcx], 0
  836.     pxor        xmm1, xmm1
  837.     paddw        xmm0, [rounder]
  838.     psraw        xmm0, 3
  839.     pshufd        xmm0, xmm0, 0
  840.     cmp            r9d, 1
  841.     jb            do_ac_sse2
  842.     ja            do_dc_mjpeg
  843.     packuswb    xmm0,xmm0
  844.  
  845.     movq        qword [rdx],xmm0        ;row 0
  846.     lea            rax,[r8+r8*2]
  847.     movq        qword [rdx+r8],xmm0        ;row 1
  848.     add            rax,rdx
  849.     movq        qword [rdx+r8*2],xmm0        ;row 2
  850.     lea            rdx,[rdx+r8*2]
  851.     movq        qword [rax],xmm0            ;row 3
  852.     movq        qword [rdx+r8*2],xmm0        ;row 4
  853.     movq        qword [rax+r8*2],xmm0        ;row 5
  854.     movq        qword [rdx+r8*4],xmm0        ;row 6
  855.     movq        qword [rax+r8*4],xmm0        ;row 7
  856.     ret
  857.  
  858.     align        16
  859. do_ac_sse2:
  860.     psubw        xmm1,xmm0
  861.     packuswb    xmm0,xmm0            ;mm0 = adder
  862.     packuswb    xmm1,xmm1            ;mm1 = subtractor
  863.  
  864.     mov        rax,8
  865. do_ac_sse2.loop:
  866.     movq        xmm2, qword [rdx]
  867.     paddusb        xmm2,xmm0
  868.     psubusb        xmm2,xmm1
  869.     movq        qword [rdx],xmm2
  870.     add            rdx,r8
  871.     sub            rax,1
  872.     jne            do_ac_sse2.loop
  873.     ret
  874.  
  875. do_dc_mjpeg:
  876.     pshufd        xmm0, xmm0, 0
  877.     movdqa        [rdx], xmm0            ;row 0
  878.     lea            rax,[rcx+r8*2]
  879.     movdqa        [rdx+r8],xmm0        ;row 1
  880.     add            rax,rdx
  881.     movdqa        [rdx+r8*2],xmm0        ;row 2
  882.     lea            rdx,[rdx+r8*2]
  883.     movdqa        [rax],xmm0            ;row 3
  884.     movdqa        [rdx+r8*2],xmm0        ;row 4
  885.     movdqa        [rax+r8*2],xmm0        ;row 5
  886.     movdqa        [rdx+r8*4],xmm0        ;row 6
  887.     movdqa        [rax+r8*4],xmm0        ;row 7
  888.     ret
  889.  
  890.     end
  891.