text_idct_mmx.c
上传用户:hxb_1234
上传日期:2010-03-30
资源大小:8328k
文件大小:12k
源码类别:

VC书籍

开发平台:

Visual C++

  1. #define DEFAULT_FUNCTION_NAME       Fast_IDCT
  2. #ifndef MMX_IDCT_NAME
  3. #define MMX_IDCT_NAME DEFAULT_FUNCTION_NAME
  4. #endif
  5. #define int16_t short
  6. #define int32_t int
  7. #define uint64_t unsigned __int64
  8. #define MPTR qword ptr 
  9. #define SHORT4_TO_QWORD(A, B, C, D)   ( 
  10.     ( ( ((uint64_t)(A)) & ((uint64_t)(0xffff)) )  <<  0 ) | 
  11.     ( ( ((uint64_t)(B)) & ((uint64_t)(0xffff)) )  << 16 ) | 
  12.     ( ( ((uint64_t)(C)) & ((uint64_t)(0xffff)) )  << 32 ) | 
  13.     ( ( ((uint64_t)(D)) & ((uint64_t)(0xffff)) )  << 48 ) ) 
  14. #define INT2_TO_QWORD(A, B)    ( 
  15.     ( ( ((uint64_t)(A)) & ((uint64_t)(0xffffffff)) )  <<  0 ) | 
  16.     ( ( ((uint64_t)(B)) & ((uint64_t)(0xffffffff)) )  << 32 ) )
  17. #define BITS_INV_ACC      5                             
  18. #define SHIFT_INV_ROW     (16 - BITS_INV_ACC)
  19. #define SHIFT_INV_COL     (1 + BITS_INV_ACC)
  20. #define RND_INV_ROW       (1024 * (6 - BITS_INV_ACC))   
  21. #define RND_INV_COL       (16 * (BITS_INV_ACC - 3))     
  22. #define RND_INV_CORR      (RND_INV_COL - 1)             
  23. #define BITS_FRW_ACC      3                             
  24. #define SHIFT_FRW_COL     BITS_FRW_ACC
  25. #define SHIFT_FRW_ROW     (BITS_FRW_ACC + 17)
  26. #define RND_FRW_ROW       (262144 * (BITS_FRW_ACC - 1)) 
  27. static const uint64_t   tg_1_16 = SHORT4_TO_QWORD( 13036,  13036,  13036,  13036 );
  28. static const uint64_t   tg_2_16 = SHORT4_TO_QWORD( 27146,  27146,  27146,  27146 );
  29. static const uint64_t   tg_3_16 = SHORT4_TO_QWORD(-21746, -21746, -21746, -21746 );
  30. static const uint64_t ocos_4_16 = SHORT4_TO_QWORD( 23170,  23170,  23170,  23170 );
  31. #if   SHIFT_INV_ROW == 12
  32. static const uint64_t rounder[8] = {
  33. INT2_TO_QWORD( 65536, 65536),        
  34. INT2_TO_QWORD(  7195,  7195),  
  35. INT2_TO_QWORD(  4520,  4520),  
  36. INT2_TO_QWORD(  2407,  2407),  
  37. INT2_TO_QWORD(     0,     0),  
  38. INT2_TO_QWORD(   240,   240), 
  39. INT2_TO_QWORD(  1024,  1024), 
  40. INT2_TO_QWORD(  1024,  1024)  
  41. };
  42. #elif SHIFT_INV_ROW == 11
  43. static const uint64_t rounder[2*8] = {
  44. INT2_TO_QWORD( 65536, 65536), 
  45. INT2_TO_QWORD(  3597,  3597), 
  46. INT2_TO_QWORD(  2260,  2260), 
  47. INT2_TO_QWORD(  1203,  1203), 
  48. INT2_TO_QWORD(   0,   0), 
  49. INT2_TO_QWORD(   120, 120), 
  50. INT2_TO_QWORD(   512, 512), 
  51. INT2_TO_QWORD(   512, 512)  
  52. };
  53. #endif
  54. static const uint64_t tab_i_04[8*8] = {
  55.   SHORT4_TO_QWORD( 16384,  16384,  16384, -16384 ),   
  56. SHORT4_TO_QWORD( 21407,   8867,   8867, -21407 ),   
  57. SHORT4_TO_QWORD( 16384, -16384,  16384,  16384 ),   
  58. SHORT4_TO_QWORD( -8867,  21407, -21407,  -8867 ),   
  59. SHORT4_TO_QWORD( 22725,  12873,  19266, -22725 ),   
  60. SHORT4_TO_QWORD( 19266,   4520,  -4520, -12873 ),   
  61. SHORT4_TO_QWORD( 12873,   4520,   4520,  19266 ),   
  62. SHORT4_TO_QWORD(-22725,  19266, -12873, -22725 ),   
  63. SHORT4_TO_QWORD( 22725,  22725,  22725, -22725 ),   
  64. SHORT4_TO_QWORD( 29692,  12299,  12299, -29692 ),   
  65. SHORT4_TO_QWORD( 22725, -22725,  22725,  22725 ),   
  66. SHORT4_TO_QWORD(-12299,  29692, -29692, -12299 ),   
  67. SHORT4_TO_QWORD( 31521,  17855,  26722, -31521 ),   
  68. SHORT4_TO_QWORD( 26722,   6270,  -6270, -17855 ),   
  69. SHORT4_TO_QWORD( 17855,   6270,   6270,  26722 ),   
  70. SHORT4_TO_QWORD(-31521,  26722, -17855, -31521 ),   
  71. SHORT4_TO_QWORD( 21407,  21407,  21407, -21407 ),   
  72. SHORT4_TO_QWORD( 27969,  11585,  11585, -27969 ),   
  73. SHORT4_TO_QWORD( 21407, -21407,  21407,  21407 ),   
  74. SHORT4_TO_QWORD(-11585,  27969, -27969, -11585 ),   
  75. SHORT4_TO_QWORD( 29692,  16819,  25172, -29692 ),   
  76. SHORT4_TO_QWORD( 25172,   5906,  -5906, -16819 ),   
  77. SHORT4_TO_QWORD( 16819,   5906,   5906,  25172 ),   
  78. SHORT4_TO_QWORD(-29692,  25172, -16819, -29692 ),   
  79. SHORT4_TO_QWORD( 19266,  19266,  19266, -19266 ),   
  80. SHORT4_TO_QWORD( 25172,  10426,  10426, -25172 ),   
  81. SHORT4_TO_QWORD( 19266, -19266,  19266,  19266 ),   
  82. SHORT4_TO_QWORD(-10426,  25172, -25172, -10426 ),   
  83. SHORT4_TO_QWORD( 26722,  15137,  22654, -26722 ),   
  84. SHORT4_TO_QWORD( 22654,   5315,  -5315, -15137 ),   
  85. SHORT4_TO_QWORD( 15137,   5315,   5315,  22654 ),   
  86. SHORT4_TO_QWORD(-26722,  22654, -15137, -26722 ),   
  87.   SHORT4_TO_QWORD( 16384,  16384,  16384, -16384 ),   
  88. SHORT4_TO_QWORD( 21407,   8867,   8867, -21407 ),   
  89. SHORT4_TO_QWORD( 16384, -16384,  16384,  16384 ),   
  90. SHORT4_TO_QWORD(-8867,  21407, -21407,  -8867  ),   
  91. SHORT4_TO_QWORD( 22725,  12873,  19266, -22725 ),   
  92. SHORT4_TO_QWORD( 19266,   4520,  -4520, -12873 ),   
  93. SHORT4_TO_QWORD( 12873,   4520,   4520,  19266 ),   
  94. SHORT4_TO_QWORD(-22725,  19266, -12873, -22725 ),   
  95. SHORT4_TO_QWORD( 19266,  19266,  19266, -19266 ),   
  96. SHORT4_TO_QWORD( 25172,  10426,  10426, -25172 ),   
  97. SHORT4_TO_QWORD( 19266, -19266,  19266,  19266 ),   
  98. SHORT4_TO_QWORD(-10426,  25172, -25172, -10426 ),   
  99. SHORT4_TO_QWORD( 26722,  15137,  22654, -26722 ),   
  100. SHORT4_TO_QWORD( 22654,   5315,  -5315, -15137 ),   
  101. SHORT4_TO_QWORD( 15137,   5315,   5315,  22654 ),   
  102. SHORT4_TO_QWORD(-26722,  22654, -15137, -26722 ),   
  103. SHORT4_TO_QWORD( 21407,  21407,  21407, -21407 ),   
  104. SHORT4_TO_QWORD( 27969,  11585,  11585, -27969 ),   
  105. SHORT4_TO_QWORD( 21407, -21407,  21407,  21407 ),   
  106. SHORT4_TO_QWORD(-11585,  27969, -27969, -11585 ),   
  107. SHORT4_TO_QWORD( 29692,  16819,  25172, -29692 ),   
  108. SHORT4_TO_QWORD( 25172,   5906,  -5906, -16819 ),   
  109. SHORT4_TO_QWORD( 16819,   5906,   5906,  25172 ),   
  110. SHORT4_TO_QWORD(-29692,  25172, -16819, -29692 ),   
  111. SHORT4_TO_QWORD( 22725,  22725,  22725, -22725 ),   
  112. SHORT4_TO_QWORD( 29692,  12299,  12299, -29692 ),   
  113. SHORT4_TO_QWORD( 22725, -22725,  22725,  22725 ),   
  114. SHORT4_TO_QWORD(-12299,  29692, -29692, -12299 ),   
  115. SHORT4_TO_QWORD( 31521,  17855,  26722, -31521 ),   
  116. SHORT4_TO_QWORD( 26722,   6270,  -6270, -17855 ),   
  117. SHORT4_TO_QWORD( 17855,   6270,   6270,  26722 ),   
  118. SHORT4_TO_QWORD(-31521,  26722, -17855, -31521 ),   
  119. };
  120. uint64_t tempMatrix[64/4];
  121. #define INP      eax
  122. #define ROUNDER  ebx
  123. #define TABLE    ecx
  124. #define OUTP     edx
  125. void MMX_IDCT_NAME
  126.               (int16_t *block) {
  127. __asm {
  128. push eax
  129. push ebx 
  130. push ecx
  131. push edx 
  132. push edi
  133. mov INP, block
  134. lea OUTP,  [tempMatrix]
  135. lea TABLE, [tab_i_04]
  136. lea ROUNDER, [rounder]
  137. mov edi, -8;                 ; i=-8
  138. align 16
  139. rowloop:
  140. movq mm0, MPTR [INP]  ; 0 ; x3 x2 x1 x0
  141. movq mm1, MPTR [INP+8] ; 1 ; x7 x6 x5 x4
  142. movq mm2, mm0  ; 2 ; x3 x2 x1 x0
  143. movq mm3, MPTR [TABLE] ; 3 ; w06 w04 w02 w00
  144. punpcklwd mm0, mm1  ; x5 x1 x4 x0
  145. movq mm5, mm0  ; 5 ; x5 x1 x4 x0
  146. punpckldq mm0, mm0  ; x4 x0 x4 x0
  147. movq mm4, MPTR [TABLE+8]  ; 4 ; w07 w05 w03 w01
  148. punpckhwd mm2, mm1 ; 1 ; x7 x3 x6 x2
  149. pmaddwd mm3, mm0  ; x4*w06+x0*w04 x4*w02+x0*w00
  150. movq mm6, mm2  ; 6  ; x7 x3 x6 x2
  151. movq mm1, MPTR [TABLE+32]  ; 1  ; w22 w20 w18 w16
  152. punpckldq mm2, mm2  ; x6 x2 x6 x2
  153. pmaddwd mm4, mm2  ; x6*w07+x2*w05 x6*w03+x2*w01
  154. punpckhdq mm5, mm5  ; x5 x1 x5 x1
  155. pmaddwd mm0, MPTR [TABLE+16]  ; x4*w14+x0*w12 x4*w10+x0*w08
  156. punpckhdq mm6, mm6  ; x7 x3 x7 x3
  157. movq mm7, MPTR [TABLE+40]  ; 7  ; w23 w21 w19 w17
  158. pmaddwd mm1, mm5  ; x5*w22+x1*w20 x5*w18+x1*w16
  159. paddd mm3, MPTR [ROUNDER]  ; +rounder
  160. pmaddwd mm7, mm6  ; x7*w23+x3*w21 x7*w19+x3*w17
  161. pmaddwd mm2, MPTR [TABLE+24]  ; x6*w15+x2*w13 x6*w11+x2*w09
  162. paddd mm3, mm4  ; 4  ; a1=sum(even1) a0=sum(even0)
  163. pmaddwd mm5, MPTR [TABLE+48]  ; x5*w30+x1*w28 x5*w26+x1*w24
  164. movq mm4, mm3  ; 4  ; a1 a0
  165. pmaddwd mm6, MPTR [TABLE+56]  ; x7*w31+x3*w29 x7*w27+x3*w25
  166. paddd mm1, mm7  ; 7  ; b1=sum(odd1) b0=sum(odd0)
  167. paddd mm0, MPTR [ROUNDER] ; +rounder
  168. psubd mm3, mm1  ; a1-b1 a0-b0
  169. psrad mm3, SHIFT_INV_ROW  ; y6=a1-b1 y7=a0-b0
  170. paddd mm1, mm4  ; 4  ; a1+b1 a0+b0
  171. paddd mm0, mm2  ; 2  ; a3=sum(even3) a2=sum(even2)
  172. psrad mm1, SHIFT_INV_ROW  ; y1=a1+b1 y0=a0+b0
  173. paddd mm5, mm6  ; 6  ; b3=sum(odd3) b2=sum(odd2)
  174. movq mm4, mm0  ; 4  ; a3 a2
  175. paddd mm0, mm5  ; a3+b3 a2+b2
  176. psubd mm4, mm5  ; 5  ; a3-b3 a2-b2
  177. psrad mm0, SHIFT_INV_ROW  ; y3=a3+b3 y2=a2+b2
  178. psrad mm4, SHIFT_INV_ROW  ; y4=a3-b3 y5=a2-b2
  179. packssdw mm1, mm0  ; 0  ; y3 y2 y1 y0
  180. packssdw mm4, mm3  ; 3  ; y6 y7 y4 y5
  181. movq mm7, mm4  ; 7  ; y6 y7 y4 y5
  182. psrld mm4, 16  ; 0 y6 0 y4
  183. pslld mm7, 16  ; y7 0 y5 0
  184. movq MPTR [OUTP], mm1  ; 1  ; save y3 y2 y1 y0
  185.                              
  186. por mm7, mm4  ; 4  ; y7 y6 y5 y4
  187. movq MPTR [OUTP+8], mm7  ; 7  ; save y7 y6 y5 y4
  188. add INP,  16                    ; add 1 row to input pointer
  189. add ROUNDER, 8                  ; go to next rounding values
  190. add OUTP, 16                    ; add 1 row to output pointer
  191. add TABLE,64                    ; move to next section of table
  192. add edi, 1
  193. jne rowloop;
  194. lea INP,   [tempMatrix] 
  195. mov OUTP,  block
  196. mov edi, -2;                 ; i=-2
  197. align 16
  198. colloop:
  199. movq mm0, tg_3_16
  200. movq mm3, MPTR [INP+16*3]
  201. movq mm1, mm0 ; tg_3_16
  202. movq mm5, MPTR [INP+16*5]
  203. pmulhw mm0, mm3 ; x3*(tg_3_16-1)
  204. movq mm4, tg_1_16
  205. pmulhw mm1, mm5 ; x5*(tg_3_16-1)
  206. movq mm7, MPTR [INP+16*7]
  207. movq mm2, mm4 ; tg_1_16
  208. movq mm6, MPTR [INP+16*1]
  209. pmulhw mm4, mm7 ; x7*tg_1_16
  210. paddsw mm0, mm3 ; x3*tg_3_16
  211. pmulhw mm2, mm6 ; x1*tg_1_16
  212. paddsw mm1, mm3 ; x3+x5*(tg_3_16-1)
  213. psubsw mm0, mm5 ; x3*tg_3_16-x5 = tm35
  214. movq mm3, ocos_4_16
  215. paddsw mm1, mm5 ; x3+x5*tg_3_16 = tp35
  216. paddsw mm4, mm6 ; x1+tg_1_16*x7 = tp17
  217. psubsw mm2, mm7 ; x1*tg_1_16-x7 = tm17
  218. movq mm5, mm4 ; tp17
  219. movq mm6, mm2 ; tm17
  220. paddsw mm5, mm1 ; tp17+tp35 = b0
  221. psubsw mm6, mm0 ; tm17-tm35 = b3
  222. psubsw mm4, mm1 ; tp17-tp35 = t1
  223. paddsw mm2, mm0 ; tm17+tm35 = t2
  224. movq mm7, tg_2_16
  225. movq mm1, mm4 ; t1
  226. ; movq MPTR [SCRATCH+0], mm5 ; save b0
  227. movq MPTR [OUTP+3*16], mm5 ; save b0
  228. paddsw mm1, mm2 ; t1+t2
  229. ; movq MPTR [SCRATCH+8], mm6 ; save b3
  230. movq MPTR [OUTP+5*16], mm6 ; save b3
  231. psubsw mm4, mm2 ; t1-t2
  232. movq mm5, MPTR [INP+2*16]
  233. movq mm0, mm7 ; tg_2_16
  234. movq mm6, MPTR [INP+6*16]
  235. pmulhw mm0, mm5 ; x2*tg_2_16
  236. pmulhw mm7, mm6 ; x6*tg_2_16
  237. ; slot
  238. pmulhw mm1, mm3 ; ocos_4_16*(t1+t2) = b1/2
  239. ; slot
  240. movq mm2, MPTR [INP+0*16]
  241. pmulhw mm4, mm3 ; ocos_4_16*(t1-t2) = b2/2
  242. psubsw mm0, mm6 ; t2*tg_2_16-x6 = tm26
  243. movq mm3, mm2 ; x0
  244. movq mm6, MPTR [INP+4*16]
  245. paddsw mm7, mm5 ; x2+x6*tg_2_16 = tp26
  246. paddsw mm2, mm6 ; x0+x4 = tp04
  247. psubsw mm3, mm6 ; x0-x4 = tm04
  248. movq mm5, mm2 ; tp04
  249. movq mm6, mm3 ; tm04
  250. psubsw mm2, mm7 ; tp04-tp26 = a3
  251. paddsw mm3, mm0 ; tm04+tm26 = a1
  252. paddsw mm1, mm1 ; b1
  253. paddsw mm4, mm4 ; b2
  254. paddsw mm5, mm7 ; tp04+tp26 = a0
  255. psubsw mm6, mm0 ; tm04-tm26 = a2
  256. movq mm7, mm3 ; a1
  257. movq mm0, mm6 ; a2
  258. paddsw mm3, mm1 ; a1+b1
  259. paddsw mm6, mm4 ; a2+b2
  260. psraw mm3, SHIFT_INV_COL ; dst1
  261. psubsw mm7, mm1 ; a1-b1
  262. psraw mm6, SHIFT_INV_COL ; dst2
  263. psubsw mm0, mm4 ; a2-b2
  264. ; movq mm1, MPTR [SCRATCH+0] ; load b0
  265. movq mm1, MPTR [OUTP+3*16] ; load b0
  266. psraw mm7, SHIFT_INV_COL ; dst6
  267. movq mm4, mm5 ; a0
  268. psraw mm0, SHIFT_INV_COL ; dst5
  269. movq MPTR [OUTP+1*16], mm3
  270. paddsw mm5, mm1 ; a0+b0
  271. movq MPTR [OUTP+2*16], mm6
  272. psubsw mm4, mm1 ; a0-b0
  273. ; movq mm3, MPTR [SCRATCH+8] ; load b3
  274. movq mm3, MPTR [OUTP+5*16] ; load b3
  275. psraw mm5, SHIFT_INV_COL ; dst0
  276. movq mm6, mm2 ; a3
  277. psraw mm4, SHIFT_INV_COL ; dst7
  278. movq MPTR [OUTP+5*16], mm0
  279. paddsw mm2, mm3 ; a3+b3
  280. movq MPTR [OUTP+6*16], mm7
  281. psubsw mm6, mm3 ; a3-b3
  282. movq MPTR [OUTP+0*16], mm5
  283. psraw mm2, SHIFT_INV_COL ; dst3
  284. movq MPTR [OUTP+7*16], mm4
  285. psraw mm6, SHIFT_INV_COL ; dst4
  286. movq MPTR [OUTP+3*16], mm2
  287. movq MPTR [OUTP+4*16], mm6
  288. lea INP,   [tempMatrix] 
  289. mov OUTP,  block
  290. add INP,  8                    ; add 4 cols to input pointer
  291. add OUTP, 8                    ; add 4 cols to output pointer
  292. add edi, 1
  293. jne colloop
  294. pop edi
  295. pop edx 
  296. pop ecx
  297. pop ebx
  298. pop eax
  299. emms 
  300. }; 
  301. };