text_idct_mmx.c
上传用户:enenge
上传日期:2007-01-08
资源大小:96k
文件大小:20k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /**************************************************************************
  2.  *                                                                        *
  3.  * This code is developed by John Funnell.  This software is an           *
  4.  * an implementation of a part of one or more MPEG-4 Video tools as       *
  5.  * specified in ISO/IEC 14496-2 standard.  Those intending to use this    *
  6.  * software module in hardware or software products are advised that its  *
  7.  * use may infringe existing patents or copyrights, and any such use      *
  8.  * would be at such party's own risk.  The original developer of this     *
  9.  * software module and his/her company, and subsequent editors and their  *
  10.  * companies (including Project Mayo), will have no liability for use of  *
  11.  * this software or modifications or derivatives thereof.                 *
  12.  *                                                                        *
  13.  * Project Mayo gives users of the Codec a license to this software       *
  14.  * module or modifications thereof for use in hardware or software        *
  15.  * products claiming conformance to the MPEG-4 Video Standard as          *
  16.  * described in the Open DivX license.                                    *
  17.  *                                                                        *
  18.  * The complete Open DivX license can be found at                         *
  19.  * http://www.projectmayo.com/opendivx/license.php .                      *
  20.  *                                                                        *
  21.  **************************************************************************/
  22. /**************************************************************************
  23.  *
  24.  *  text_idct_mmx.c
  25.  *
  26.  *  Copyright (C) 2001  Project Mayo
  27.  *
  28.  *  John Funnell
  29.  *
  30.  *  DivX Advance Research Center <darc@projectmayo.com>
  31.  *
  32.  **************************************************************************/
  33. /* This file contains idct functions with MMX optimization.               */
  34. /* Please see acknowledgement below.                                      */
  35. /*
  36. ;
  37. ; MMX iDCT
  38. ;
  39. ; Originally provided by Intel at AP-922
  40. ; http://developer.intel.com/vtune/cbts/strmsimd/922down.htm
  41. ; (See more app notes at http://developer.intel.com/vtune/cbts/strmsimd/appnotes.htm)
  42. ; but in a limited edition.
  43. ; New macro implements a column part for precise iDCT
  44. ; The routine precision now satisfies IEEE standard 1180-1990. 
  45. ;
  46. ; Copyright (c) 2000-2001 Peter Gubanov <peter@elecard.net.ru>
  47. ; Rounding trick Copyright (c) 2000 Michel Lespinasse <walken@zoy.org>
  48. ;
  49. ; http://www.elecard.com/peter/idct.html
  50. ; http://www.linuxvideo.org/mpeg2dec/
  51. ;
  52. ; Conversion to MS-style inline C format (c) 2001 Project Mayo Inc. John Funnell
  53. ;
  54. ; Version v1.0.0 10 January 2001
  55. ;
  56. */
  57. /*
  58.  if you are not setting the name of you MMX idct function with compile flag MMX_IDCT_NAME,
  59.  then you need to choose a name to insert in here:
  60. */
  61. #define DEFAULT_FUNCTION_NAME       Fast_IDCT
  62. #ifndef MMX_IDCT_NAME
  63. #define MMX_IDCT_NAME DEFAULT_FUNCTION_NAME
  64. #endif
  65. /* some types */
  66. #define int16_t short
  67. #define int32_t int
  68. #define uint64_t unsigned __int64
  69. #define MPTR qword ptr 
  70. /* some conversions from readable integer constants to qwords */
  71. #define SHORT4_TO_QWORD(A, B, C, D)   ( 
  72.     ( ( ((uint64_t)(A)) & ((uint64_t)(0xffff)) )  <<  0 ) | 
  73.     ( ( ((uint64_t)(B)) & ((uint64_t)(0xffff)) )  << 16 ) | 
  74.     ( ( ((uint64_t)(C)) & ((uint64_t)(0xffff)) )  << 32 ) | 
  75.     ( ( ((uint64_t)(D)) & ((uint64_t)(0xffff)) )  << 48 ) ) 
  76. #define INT2_TO_QWORD(A, B)    ( 
  77.     ( ( ((uint64_t)(A)) & ((uint64_t)(0xffffffff)) )  <<  0 ) | 
  78.     ( ( ((uint64_t)(B)) & ((uint64_t)(0xffffffff)) )  << 32 ) )
  79. #define BITS_INV_ACC      5                             /* 4 or 5 for IEEE */
  80. #define SHIFT_INV_ROW     (16 - BITS_INV_ACC)
  81. #define SHIFT_INV_COL     (1 + BITS_INV_ACC)
  82. #define RND_INV_ROW       (1024 * (6 - BITS_INV_ACC))   /* 1 << (SHIFT_INV_ROW-1) */
  83. #define RND_INV_COL       (16 * (BITS_INV_ACC - 3))     /* 1 << (SHIFT_INV_COL-1) */
  84. #define RND_INV_CORR      (RND_INV_COL - 1)             /* correction -1.0 and round */
  85. #define BITS_FRW_ACC      3                             /* 2 or 3 for accuracy */
  86. #define SHIFT_FRW_COL     BITS_FRW_ACC
  87. #define SHIFT_FRW_ROW     (BITS_FRW_ACC + 17)
  88. #define RND_FRW_ROW       (262144 * (BITS_FRW_ACC - 1)) /* 1 << (SHIFT_FRW_ROW-1) */
  89. static const uint64_t   tg_1_16 = SHORT4_TO_QWORD( 13036,  13036,  13036,  13036 );
  90. static const uint64_t   tg_2_16 = SHORT4_TO_QWORD( 27146,  27146,  27146,  27146 );
  91. static const uint64_t   tg_3_16 = SHORT4_TO_QWORD(-21746, -21746, -21746, -21746 );
  92. static const uint64_t ocos_4_16 = SHORT4_TO_QWORD( 23170,  23170,  23170,  23170 );
  93. /* rounding value that is added before the row transform's rounding */
  94. #if   SHIFT_INV_ROW == 12
  95. static const uint64_t rounder[8] = {
  96. INT2_TO_QWORD( 65536, 65536), /* rounder_0 */       
  97. INT2_TO_QWORD(  7195,  7195), /* rounder_1 */ 
  98. INT2_TO_QWORD(  4520,  4520), /* rounder_2 */ 
  99. INT2_TO_QWORD(  2407,  2407), /* rounder_3 */ 
  100. INT2_TO_QWORD(     0,     0), /* rounder_4 */ 
  101. INT2_TO_QWORD(   240,   240), /* rounder_5 */
  102. INT2_TO_QWORD(  1024,  1024), /* rounder_6 */
  103. INT2_TO_QWORD(  1024,  1024)  /* rounder_7 */
  104. };
  105. #elif SHIFT_INV_ROW == 11
  106. static const uint64_t rounder[2*8] = {
  107. INT2_TO_QWORD( 65536, 65536), /* rounder_0 */
  108. INT2_TO_QWORD(  3597,  3597), /* rounder_1 */
  109. INT2_TO_QWORD(  2260,  2260), /* rounder_2 */
  110. INT2_TO_QWORD(  1203,  1203), /* rounder_3 */
  111. INT2_TO_QWORD(   0,   0), /* rounder_4 */
  112. INT2_TO_QWORD(   120, 120), /* rounder_5 */
  113. INT2_TO_QWORD(   512, 512), /* rounder_6 */
  114. INT2_TO_QWORD(   512, 512)  /* rounder_7 */
  115. };
  116. #endif
  117. /*
  118. ;=============================================================================
  119. ;
  120. ; The first stage iDCT 8x8 - inverse DCTs of rows
  121. ;
  122. ;-----------------------------------------------------------------------------
  123. ; The 8-point inverse DCT direct algorithm
  124. ;-----------------------------------------------------------------------------
  125. ;
  126. ; static const short w[32] = {
  127. ; FIX(cos_4_16), FIX(cos_2_16), FIX(cos_4_16), FIX(cos_6_16),
  128. ; FIX(cos_4_16), FIX(cos_6_16), -FIX(cos_4_16), -FIX(cos_2_16),
  129. ; FIX(cos_4_16), -FIX(cos_6_16), -FIX(cos_4_16), FIX(cos_2_16),
  130. ; FIX(cos_4_16), -FIX(cos_2_16), FIX(cos_4_16), -FIX(cos_6_16),
  131. ; FIX(cos_1_16), FIX(cos_3_16), FIX(cos_5_16), FIX(cos_7_16),
  132. ; FIX(cos_3_16), -FIX(cos_7_16), -FIX(cos_1_16), -FIX(cos_5_16),
  133. ; FIX(cos_5_16), -FIX(cos_1_16), FIX(cos_7_16), FIX(cos_3_16),
  134. ; FIX(cos_7_16), -FIX(cos_5_16), FIX(cos_3_16), -FIX(cos_1_16) };
  135. ;
  136. ; #define DCT_8_INV_ROW(x, y)
  137. ;{
  138. ; int a0, a1, a2, a3, b0, b1, b2, b3;
  139. ;
  140. ; a0 =x[0]*w[0]+x[2]*w[1]+x[4]*w[2]+x[6]*w[3];
  141. ; a1 =x[0]*w[4]+x[2]*w[5]+x[4]*w[6]+x[6]*w[7];
  142. ; a2 = x[0] * w[ 8] + x[2] * w[ 9] + x[4] * w[10] + x[6] * w[11];
  143. ; a3 = x[0] * w[12] + x[2] * w[13] + x[4] * w[14] + x[6] * w[15];
  144. ; b0 = x[1] * w[16] + x[3] * w[17] + x[5] * w[18] + x[7] * w[19];
  145. ; b1 = x[1] * w[20] + x[3] * w[21] + x[5] * w[22] + x[7] * w[23];
  146. ; b2 = x[1] * w[24] + x[3] * w[25] + x[5] * w[26] + x[7] * w[27];
  147. ; b3 = x[1] * w[28] + x[3] * w[29] + x[5] * w[30] + x[7] * w[31];
  148. ;
  149. ; y[0] = SHIFT_ROUND ( a0 + b0 );
  150. ; y[1] = SHIFT_ROUND ( a1 + b1 );
  151. ; y[2] = SHIFT_ROUND ( a2 + b2 );
  152. ; y[3] = SHIFT_ROUND ( a3 + b3 );
  153. ; y[4] = SHIFT_ROUND ( a3 - b3 );
  154. ; y[5] = SHIFT_ROUND ( a2 - b2 );
  155. ; y[6] = SHIFT_ROUND ( a1 - b1 );
  156. ; y[7] = SHIFT_ROUND ( a0 - b0 );
  157. ;}
  158. ;
  159. ;-----------------------------------------------------------------------------
  160. ;
  161. ; In this implementation the outputs of the iDCT-1D are multiplied
  162. ; for rows 0,4 - by cos_4_16,
  163. ; for rows 1,7 - by cos_1_16,
  164. ; for rows 2,6 - by cos_2_16,
  165. ; for rows 3,5 - by cos_3_16
  166. ; and are shifted to the left for better accuracy
  167. ;
  168. ; For the constants used,
  169. ; FIX(float_const) = (short) (float_const * (1<<15) + 0.5)
  170. ;
  171. ;=============================================================================
  172. */
  173. /*
  174. ;=============================================================================
  175. ; code for MMX
  176. ;=============================================================================
  177. ; Table for rows 0,4 - constants are multiplied by cos_4_16
  178. */
  179. static const uint64_t tab_i_04[8*8] = {
  180. /* Table for rows 0,4 - constants are multiplied by cos_4_16 */
  181.   SHORT4_TO_QWORD( 16384,  16384,  16384, -16384 ),   /* movq-> w06 w04 w02 w00 */
  182. SHORT4_TO_QWORD( 21407,   8867,   8867, -21407 ),   /*        w07 w05 w03 w01 */
  183. SHORT4_TO_QWORD( 16384, -16384,  16384,  16384 ),   /*        w14 w12 w10 w08 */
  184. SHORT4_TO_QWORD( -8867,  21407, -21407,  -8867 ),   /*        w15 w13 w11 w09 */
  185. SHORT4_TO_QWORD( 22725,  12873,  19266, -22725 ),   /*        w22 w20 w18 w16 */
  186. SHORT4_TO_QWORD( 19266,   4520,  -4520, -12873 ),   /*        w23 w21 w19 w17 */
  187. SHORT4_TO_QWORD( 12873,   4520,   4520,  19266 ),   /*        w30 w28 w26 w24 */
  188. SHORT4_TO_QWORD(-22725,  19266, -12873, -22725 ),   /*        w31 w29 w27 w25 */
  189. /* Table for rows 1,7 - constants are multiplied by cos_1_16 */
  190. SHORT4_TO_QWORD( 22725,  22725,  22725, -22725 ),   /* movq-> w06 w04 w02 w00 */
  191. SHORT4_TO_QWORD( 29692,  12299,  12299, -29692 ),   /*        w07 w05 w03 w01 */
  192. SHORT4_TO_QWORD( 22725, -22725,  22725,  22725 ),   /*        w14 w12 w10 w08 */
  193. SHORT4_TO_QWORD(-12299,  29692, -29692, -12299 ),   /*        w15 w13 w11 w09 */
  194. SHORT4_TO_QWORD( 31521,  17855,  26722, -31521 ),   /*        w22 w20 w18 w16 */
  195. SHORT4_TO_QWORD( 26722,   6270,  -6270, -17855 ),   /*        w23 w21 w19 w17 */
  196. SHORT4_TO_QWORD( 17855,   6270,   6270,  26722 ),   /*        w30 w28 w26 w24 */
  197. SHORT4_TO_QWORD(-31521,  26722, -17855, -31521 ),   /*        w31 w29 w27 w25 */
  198. /* Table for rows 2,6 - constants are multiplied by cos_2_16 */
  199. SHORT4_TO_QWORD( 21407,  21407,  21407, -21407 ),   /* movq-> w06 w04 w02 w00 */
  200. SHORT4_TO_QWORD( 27969,  11585,  11585, -27969 ),   /*        w07 w05 w03 w01 */
  201. SHORT4_TO_QWORD( 21407, -21407,  21407,  21407 ),   /*        w14 w12 w10 w08 */
  202. SHORT4_TO_QWORD(-11585,  27969, -27969, -11585 ),   /*        w15 w13 w11 w09 */
  203. SHORT4_TO_QWORD( 29692,  16819,  25172, -29692 ),   /*        w22 w20 w18 w16 */
  204. SHORT4_TO_QWORD( 25172,   5906,  -5906, -16819 ),   /*        w23 w21 w19 w17 */
  205. SHORT4_TO_QWORD( 16819,   5906,   5906,  25172 ),   /*        w30 w28 w26 w24 */
  206. SHORT4_TO_QWORD(-29692,  25172, -16819, -29692 ),   /*        w31 w29 w27 w25 */
  207. /* Table for rows 3,5 - constants are multiplied by cos_3_16 */
  208. SHORT4_TO_QWORD( 19266,  19266,  19266, -19266 ),   /* movq-> w06 w04 w02 w00 */
  209. SHORT4_TO_QWORD( 25172,  10426,  10426, -25172 ),   /*        w07 w05 w03 w01 */
  210. SHORT4_TO_QWORD( 19266, -19266,  19266,  19266 ),   /*        w14 w12 w10 w08 */
  211. SHORT4_TO_QWORD(-10426,  25172, -25172, -10426 ),   /*        w15 w13 w11 w09 */
  212. SHORT4_TO_QWORD( 26722,  15137,  22654, -26722 ),   /*        w22 w20 w18 w16 */
  213. SHORT4_TO_QWORD( 22654,   5315,  -5315, -15137 ),   /*        w23 w21 w19 w17 */
  214. SHORT4_TO_QWORD( 15137,   5315,   5315,  22654 ),   /*        w30 w28 w26 w24 */
  215. SHORT4_TO_QWORD(-26722,  22654, -15137, -26722 ),   /*        w31 w29 w27 w25 */
  216. /* Table for rows 0,4 - constants are multiplied by cos_4_16 */
  217.   SHORT4_TO_QWORD( 16384,  16384,  16384, -16384 ),   /* movq-> w06 w04 w02 w00 */
  218. SHORT4_TO_QWORD( 21407,   8867,   8867, -21407 ),   /*        w07 w05 w03 w01 */
  219. SHORT4_TO_QWORD( 16384, -16384,  16384,  16384 ),   /*        w14 w12 w10 w08 */
  220. SHORT4_TO_QWORD(-8867,  21407, -21407,  -8867  ),   /*        w15 w13 w11 w09 */
  221. SHORT4_TO_QWORD( 22725,  12873,  19266, -22725 ),   /*        w22 w20 w18 w16 */
  222. SHORT4_TO_QWORD( 19266,   4520,  -4520, -12873 ),   /*        w23 w21 w19 w17 */
  223. SHORT4_TO_QWORD( 12873,   4520,   4520,  19266 ),   /*        w30 w28 w26 w24 */
  224. SHORT4_TO_QWORD(-22725,  19266, -12873, -22725 ),   /*        w31 w29 w27 w25 */
  225. /* Table for rows 3,5 - constants are multiplied by cos_3_16 */
  226. SHORT4_TO_QWORD( 19266,  19266,  19266, -19266 ),   /* movq-> w06 w04 w02 w00 */
  227. SHORT4_TO_QWORD( 25172,  10426,  10426, -25172 ),   /*        w07 w05 w03 w01 */
  228. SHORT4_TO_QWORD( 19266, -19266,  19266,  19266 ),   /*        w14 w12 w10 w08 */
  229. SHORT4_TO_QWORD(-10426,  25172, -25172, -10426 ),   /*        w15 w13 w11 w09 */
  230. SHORT4_TO_QWORD( 26722,  15137,  22654, -26722 ),   /*        w22 w20 w18 w16 */
  231. SHORT4_TO_QWORD( 22654,   5315,  -5315, -15137 ),   /*        w23 w21 w19 w17 */
  232. SHORT4_TO_QWORD( 15137,   5315,   5315,  22654 ),   /*        w30 w28 w26 w24 */
  233. SHORT4_TO_QWORD(-26722,  22654, -15137, -26722 ),   /*        w31 w29 w27 w25 */
  234. /* Table for rows 2,6 - constants are multiplied by cos_2_16 */
  235. SHORT4_TO_QWORD( 21407,  21407,  21407, -21407 ),   /* movq-> w06 w04 w02 w00 */
  236. SHORT4_TO_QWORD( 27969,  11585,  11585, -27969 ),   /*        w07 w05 w03 w01 */
  237. SHORT4_TO_QWORD( 21407, -21407,  21407,  21407 ),   /*        w14 w12 w10 w08 */
  238. SHORT4_TO_QWORD(-11585,  27969, -27969, -11585 ),   /*        w15 w13 w11 w09 */
  239. SHORT4_TO_QWORD( 29692,  16819,  25172, -29692 ),   /*        w22 w20 w18 w16 */
  240. SHORT4_TO_QWORD( 25172,   5906,  -5906, -16819 ),   /*        w23 w21 w19 w17 */
  241. SHORT4_TO_QWORD( 16819,   5906,   5906,  25172 ),   /*        w30 w28 w26 w24 */
  242. SHORT4_TO_QWORD(-29692,  25172, -16819, -29692 ),   /*        w31 w29 w27 w25 */
  243. /* Table for rows 1,7 - constants are multiplied by cos_1_16 */
  244. SHORT4_TO_QWORD( 22725,  22725,  22725, -22725 ),   /* movq-> w06 w04 w02 w00 */
  245. SHORT4_TO_QWORD( 29692,  12299,  12299, -29692 ),   /*        w07 w05 w03 w01 */
  246. SHORT4_TO_QWORD( 22725, -22725,  22725,  22725 ),   /*        w14 w12 w10 w08 */
  247. SHORT4_TO_QWORD(-12299,  29692, -29692, -12299 ),   /*        w15 w13 w11 w09 */
  248. SHORT4_TO_QWORD( 31521,  17855,  26722, -31521 ),   /*        w22 w20 w18 w16 */
  249. SHORT4_TO_QWORD( 26722,   6270,  -6270, -17855 ),   /*        w23 w21 w19 w17 */
  250. SHORT4_TO_QWORD( 17855,   6270,   6270,  26722 ),   /*        w30 w28 w26 w24 */
  251. SHORT4_TO_QWORD(-31521,  26722, -17855, -31521 ),   /*        w31 w29 w27 w25 */
  252. };
  253. uint64_t tempMatrix[64/4];
  254. #define INP      eax
  255. #define ROUNDER  ebx
  256. #define TABLE    ecx
  257. #define OUTP     edx
  258. /* the function itself */
  259. void MMX_IDCT_NAME
  260.               (int16_t *block) {
  261. __asm {
  262. push eax
  263. push ebx 
  264. push ecx
  265. push edx 
  266. push edi
  267. mov INP, block
  268. lea OUTP,  [tempMatrix]
  269. lea TABLE, [tab_i_04]
  270. lea ROUNDER, [rounder]
  271. mov edi, -8;                 ; i=-8
  272. align 16
  273. rowloop:
  274. movq mm0, MPTR [INP]  ; 0 ; x3 x2 x1 x0
  275. movq mm1, MPTR [INP+8] ; 1 ; x7 x6 x5 x4
  276. movq mm2, mm0  ; 2 ; x3 x2 x1 x0
  277. movq mm3, MPTR [TABLE] ; 3 ; w06 w04 w02 w00
  278. punpcklwd mm0, mm1  ; x5 x1 x4 x0
  279. movq mm5, mm0  ; 5 ; x5 x1 x4 x0
  280. punpckldq mm0, mm0  ; x4 x0 x4 x0
  281. movq mm4, MPTR [TABLE+8]  ; 4 ; w07 w05 w03 w01
  282. punpckhwd mm2, mm1 ; 1 ; x7 x3 x6 x2
  283. pmaddwd mm3, mm0  ; x4*w06+x0*w04 x4*w02+x0*w00
  284. movq mm6, mm2  ; 6  ; x7 x3 x6 x2
  285. movq mm1, MPTR [TABLE+32]  ; 1  ; w22 w20 w18 w16
  286. punpckldq mm2, mm2  ; x6 x2 x6 x2
  287. pmaddwd mm4, mm2  ; x6*w07+x2*w05 x6*w03+x2*w01
  288. punpckhdq mm5, mm5  ; x5 x1 x5 x1
  289. pmaddwd mm0, MPTR [TABLE+16]  ; x4*w14+x0*w12 x4*w10+x0*w08
  290. punpckhdq mm6, mm6  ; x7 x3 x7 x3
  291. movq mm7, MPTR [TABLE+40]  ; 7  ; w23 w21 w19 w17
  292. pmaddwd mm1, mm5  ; x5*w22+x1*w20 x5*w18+x1*w16
  293. paddd mm3, MPTR [ROUNDER]  ; +rounder
  294. pmaddwd mm7, mm6  ; x7*w23+x3*w21 x7*w19+x3*w17
  295. pmaddwd mm2, MPTR [TABLE+24]  ; x6*w15+x2*w13 x6*w11+x2*w09
  296. paddd mm3, mm4  ; 4  ; a1=sum(even1) a0=sum(even0)
  297. pmaddwd mm5, MPTR [TABLE+48]  ; x5*w30+x1*w28 x5*w26+x1*w24
  298. movq mm4, mm3  ; 4  ; a1 a0
  299. pmaddwd mm6, MPTR [TABLE+56]  ; x7*w31+x3*w29 x7*w27+x3*w25
  300. paddd mm1, mm7  ; 7  ; b1=sum(odd1) b0=sum(odd0)
  301. paddd mm0, MPTR [ROUNDER] ; +rounder
  302. psubd mm3, mm1  ; a1-b1 a0-b0
  303. psrad mm3, SHIFT_INV_ROW  ; y6=a1-b1 y7=a0-b0
  304. paddd mm1, mm4  ; 4  ; a1+b1 a0+b0
  305. paddd mm0, mm2  ; 2  ; a3=sum(even3) a2=sum(even2)
  306. psrad mm1, SHIFT_INV_ROW  ; y1=a1+b1 y0=a0+b0
  307. paddd mm5, mm6  ; 6  ; b3=sum(odd3) b2=sum(odd2)
  308. movq mm4, mm0  ; 4  ; a3 a2
  309. paddd mm0, mm5  ; a3+b3 a2+b2
  310. psubd mm4, mm5  ; 5  ; a3-b3 a2-b2
  311. psrad mm0, SHIFT_INV_ROW  ; y3=a3+b3 y2=a2+b2
  312. psrad mm4, SHIFT_INV_ROW  ; y4=a3-b3 y5=a2-b2
  313. packssdw mm1, mm0  ; 0  ; y3 y2 y1 y0
  314. packssdw mm4, mm3  ; 3  ; y6 y7 y4 y5
  315. movq mm7, mm4  ; 7  ; y6 y7 y4 y5
  316. psrld mm4, 16  ; 0 y6 0 y4
  317. pslld mm7, 16  ; y7 0 y5 0
  318. movq MPTR [OUTP], mm1  ; 1  ; save y3 y2 y1 y0
  319.                              
  320. por mm7, mm4  ; 4  ; y7 y6 y5 y4
  321. movq MPTR [OUTP+8], mm7  ; 7  ; save y7 y6 y5 y4
  322. add INP,  16                    ; add 1 row to input pointer
  323. add ROUNDER, 8                  ; go to next rounding values
  324. add OUTP, 16                    ; add 1 row to output pointer
  325. add TABLE,64                    ; move to next section of table
  326. add edi, 1
  327. jne rowloop;
  328. /* column code starts here... */
  329. lea INP,   [tempMatrix] 
  330. mov OUTP,  block
  331. mov edi, -2;                 ; i=-2
  332. align 16
  333. colloop:
  334. // movq mm0, MPTR [tg_3_16]
  335. movq mm0, tg_3_16
  336. movq mm3, MPTR [INP+16*3]
  337. movq mm1, mm0 ; tg_3_16
  338. movq mm5, MPTR [INP+16*5]
  339. pmulhw mm0, mm3 ; x3*(tg_3_16-1)
  340. // movq mm4, MPTR [tg_1_16]
  341. movq mm4, tg_1_16
  342. pmulhw mm1, mm5 ; x5*(tg_3_16-1)
  343. movq mm7, MPTR [INP+16*7]
  344. movq mm2, mm4 ; tg_1_16
  345. movq mm6, MPTR [INP+16*1]
  346. pmulhw mm4, mm7 ; x7*tg_1_16
  347. paddsw mm0, mm3 ; x3*tg_3_16
  348. pmulhw mm2, mm6 ; x1*tg_1_16
  349. paddsw mm1, mm3 ; x3+x5*(tg_3_16-1)
  350. psubsw mm0, mm5 ; x3*tg_3_16-x5 = tm35
  351. // movq mm3, MPTR [ocos_4_16]
  352. movq mm3, ocos_4_16
  353. paddsw mm1, mm5 ; x3+x5*tg_3_16 = tp35
  354. paddsw mm4, mm6 ; x1+tg_1_16*x7 = tp17
  355. psubsw mm2, mm7 ; x1*tg_1_16-x7 = tm17
  356. movq mm5, mm4 ; tp17
  357. movq mm6, mm2 ; tm17
  358. paddsw mm5, mm1 ; tp17+tp35 = b0
  359. psubsw mm6, mm0 ; tm17-tm35 = b3
  360. psubsw mm4, mm1 ; tp17-tp35 = t1
  361. paddsw mm2, mm0 ; tm17+tm35 = t2
  362. // movq mm7, MPTR [tg_2_16]
  363. movq mm7, tg_2_16
  364. movq mm1, mm4 ; t1
  365. ; movq MPTR [SCRATCH+0], mm5 ; save b0
  366. movq MPTR [OUTP+3*16], mm5 ; save b0
  367. paddsw mm1, mm2 ; t1+t2
  368. ; movq MPTR [SCRATCH+8], mm6 ; save b3
  369. movq MPTR [OUTP+5*16], mm6 ; save b3
  370. psubsw mm4, mm2 ; t1-t2
  371. movq mm5, MPTR [INP+2*16]
  372. movq mm0, mm7 ; tg_2_16
  373. movq mm6, MPTR [INP+6*16]
  374. pmulhw mm0, mm5 ; x2*tg_2_16
  375. pmulhw mm7, mm6 ; x6*tg_2_16
  376. ; slot
  377. pmulhw mm1, mm3 ; ocos_4_16*(t1+t2) = b1/2
  378. ; slot
  379. movq mm2, MPTR [INP+0*16]
  380. pmulhw mm4, mm3 ; ocos_4_16*(t1-t2) = b2/2
  381. psubsw mm0, mm6 ; t2*tg_2_16-x6 = tm26
  382. movq mm3, mm2 ; x0
  383. movq mm6, MPTR [INP+4*16]
  384. paddsw mm7, mm5 ; x2+x6*tg_2_16 = tp26
  385. paddsw mm2, mm6 ; x0+x4 = tp04
  386. psubsw mm3, mm6 ; x0-x4 = tm04
  387. movq mm5, mm2 ; tp04
  388. movq mm6, mm3 ; tm04
  389. psubsw mm2, mm7 ; tp04-tp26 = a3
  390. paddsw mm3, mm0 ; tm04+tm26 = a1
  391. paddsw mm1, mm1 ; b1
  392. paddsw mm4, mm4 ; b2
  393. paddsw mm5, mm7 ; tp04+tp26 = a0
  394. psubsw mm6, mm0 ; tm04-tm26 = a2
  395. movq mm7, mm3 ; a1
  396. movq mm0, mm6 ; a2
  397. paddsw mm3, mm1 ; a1+b1
  398. paddsw mm6, mm4 ; a2+b2
  399. psraw mm3, SHIFT_INV_COL ; dst1
  400. psubsw mm7, mm1 ; a1-b1
  401. psraw mm6, SHIFT_INV_COL ; dst2
  402. psubsw mm0, mm4 ; a2-b2
  403. ; movq mm1, MPTR [SCRATCH+0] ; load b0
  404. movq mm1, MPTR [OUTP+3*16] ; load b0
  405. psraw mm7, SHIFT_INV_COL ; dst6
  406. movq mm4, mm5 ; a0
  407. psraw mm0, SHIFT_INV_COL ; dst5
  408. movq MPTR [OUTP+1*16], mm3
  409. paddsw mm5, mm1 ; a0+b0
  410. movq MPTR [OUTP+2*16], mm6
  411. psubsw mm4, mm1 ; a0-b0
  412. ; movq mm3, MPTR [SCRATCH+8] ; load b3
  413. movq mm3, MPTR [OUTP+5*16] ; load b3
  414. psraw mm5, SHIFT_INV_COL ; dst0
  415. movq mm6, mm2 ; a3
  416. psraw mm4, SHIFT_INV_COL ; dst7
  417. movq MPTR [OUTP+5*16], mm0
  418. paddsw mm2, mm3 ; a3+b3
  419. movq MPTR [OUTP+6*16], mm7
  420. psubsw mm6, mm3 ; a3-b3
  421. movq MPTR [OUTP+0*16], mm5
  422. psraw mm2, SHIFT_INV_COL ; dst3
  423. movq MPTR [OUTP+7*16], mm4
  424. psraw mm6, SHIFT_INV_COL ; dst4
  425. movq MPTR [OUTP+3*16], mm2
  426. movq MPTR [OUTP+4*16], mm6
  427. lea INP,   [tempMatrix] 
  428. mov OUTP,  block
  429. add INP,  8                    ; add 4 cols to input pointer
  430. add OUTP, 8                    ; add 4 cols to output pointer
  431. add edi, 1
  432. jne colloop
  433. pop edi
  434. pop edx 
  435. pop ecx
  436. pop ebx
  437. pop eax
  438. emms 
  439. }; /* __asm */
  440. };