idct_mmx.asm
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:25k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. ; Originally provided by Intel at AP-922
  2. ; http://developer.intel.com/vtune/cbts/strmsimd/922down.htm
  3. ; (See more app notes at http://developer.intel.com/vtune/cbts/strmsimd/appnotes.htm)
  4. ; but in a limited edition.
  5. ; New macro implements a column part for precise iDCT
  6. ; The routine precision now satisfies IEEE standard 1180-1990. 
  7. ;
  8. ; Copyright (c) 2000-2001 Peter Gubanov <peter@elecard.net.ru>
  9. ; Rounding trick Copyright (c) 2000 Michel Lespinasse <walken@zoy.org>
  10. ;
  11. ; http://www.elecard.com/peter/idct.html
  12. ; http://www.linuxvideo.org/mpeg2dec/
  13. ;
  14. ;=============================================================================
  15. ;
  16. ; These examples contain code fragments for first stage iDCT 8x8
  17. ; (for rows) and first stage DCT 8x8 (for columns)
  18. ;
  19. ;=============================================================================
  20. ;
  21. ; 04.11.2001  nasm conversion; peter ross <pross@cs.rmit.edu.au>
  22. ;
  23. bits 32
  24. %macro cglobal 1 
  25. %ifdef PREFIX
  26. global _%1 
  27. %define %1 _%1
  28. %else
  29. global %1
  30. %endif
  31. %endmacro
  32. %define BITS_INV_ACC    5                        ; 4 or 5 for IEEE
  33. %define SHIFT_INV_ROW   16 - BITS_INV_ACC
  34. %define SHIFT_INV_COL   1 + BITS_INV_ACC
  35. %define RND_INV_ROW     1024 * (6 - BITS_INV_ACC) ; 1 << (SHIFT_INV_ROW-1)
  36. %define RND_INV_COL     16 * (BITS_INV_ACC - 3)   ; 1 << (SHIFT_INV_COL-1)
  37. %define RND_INV_CORR    RND_INV_COL - 1          ; correction -1.0 and round
  38. %define BITS_FRW_ACC    3                        ; 2 or 3 for accuracy
  39. %define SHIFT_FRW_COL   BITS_FRW_ACC
  40. %define SHIFT_FRW_ROW   BITS_FRW_ACC + 17
  41. %define RND_FRW_ROW     262144 * (BITS_FRW_ACC - 1)       ; 1 << (SHIFT_FRW_ROW-1)
  42. section .data
  43. align 16
  44. one_corr        dw            1,            1,            1,            1
  45. round_inv_row   dd  RND_INV_ROW,  RND_INV_ROW
  46. round_inv_col   dw  RND_INV_COL,  RND_INV_COL,  RND_INV_COL, RND_INV_COL
  47. round_inv_corr  dw  RND_INV_CORR, RND_INV_CORR, RND_INV_CORR, RND_INV_CORR
  48. round_frw_row   dd  RND_FRW_ROW,  RND_FRW_ROW
  49.   tg_1_16       dw  13036,  13036,  13036,  13036    ; tg * (2<<16) + 0.5
  50.   tg_2_16       dw  27146,  27146,  27146,  27146    ; tg * (2<<16) + 0.5
  51.   tg_3_16       dw -21746, -21746, -21746, -21746    ; tg * (2<<16) + 0.5
  52.  cos_4_16       dw -19195, -19195, -19195, -19195    ; cos * (2<<16) + 0.5
  53. ocos_4_16       dw  23170,  23170,  23170,  23170    ; cos * (2<<15) + 0.5
  54.  otg_3_16       dw  21895, 21895, 21895, 21895       ; tg * (2<<16) + 0.5
  55. %if SHIFT_INV_ROW == 12   ; assume SHIFT_INV_ROW == 12
  56. rounder_0      dd  65536, 65536
  57. rounder_4      dd      0,     0
  58. rounder_1      dd   7195,  7195
  59. rounder_7      dd   1024,  1024
  60. rounder_2      dd   4520,  4520
  61. rounder_6      dd   1024,  1024
  62. rounder_3      dd   2407,  2407
  63. rounder_5      dd    240,   240
  64. %elif SHIFT_INV_ROW == 11   ; assume SHIFT_INV_ROW == 11
  65. rounder_0      dd  65536, 65536
  66. rounder_4      dd      0,     0
  67. rounder_1      dd   3597,  3597
  68. rounder_7      dd    512,   512
  69. rounder_2      dd   2260,  2260
  70. rounder_6      dd    512,   512
  71. rounder_3      dd   1203,  1203
  72. rounder_5      dd    120,   120
  73. %else
  74. %error invalid _SHIFT_INV_ROW_
  75. %endif
  76. ;=============================================================================
  77. ;
  78. ; The first stage iDCT 8x8 - inverse DCTs of rows
  79. ;
  80. ;-----------------------------------------------------------------------------
  81. ; The 8-point inverse DCT direct algorithm
  82. ;-----------------------------------------------------------------------------
  83. ;
  84. ; static const short w[32] = {
  85. ; FIX(cos_4_16),  FIX(cos_2_16),  FIX(cos_4_16),  FIX(cos_6_16),
  86. ; FIX(cos_4_16),  FIX(cos_6_16), -FIX(cos_4_16), -FIX(cos_2_16),
  87. ; FIX(cos_4_16), -FIX(cos_6_16), -FIX(cos_4_16),  FIX(cos_2_16),
  88. ; FIX(cos_4_16), -FIX(cos_2_16),  FIX(cos_4_16), -FIX(cos_6_16),
  89. ; FIX(cos_1_16),  FIX(cos_3_16),  FIX(cos_5_16),  FIX(cos_7_16),
  90. ; FIX(cos_3_16), -FIX(cos_7_16), -FIX(cos_1_16), -FIX(cos_5_16),
  91. ; FIX(cos_5_16), -FIX(cos_1_16),  FIX(cos_7_16),  FIX(cos_3_16),
  92. ; FIX(cos_7_16), -FIX(cos_5_16),  FIX(cos_3_16), -FIX(cos_1_16) };
  93. ;
  94. ; #define DCT_8_INV_ROW(x, y)
  95. ; {
  96. ;  int a0, a1, a2, a3, b0, b1, b2, b3;
  97. ;
  98. ;  a0 =x[0]*w[0]+x[2]*w[1]+x[4]*w[2]+x[6]*w[3];
  99. ;  a1 =x[0]*w[4]+x[2]*w[5]+x[4]*w[6]+x[6]*w[7];
  100. ;  a2 = x[0] * w[ 8] + x[2] * w[ 9] + x[4] * w[10] + x[6] * w[11];
  101. ;  a3 = x[0] * w[12] + x[2] * w[13] + x[4] * w[14] + x[6] * w[15];
  102. ;  b0 = x[1] * w[16] + x[3] * w[17] + x[5] * w[18] + x[7] * w[19];
  103. ;  b1 = x[1] * w[20] + x[3] * w[21] + x[5] * w[22] + x[7] * w[23];
  104. ;  b2 = x[1] * w[24] + x[3] * w[25] + x[5] * w[26] + x[7] * w[27];
  105. ;  b3 = x[1] * w[28] + x[3] * w[29] + x[5] * w[30] + x[7] * w[31];
  106. ;
  107. ;  y[0] = SHIFT_ROUND ( a0 + b0 );
  108. ;  y[1] = SHIFT_ROUND ( a1 + b1 );
  109. ;  y[2] = SHIFT_ROUND ( a2 + b2 );
  110. ;  y[3] = SHIFT_ROUND ( a3 + b3 );
  111. ;  y[4] = SHIFT_ROUND ( a3 - b3 );
  112. ;  y[5] = SHIFT_ROUND ( a2 - b2 );
  113. ;  y[6] = SHIFT_ROUND ( a1 - b1 );
  114. ;  y[7] = SHIFT_ROUND ( a0 - b0 );
  115. ; }
  116. ;
  117. ;-----------------------------------------------------------------------------
  118. ;
  119. ; In this implementation the outputs of the iDCT-1D are multiplied
  120. ;  for rows 0,4 - by cos_4_16,
  121. ;  for rows 1,7 - by cos_1_16,
  122. ;  for rows 2,6 - by cos_2_16,
  123. ;  for rows 3,5 - by cos_3_16
  124. ; and are shifted to the left for better accuracy
  125. ;
  126. ; For the constants used,
  127. ;  FIX(float_const) = (short) (float_const * (1<<15) + 0.5)
  128. ;
  129. ;=============================================================================
  130. ;=============================================================================
  131. ; MMX code
  132. ;=============================================================================
  133. ; Table for rows 0,4 - constants are multiplied by cos_4_16
  134. tab_i_04        dw  16384,  16384,  16384, -16384    ; movq-> w06 w04 w02 w00
  135.                 dw  21407,   8867,   8867, -21407    ; w07 w05 w03 w01
  136.                 dw  16384, -16384,  16384,  16384    ; w14 w12 w10 w08
  137.                 dw  -8867,  21407, -21407,  -8867    ; w15 w13 w11 w09
  138.                 dw  22725,  12873,  19266, -22725    ; w22 w20 w18 w16
  139.                 dw  19266,   4520,  -4520, -12873    ; w23 w21 w19 w17
  140.                 dw  12873,   4520,   4520,  19266    ; w30 w28 w26 w24
  141.                 dw -22725,  19266, -12873, -22725    ; w31 w29 w27 w25
  142. ; Table for rows 1,7 - constants are multiplied by cos_1_16
  143. tab_i_17        dw  22725,  22725,  22725, -22725    ; movq-> w06 w04 w02 w00
  144.                 dw  29692,  12299,  12299, -29692    ; w07 w05 w03 w01
  145.                 dw  22725, -22725,  22725,  22725    ; w14 w12 w10 w08
  146.                 dw -12299,  29692, -29692, -12299    ; w15 w13 w11 w09
  147.                 dw  31521,  17855,  26722, -31521    ; w22 w20 w18 w16
  148.                 dw  26722,   6270,  -6270, -17855    ; w23 w21 w19 w17
  149.                 dw  17855,   6270,   6270,  26722    ; w30 w28 w26 w24
  150.                 dw -31521,  26722, -17855, -31521    ; w31 w29 w27 w25
  151. ; Table for rows 2,6 - constants are multiplied by cos_2_16
  152. tab_i_26        dw  21407,  21407,  21407, -21407    ; movq-> w06 w04 w02 w00
  153.                 dw  27969,  11585,  11585, -27969    ; w07 w05 w03 w01
  154.                 dw  21407, -21407,  21407,  21407    ; w14 w12 w10 w08
  155.                 dw -11585,  27969, -27969, -11585    ; w15 w13 w11 w09
  156.                 dw  29692,  16819,  25172, -29692    ; w22 w20 w18 w16
  157.                 dw  25172,   5906,  -5906, -16819    ; w23 w21 w19 w17
  158.                 dw  16819,   5906,   5906,  25172    ; w30 w28 w26 w24
  159.                 dw -29692,  25172, -16819, -29692    ; w31 w29 w27 w25
  160. ; Table for rows 3,5 - constants are multiplied by cos_3_16
  161. tab_i_35        dw  19266,  19266,  19266, -19266    ; movq-> w06 w04 w02 w00
  162.                 dw  25172,  10426,  10426, -25172    ; w07 w05 w03 w01
  163.                 dw  19266, -19266,  19266,  19266    ; w14 w12 w10 w08
  164.                 dw -10426,  25172, -25172, -10426    ; w15 w13 w11 w09
  165.                 dw  26722,  15137,  22654, -26722    ; w22 w20 w18 w16
  166.                 dw  22654,   5315,  -5315, -15137    ; w23 w21 w19 w17
  167.                 dw  15137,   5315,   5315,  22654    ; w30 w28 w26 w24
  168.                 dw -26722,  22654, -15137, -26722    ; w31 w29 w27 w25
  169. ;-----------------------------------------------------------------------------
  170. ;
  171. ; DCT_8_INV_ROW_1  INP, OUT, TABLE, ROUNDER
  172. ;
  173. %macro  DCT_8_INV_ROW_1         4
  174.         movq mm0, [%1]            ; 0     ; x3 x2 x1 x0
  175.         movq mm1, [%1+8]          ; 1     ; x7 x6 x5 x4
  176. movq mm2, mm0  ; 2 ; x3 x2 x1 x0
  177.         movq mm3, [%3]          ; 3     ; w06 w04 w02 w00
  178. punpcklwd mm0, mm1  ; x5 x1 x4 x0
  179. movq mm5, mm0  ; 5 ; x5 x1 x4 x0
  180. punpckldq mm0, mm0  ; x4 x0 x4 x0
  181.         movq mm4, [%3+8]        ; 4     ; w07 w05 w03 w01
  182. punpckhwd mm2, mm1 ; 1 ; x7 x3 x6 x2
  183. pmaddwd mm3, mm0  ; x4*w06+x0*w04 x4*w02+x0*w00
  184. movq mm6, mm2  ; 6  ; x7 x3 x6 x2
  185.         movq mm1, [%3+32]       ; 1     ; w22 w20 w18 w16
  186. punpckldq mm2, mm2  ; x6 x2 x6 x2
  187. pmaddwd mm4, mm2  ; x6*w07+x2*w05 x6*w03+x2*w01
  188. punpckhdq mm5, mm5  ; x5 x1 x5 x1
  189.         pmaddwd mm0, [%3+16]            ; x4*w14+x0*w12 x4*w10+x0*w08
  190. punpckhdq mm6, mm6  ; x7 x3 x7 x3
  191.         movq mm7, [%3+40]       ; 7     ; w23 w21 w19 w17
  192. pmaddwd mm1, mm5  ; x5*w22+x1*w20 x5*w18+x1*w16
  193.         paddd mm3, [%4]               ; +%4
  194. pmaddwd mm7, mm6  ; x7*w23+x3*w21 x7*w19+x3*w17
  195.         pmaddwd mm2, [%3+24]            ; x6*w15+x2*w13 x6*w11+x2*w09
  196. paddd mm3, mm4  ; 4  ; a1=sum(even1) a0=sum(even0)
  197.         pmaddwd mm5, [%3+48]            ; x5*w30+x1*w28 x5*w26+x1*w24
  198. movq mm4, mm3  ; 4  ; a1 a0
  199.         pmaddwd mm6, [%3+56]            ; x7*w31+x3*w29 x7*w27+x3*w25
  200. paddd mm1, mm7  ; 7  ; b1=sum(odd1) b0=sum(odd0)
  201.         paddd mm0, [%4]               ; +%4
  202. psubd mm3, mm1  ; a1-b1 a0-b0
  203. psrad mm3, SHIFT_INV_ROW  ; y6=a1-b1 y7=a0-b0
  204. paddd mm1, mm4  ; 4  ; a1+b1 a0+b0
  205. paddd mm0, mm2  ; 2  ; a3=sum(even3) a2=sum(even2)
  206. psrad mm1, SHIFT_INV_ROW  ; y1=a1+b1 y0=a0+b0
  207. paddd mm5, mm6  ; 6  ; b3=sum(odd3) b2=sum(odd2)
  208. movq mm4, mm0  ; 4  ; a3 a2
  209. paddd mm0, mm5  ; a3+b3 a2+b2
  210. psubd mm4, mm5  ; 5  ; a3-b3 a2-b2
  211. psrad mm0, SHIFT_INV_ROW  ; y3=a3+b3 y2=a2+b2
  212. psrad mm4, SHIFT_INV_ROW  ; y4=a3-b3 y5=a2-b2
  213. packssdw mm1, mm0  ; 0  ; y3 y2 y1 y0
  214. packssdw mm4, mm3  ; 3  ; y6 y7 y4 y5
  215. movq mm7, mm4  ; 7  ; y6 y7 y4 y5
  216. psrld mm4, 16  ; 0 y6 0 y4
  217. pslld mm7, 16  ; y7 0 y5 0
  218.         movq [%2], mm1            ; 1     ; save y3 y2 y1 y0
  219.                              
  220. por mm7, mm4  ; 4  ; y7 y6 y5 y4
  221.         movq [%2+8], mm7          ; 7     ; save y7 y6 y5 y4
  222. %endmacro
  223. ;=============================================================================
  224. ; code for Pentium III
  225. ;=============================================================================
  226. ; %3 for rows 0,4 - constants are multiplied by cos_4_16
  227. tab_i_04_sse    dw 16384, 21407, 16384, 8867 ; movq-> w05 w04 w01 w00
  228.                 dw 16384, 8867, -16384, -21407 ; w07 w06 w03 w02
  229.                 dw 16384, -8867, 16384, -21407 ; w13 w12 w09 w08
  230.                 dw -16384, 21407, 16384, -8867 ; w15 w14 w11 w10
  231.                 dw 22725, 19266, 19266, -4520 ; w21 w20 w17 w16
  232.                 dw 12873, 4520, -22725, -12873 ; w23 w22 w19 w18
  233.                 dw 12873, -22725, 4520, -12873 ; w29 w28 w25 w24
  234.                 dw 4520, 19266, 19266, -22725 ; w31 w30 w27 w26
  235. ; %3 for rows 1,7 - constants are multiplied by cos_1_16
  236. tab_i_17_sse    dw 22725, 29692, 22725, 12299 ; movq-> w05 w04 w01 w00
  237.                 dw 22725, 12299, -22725, -29692 ; w07 w06 w03 w02
  238.                 dw 22725, -12299, 22725, -29692 ; w13 w12 w09 w08
  239.                 dw -22725, 29692, 22725, -12299 ; w15 w14 w11 w10
  240.                 dw 31521, 26722, 26722, -6270 ; w21 w20 w17 w16
  241.                 dw 17855, 6270, -31521, -17855 ; w23 w22 w19 w18
  242.                 dw 17855, -31521, 6270, -17855 ; w29 w28 w25 w24
  243.                 dw 6270, 26722, 26722, -31521 ; w31 w30 w27 w26
  244. ; %3 for rows 2,6 - constants are multiplied by cos_2_16
  245. tab_i_26_sse    dw 21407, 27969, 21407, 11585 ; movq-> w05 w04 w01 w00
  246.                 dw 21407, 11585, -21407, -27969 ; w07 w06 w03 w02
  247.                 dw 21407, -11585, 21407, -27969 ; w13 w12 w09 w08
  248.                 dw -21407, 27969, 21407, -11585 ; w15 w14 w11 w10
  249.                 dw 29692, 25172, 25172, -5906 ; w21 w20 w17 w16
  250.                 dw 16819, 5906, -29692, -16819 ; w23 w22 w19 w18
  251.                 dw 16819, -29692, 5906, -16819 ; w29 w28 w25 w24
  252.                 dw 5906, 25172, 25172, -29692 ; w31 w30 w27 w26
  253. ; %3 for rows 3,5 - constants are multiplied by cos_3_16
  254. tab_i_35_sse    dw 19266, 25172, 19266, 10426 ; movq-> w05 w04 w01 w00
  255.                 dw 19266, 10426, -19266, -25172 ; w07 w06 w03 w02
  256.                 dw 19266, -10426, 19266, -25172 ; w13 w12 w09 w08
  257.                 dw -19266, 25172, 19266, -10426 ; w15 w14 w11 w10
  258.                 dw 26722, 22654, 22654, -5315 ; w21 w20 w17 w16
  259.                 dw 15137, 5315, -26722, -15137 ; w23 w22 w19 w18
  260.                 dw 15137, -26722, 5315, -15137 ; w29 w28 w25 w24
  261.                 dw 5315, 22654, 22654, -26722 ; w31 w30 w27 w26
  262. ;-----------------------------------------------------------------------------
  263. ;
  264. ; DCT_8_INV_ROW_1_sse  INP, OUT, TABLE, ROUNDER
  265. ;
  266. %macro DCT_8_INV_ROW_1_sse  4
  267.         movq    mm0, [%1]         ; 0     ; x3 x2 x1 x0
  268.         movq    mm1, [%1+8]       ; 1     ; x7 x6 x5 x4
  269. movq  mm2, mm0  ; 2  ; x3 x2 x1 x0
  270.         movq    mm3, [%3]       ; 3     ; w05 w04 w01 w00
  271. pshufw mm0, mm0, 10001000b  ; x2 x0 x2 x0
  272.         movq    mm4, [%3+8]     ; 4     ; w07 w06 w03 w02
  273. movq  mm5, mm1 ; 5  ; x7 x6 x5 x4
  274. pmaddwd mm3, mm0  ; x2*w05+x0*w04 x2*w01+x0*w00
  275.         movq    mm6, [%3+32]    ; 6     ; w21 w20 w17 w16
  276. pshufw  mm1, mm1, 10001000b  ; x6 x4 x6 x4
  277. pmaddwd mm4, mm1  ; x6*w07+x4*w06 x6*w03+x4*w02
  278.         movq    mm7, [%3+40]    ; 7     ; w23 w22 w19 w18
  279. pshufw  mm2, mm2, 11011101b  ; x3 x1 x3 x1
  280. pmaddwd mm6, mm2  ; x3*w21+x1*w20 x3*w17+x1*w16
  281. pshufw  mm5, mm5, 11011101b  ; x7 x5 x7 x5
  282. pmaddwd mm7, mm5  ; x7*w23+x5*w22 x7*w19+x5*w18
  283.         paddd   mm3, [%4]             ; +%4
  284.         pmaddwd mm0, [%3+16]            ; x2*w13+x0*w12 x2*w09+x0*w08
  285. paddd  mm3, mm4  ; 4  ; a1=sum(even1) a0=sum(even0)
  286.         pmaddwd mm1, [%3+24]            ; x6*w15+x4*w14 x6*w11+x4*w10
  287. movq  mm4, mm3  ; 4  ; a1 a0
  288.         pmaddwd mm2, [%3+48]            ; x3*w29+x1*w28 x3*w25+x1*w24
  289. paddd  mm6, mm7  ; 7  ; b1=sum(odd1) b0=sum(odd0)
  290.         pmaddwd mm5, [%3+56]            ; x7*w31+x5*w30 x7*w27+x5*w26
  291. paddd mm3, mm6  ; a1+b1 a0+b0
  292.         paddd mm0, [%4]               ; +%4
  293. psrad mm3, SHIFT_INV_ROW  ; y1=a1+b1 y0=a0+b0
  294. paddd mm0, mm1  ; 1  ; a3=sum(even3) a2=sum(even2)
  295. psubd mm4, mm6  ; 6  ; a1-b1 a0-b0
  296. movq mm7, mm0  ; 7  ; a3 a2
  297. paddd mm2, mm5  ; 5  ; b3=sum(odd3) b2=sum(odd2)
  298. paddd mm0, mm2  ; a3+b3 a2+b2
  299. psrad mm4, SHIFT_INV_ROW  ; y6=a1-b1 y7=a0-b0
  300. psubd mm7, mm2  ; 2  ; a3-b3 a2-b2
  301. psrad mm0, SHIFT_INV_ROW  ; y3=a3+b3 y2=a2+b2
  302. psrad mm7, SHIFT_INV_ROW  ; y4=a3-b3 y5=a2-b2
  303. packssdw mm3, mm0  ; 0  ; y3 y2 y1 y0
  304. packssdw mm7, mm4  ; 4  ; y6 y7 y4 y5
  305.         movq [%2], mm3            ; 3     ; save y3 y2 y1 y0
  306. pshufw mm7, mm7, 10110001b  ; y7 y6 y5 y4
  307.         movq [%2+8], mm7          ; 7     ; save y7 y6 y5 y4
  308. %endmacro
  309. ;=============================================================================
  310. ;
  311. ;=============================================================================
  312. ;=============================================================================
  313. ;
  314. ; The first stage DCT 8x8 - forward DCTs of columns
  315. ;
  316. ; The %2puts are multiplied
  317. ; for rows 0,4 - on cos_4_16,
  318. ; for rows 1,7 - on cos_1_16,
  319. ; for rows 2,6 - on cos_2_16,
  320. ; for rows 3,5 - on cos_3_16
  321. ; and are shifted to the left for rise of accuracy
  322. ;
  323. ;-----------------------------------------------------------------------------
  324. ;
  325. ; The 8-point scaled forward DCT algorithm (26a8m)
  326. ;
  327. ;-----------------------------------------------------------------------------
  328. ;
  329. ; #define DCT_8_FRW_COL(x, y)
  330. ;{
  331. ; short t0, t1, t2, t3, t4, t5, t6, t7;
  332. ; short tp03, tm03, tp12, tm12, tp65, tm65;
  333. ; short tp465, tm465, tp765, tm765;
  334. ;
  335. ; t0 = LEFT_SHIFT ( x[0] + x[7] );
  336. ; t1 = LEFT_SHIFT ( x[1] + x[6] );
  337. ; t2 = LEFT_SHIFT ( x[2] + x[5] );
  338. ; t3 = LEFT_SHIFT ( x[3] + x[4] );
  339. ; t4 = LEFT_SHIFT ( x[3] - x[4] );
  340. ; t5 = LEFT_SHIFT ( x[2] - x[5] );
  341. ; t6 = LEFT_SHIFT ( x[1] - x[6] );
  342. ; t7 = LEFT_SHIFT ( x[0] - x[7] );
  343. ;
  344. ; tp03 = t0 + t3;
  345. ; tm03 = t0 - t3;
  346. ; tp12 = t1 + t2;
  347. ; tm12 = t1 - t2;
  348. ;
  349. ; y[0] = tp03 + tp12;
  350. ; y[4] = tp03 - tp12;
  351. ;
  352. ; y[2] = tm03 + tm12 * tg_2_16;
  353. ; y[6] = tm03 * tg_2_16 - tm12;
  354. ;
  355. ; tp65 =(t6 +t5 )*cos_4_16;
  356. ; tm65 =(t6 -t5 )*cos_4_16;
  357. ;
  358. ; tp765 = t7 + tp65;
  359. ; tm765 = t7 - tp65;
  360. ; tp465 = t4 + tm65;
  361. ; tm465 = t4 - tm65;
  362. ;
  363. ; y[1] = tp765 + tp465 * tg_1_16;
  364. ; y[7] = tp765 * tg_1_16 - tp465;
  365. ; y[5] = tm765 * tg_3_16 + tm465;
  366. ; y[3] = tm765 - tm465 * tg_3_16;
  367. ;}
  368. ;
  369. ;=============================================================================
  370. ;
  371. ; DCT_8_FRW_COL_4      INP, OUT
  372. ;
  373. %macro DCT_8_FRW_COL_4          2
  374.         LOCAL x0, x1, x2, x3, x4, x5, x6, x7
  375.         LOCAL y0, y1, y2, y3, y4, y5, y6, y7
  376.         x0 equ [%1 + 0*16]
  377.         x1 equ [%1 + 1*16]
  378.         x2 equ [%1 + 2*16]
  379.         x3 equ [%1 + 3*16]
  380.         x4 equ [%1 + 4*16]
  381.         x5 equ [%1 + 5*16]
  382.         x6 equ [%1 + 6*16]
  383.         x7 equ [%1 + 7*16]
  384.         y0 equ [%2 + 0*16]
  385.         y1 equ [%2 + 1*16]
  386.         y2 equ [%2 + 2*16]
  387.         y3 equ [%2 + 3*16]
  388.         y4 equ [%2 + 4*16]
  389.         y5 equ [%2 + 5*16]
  390.         y6 equ [%2 + 6*16]
  391.         y7 equ [%2 + 7*16]
  392.         movq mm0, x1 ; 0 ; x1
  393.         movq mm1, x6 ; 1 ; x6
  394.         movq mm2, mm0 ; 2 ; x1
  395.         movq mm3, x2 ; 3 ; x2
  396.         paddsw mm0, mm1 ; t1 = x[1] + x[6]
  397.         movq mm4, x5 ; 4 ; x5
  398.         psllw mm0, SHIFT_FRW_COL ; t1
  399.         movq mm5, x0 ; 5 ; x0
  400.         paddsw mm4, mm3 ; t2 = x[2] + x[5]
  401.         paddsw mm5, x7 ; t0 = x[0] + x[7]
  402.         psllw mm4, SHIFT_FRW_COL ; t2
  403.         movq mm6, mm0 ; 6 ; t1
  404.         psubsw mm2, mm1 ; 1 ; t6 = x[1] - x[6]
  405.         movq mm1, [tg_2_16] ; 1 ; tg_2_16
  406.         psubsw mm0, mm4 ; tm12 = t1 - t2
  407.         movq mm7, x3 ; 7 ; x3
  408.         pmulhw mm1, mm0 ; tm12*tg_2_16
  409.         paddsw mm7, x4 ; t3 = x[3] + x[4]
  410.         psllw mm5, SHIFT_FRW_COL ; t0
  411.         paddsw mm6, mm4 ; 4 ; tp12 = t1 + t2
  412.         psllw mm7, SHIFT_FRW_COL ; t3
  413.         movq mm4, mm5 ; 4 ; t0
  414.         psubsw mm5, mm7 ; tm03 = t0 - t3
  415.         paddsw mm1, mm5 ; y2 = tm03 + tm12*tg_2_16
  416.         paddsw mm4, mm7 ; 7 ; tp03 = t0 + t3
  417.         por mm1, [one_corr] ; correction y2 +0.5
  418.         psllw mm2, SHIFT_FRW_COL+1 ; t6
  419.         pmulhw mm5, [tg_2_16] ; tm03*tg_2_16
  420.         movq mm7, mm4 ; 7 ; tp03
  421.         psubsw mm3, x5 ; t5 = x[2] - x[5]
  422.         psubsw mm4, mm6 ; y4 = tp03 - tp12
  423.         movq y2, mm1 ; 1 ; save y2
  424.         paddsw mm7, mm6 ; 6 ; y0 = tp03 + tp12
  425.         movq mm1, x3 ; 1 ; x3
  426.         psllw mm3, SHIFT_FRW_COL+1 ; t5
  427.         psubsw mm1, x4 ; t4 = x[3] - x[4]
  428.         movq mm6, mm2 ; 6 ; t6
  429.         movq y4, mm4 ; 4 ; save y4
  430.         paddsw mm2, mm3 ; t6 + t5
  431.         pmulhw mm2, [ocos_4_16] ; tp65 = (t6 + t5)*cos_4_16
  432.         psubsw mm6, mm3 ; 3 ; t6 - t5
  433.         pmulhw mm6, [ocos_4_16] ; tm65 = (t6 - t5)*cos_4_16
  434.         psubsw mm5, mm0 ; 0 ; y6 = tm03*tg_2_16 - tm12
  435.         por mm5, [one_corr] ; correction y6 +0.5
  436.         psllw mm1, SHIFT_FRW_COL ; t4
  437.         por mm2, [one_corr] ; correction tp65 +0.5
  438.         movq mm4, mm1 ; 4 ; t4
  439.         movq mm3, x0 ; 3 ; x0
  440.         paddsw mm1, mm6 ; tp465 = t4 + tm65
  441.         psubsw mm3, x7 ; t7 = x[0] - x[7]
  442.         psubsw mm4, mm6 ; 6 ; tm465 = t4 - tm65
  443.         movq mm0, [tg_1_16] ; 0 ; tg_1_16
  444.         psllw mm3, SHIFT_FRW_COL ; t7
  445.         movq mm6, [tg_3_16] ; 6 ; tg_3_16
  446.         pmulhw mm0, mm1 ; tp465*tg_1_16
  447.         movq y0, mm7 ; 7 ; save y0
  448.         pmulhw mm6, mm4 ; tm465*tg_3_16
  449.         movq y6, mm5 ; 5 ; save y6
  450.         movq mm7, mm3 ; 7 ; t7
  451.         movq mm5, [tg_3_16] ; 5 ; tg_3_16
  452.         psubsw mm7, mm2 ; tm765 = t7 - tp65
  453.         paddsw mm3, mm2 ; 2 ; tp765 = t7 + tp65
  454.         pmulhw mm5, mm7 ; tm765*tg_3_16
  455.         paddsw mm0, mm3 ; y1 = tp765 + tp465*tg_1_16
  456.         paddsw mm6, mm4 ; tm465*tg_3_16
  457.         pmulhw mm3, [tg_1_16] ; tp765*tg_1_16
  458.         por mm0, [one_corr] ; correction y1 +0.5
  459.         paddsw mm5, mm7 ; tm765*tg_3_16
  460.         psubsw mm7, mm6 ; 6 ; y3 = tm765 - tm465*tg_3_16
  461.         movq y1, mm0 ; 0 ; save y1
  462.         paddsw mm5, mm4 ; 4 ; y5 = tm765*tg_3_16 + tm465
  463.         movq y3, mm7 ; 7 ; save y3
  464.         psubsw mm3, mm1 ; 1 ; y7 = tp765*tg_1_16 - tp465
  465.         movq y5, mm5 ; 5 ; save y5
  466.         movq y7, mm3 ; 3 ; save y7
  467. %endmacro
  468. ;
  469. ; DCT_8_INV_COL_4  INP,OUT
  470. ;
  471. %macro DCT_8_INV_COL_4          2
  472.         movq    mm0, [tg_3_16]
  473.         movq    mm3, [%1+16*3]
  474. movq mm1, mm0 ; tg_3_16
  475.         movq    mm5, [%1+16*5]
  476. pmulhw mm0, mm3 ; x3*(tg_3_16-1)
  477.         movq    mm4, [tg_1_16]
  478. pmulhw mm1, mm5 ; x5*(tg_3_16-1)
  479.         movq    mm7, [%1+16*7]
  480. movq mm2, mm4 ; tg_1_16
  481.         movq    mm6, [%1+16*1]
  482. pmulhw mm4, mm7 ; x7*tg_1_16
  483. paddsw mm0, mm3 ; x3*tg_3_16
  484. pmulhw mm2, mm6 ; x1*tg_1_16
  485. paddsw mm1, mm3 ; x3+x5*(tg_3_16-1)
  486. psubsw mm0, mm5 ; x3*tg_3_16-x5 = tm35
  487.         movq    mm3, [ocos_4_16]
  488. paddsw mm1, mm5 ; x3+x5*tg_3_16 = tp35
  489. paddsw mm4, mm6 ; x1+tg_1_16*x7 = tp17
  490. psubsw mm2, mm7 ; x1*tg_1_16-x7 = tm17
  491. movq mm5, mm4 ; tp17
  492. movq mm6, mm2 ; tm17
  493. paddsw mm5, mm1 ; tp17+tp35 = b0
  494. psubsw mm6, mm0 ; tm17-tm35 = b3
  495. psubsw mm4, mm1 ; tp17-tp35 = t1
  496. paddsw mm2, mm0 ; tm17+tm35 = t2
  497.         movq    mm7, [tg_2_16]
  498. movq mm1, mm4 ; t1
  499. ;       movq    [SCRATCH+0], mm5     ; save b0
  500.         movq    [%2+3*16], mm5      ; save b0
  501. paddsw mm1, mm2 ; t1+t2
  502. ;       movq    [SCRATCH+8], mm6     ; save b3
  503.         movq    [%2+5*16], mm6      ; save b3
  504. psubsw mm4, mm2 ; t1-t2
  505.         movq    mm5, [%1+2*16]
  506. movq mm0, mm7 ; tg_2_16
  507.         movq    mm6, [%1+6*16]
  508. pmulhw mm0, mm5 ; x2*tg_2_16
  509. pmulhw mm7, mm6 ; x6*tg_2_16
  510. ; slot
  511. pmulhw mm1, mm3 ; ocos_4_16*(t1+t2) = b1/2
  512. ; slot
  513.         movq    mm2, [%1+0*16]
  514. pmulhw mm4, mm3 ; ocos_4_16*(t1-t2) = b2/2
  515. psubsw mm0, mm6 ; t2*tg_2_16-x6 = tm26
  516. movq mm3, mm2 ; x0
  517.         movq    mm6, [%1+4*16]
  518. paddsw mm7, mm5 ; x2+x6*tg_2_16 = tp26
  519. paddsw mm2, mm6 ; x0+x4 = tp04
  520. psubsw mm3, mm6 ; x0-x4 = tm04
  521. movq mm5, mm2 ; tp04
  522. movq mm6, mm3 ; tm04
  523. psubsw mm2, mm7 ; tp04-tp26 = a3
  524. paddsw mm3, mm0 ; tm04+tm26 = a1
  525. paddsw mm1, mm1 ; b1
  526. paddsw mm4, mm4 ; b2
  527. paddsw mm5, mm7 ; tp04+tp26 = a0
  528. psubsw mm6, mm0 ; tm04-tm26 = a2
  529. movq mm7, mm3 ; a1
  530. movq mm0, mm6 ; a2
  531. paddsw mm3, mm1 ; a1+b1
  532. paddsw mm6, mm4 ; a2+b2
  533. psraw mm3, SHIFT_INV_COL ; dst1
  534. psubsw mm7, mm1 ; a1-b1
  535. psraw mm6, SHIFT_INV_COL ; dst2
  536. psubsw mm0, mm4 ; a2-b2
  537. ;       movq    mm1, [SCRATCH+0]     ; load b0
  538.         movq    mm1, [%2+3*16]      ; load b0
  539. psraw mm7, SHIFT_INV_COL ; dst6
  540. movq mm4, mm5 ; a0
  541. psraw mm0, SHIFT_INV_COL ; dst5
  542.         movq    [%2+1*16], mm3
  543. paddsw mm5, mm1 ; a0+b0
  544.         movq    [%2+2*16], mm6
  545. psubsw mm4, mm1 ; a0-b0
  546. ;       movq    mm3, [SCRATCH+8]     ; load b3
  547.         movq    mm3, [%2+5*16]      ; load b3
  548. psraw mm5, SHIFT_INV_COL ; dst0
  549. movq mm6, mm2 ; a3
  550. psraw mm4, SHIFT_INV_COL ; dst7
  551.         movq    [%2+5*16], mm0
  552. paddsw mm2, mm3 ; a3+b3
  553.         movq    [%2+6*16], mm7
  554. psubsw mm6, mm3 ; a3-b3
  555.         movq    [%2+0*16], mm5
  556. psraw mm2, SHIFT_INV_COL ; dst3
  557.         movq    [%2+7*16], mm4
  558. psraw mm6, SHIFT_INV_COL ; dst4
  559.         movq    [%2+3*16], mm2
  560.         movq    [%2+4*16], mm6
  561. %endmacro
  562. section .text
  563. ;=============================================================================
  564. ;
  565. ; void idct_mmx (short * const src_result);
  566. ;
  567. ;=============================================================================
  568. align 16
  569. cglobal idct_mmx
  570. idct_mmx
  571.         mov eax, dword [esp + 4]
  572.         DCT_8_INV_ROW_1 eax+0, eax+0, tab_i_04, rounder_0
  573.         DCT_8_INV_ROW_1 eax+16, eax+16, tab_i_17, rounder_1
  574.         DCT_8_INV_ROW_1 eax+32, eax+32, tab_i_26, rounder_2
  575.         DCT_8_INV_ROW_1 eax+48, eax+48, tab_i_35, rounder_3
  576.         DCT_8_INV_ROW_1 eax+64, eax+64, tab_i_04, rounder_4
  577.         DCT_8_INV_ROW_1 eax+80, eax+80, tab_i_35, rounder_5
  578.         DCT_8_INV_ROW_1 eax+96, eax+96, tab_i_26, rounder_6
  579.         DCT_8_INV_ROW_1 eax+112, eax+112, tab_i_17, rounder_7
  580.         DCT_8_INV_COL_4 eax+0,eax+0
  581.         DCT_8_INV_COL_4 eax+8,eax+8
  582.         ret    
  583. ;=============================================================================
  584. ;
  585. ; void idct_sse (short * const src_result);
  586. ;
  587. ;=============================================================================
  588. align 16
  589. cglobal idct_xmm
  590. idct_xmm
  591.         mov eax, dword [esp + 4]
  592.         DCT_8_INV_ROW_1_sse eax+0, eax+0, tab_i_04_sse, rounder_0
  593.         DCT_8_INV_ROW_1_sse eax+16, eax+16, tab_i_17_sse, rounder_1
  594.         DCT_8_INV_ROW_1_sse eax+32, eax+32, tab_i_26_sse, rounder_2
  595.         DCT_8_INV_ROW_1_sse eax+48, eax+48, tab_i_35_sse, rounder_3
  596.         DCT_8_INV_ROW_1_sse eax+64, eax+64, tab_i_04_sse, rounder_4
  597.         DCT_8_INV_ROW_1_sse eax+80, eax+80, tab_i_35_sse, rounder_5
  598.         DCT_8_INV_ROW_1_sse eax+96, eax+96, tab_i_26_sse, rounder_6
  599.         DCT_8_INV_ROW_1_sse eax+112, eax+112, tab_i_17_sse, rounder_7
  600.         DCT_8_INV_COL_4 eax+0, eax+0
  601.         DCT_8_INV_COL_4 eax+8, eax+8
  602.         ret