KJpegIdct.c
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:24k
源码类别:

模拟服务器

开发平台:

C/C++

  1. //---------------------------------------------------------------------------
  2. // Sword3 Engine (c) 1999-2000 by Kingsoft
  3. //
  4. // File: KJpegIdct.cpp
  5. // Date: 2000.08.08
  6. // Code: Daniel Wang
  7. // Desc: Jpeg 解码 MMX 版本 8x8 AAN IDCT
  8. // From: Cloud Wu's JPEG Decoder
  9. //---------------------------------------------------------------------------
  10. #include <windows.h>
  11. #include "KJpegLib.h"
  12. /****************************************************************************
  13.   本函数摘取自 developer.intel.com
  14.   ; esi - input and output data pointer
  15.   ; the input data is tranposed and each 16 bit element in the 8x8 matrix 
  16.   ; is left aligned:
  17.   ; for example in 11...1110000 format
  18.   ; If the iDCT is of I macroblock then 0.5 needs to be added to the 
  19.   ; DC Component 
  20.   ; (element[0][0] of the matrix)
  21. ****************************************************************************/
  22. static __int64 x0005000200010001 = 0x0005000200010001;
  23. static __int64 x0040000000000000 = 0x40000000000000;
  24. static __int64 x5a825a825a825a82 = 0x5a825a825a825a82; // 23170
  25. static __int64 x539f539f539f539f = 0x539f539f539f539f; // 21407
  26. static __int64 x4546454645464546 = 0x4546454645464546; // 17734
  27. static __int64 x61f861f861f861f8 = 0x61f861f861f861f8; // 25080
  28. //---------------------------------------------------------------------------
  29. static __int64 scratch1 = 0;
  30. static __int64 scratch3 = 0;
  31. static __int64 scratch5 = 0;
  32. static __int64 scratch7 = 0;
  33. //---------------------------------------------------------------------------
  34. static WORD preSC[64] = {
  35. 16384, 22725, 21407, 19266,  16384, 12873, 8867,  4520,
  36. 22725, 31521, 29692, 26722,  22725, 17855, 12299, 6270,
  37. 21407, 29692, 27969, 25172,  21407, 16819, 11585, 5906,
  38. 19266, 26722, 25172, 22654,  19266, 15137, 10426, 5315,
  39. 16384, 22725, 21407, 19266,  16384, 12873, 8867,  4520,
  40. 12873, 17855, 16819, 15137,  25746, 20228, 13933, 7103,
  41. 17734, 24598, 23170, 20853,  17734, 13933, 9597,  4892,
  42. 18081, 25080, 23624, 21261,  18081, 14206, 9785,  4988
  43. };
  44. //---------------------------------------------------------------------------
  45. // 函数: jpeg_idct_mmx
  46. // 功能: MMX 版本 8x8 AAN IDCT
  47. // 参数: buf 解码后的缓存
  48. // 返回: void
  49. //---------------------------------------------------------------------------
  50. void jpeg_idct_mmx(short* buf)
  51. {
  52. __asm
  53. {
  54. lea ecx, [preSC];
  55. mov esi, buf ; source
  56. ;slot
  57. ; column 0: even part
  58. ; use V4, V12, V0, V8 to produce V22..V25
  59. movq mm0, dword ptr [ecx+8*12] ; maybe the first mul can be done together
  60. ; with the dequantization in iHuff module ?
  61. ;slot
  62. pmulhw mm0, dword ptr [esi+8*12] ; V12
  63. ;slot
  64. movq mm1, dword ptr [ecx+8*4]
  65. ;slot
  66. pmulhw mm1, dword ptr [esi+8*4] ; V4
  67. ;slot
  68. movq mm3, dword ptr [ecx+8*0]
  69. psraw mm0, 1 ; t64=t66
  70. pmulhw mm3, dword ptr [esi+8*0] ; V0
  71. ;slot
  72. movq mm5, dword ptr [ecx+8*8] ; duplicate V4
  73. movq mm2, mm1                           ; added 11/1/96
  74. pmulhw mm5, dword ptr [esi+8*8] ; V8
  75. psubsw mm1, mm0 ; V16
  76. pmulhw mm1, dword ptr x5a825a825a825a82 ; 23170 ->V18
  77. paddsw mm2, mm0                          ; V17
  78. movq mm0, mm2 ; duplicate V17
  79. psraw mm2, 1 ; t75=t82
  80. psraw mm0, 2   ; t72
  81. movq mm4, mm3 ; duplicate V0
  82. paddsw mm3, mm5 ; V19
  83. psubsw mm4, mm5 ; V20 ;mm5 free
  84. ;moved from the block below
  85. movq mm7, dword ptr [ecx+8*10]
  86. psraw mm3, 1 ; t74=t81
  87. movq mm6, mm3 ; duplicate t74=t81
  88. psraw mm4, 2 ; t77=t79
  89. psubsw mm1, mm0 ; V21 ; mm0 free
  90. paddsw mm3, mm2 ; V22
  91. movq mm5, mm1 ; duplicate V21
  92. paddsw mm1, mm4 ; V23
  93. movq dword ptr [esi+8*4], mm3 ; V22
  94. psubsw mm4, mm5 ; V24; mm5 free
  95. movq dword ptr [esi+8*12], mm1 ; V23
  96. psubsw mm6, mm2 ; V25; mm2 free
  97. movq dword ptr [esi+8*0], mm4 ; V24
  98. ;slot
  99. ; keep mm6 alive all along the next block
  100. ;movq dword ptr [esi+8*8], mm6 ; V25
  101. ; column 0: odd part
  102. ; use V2, V6, V10, V14 to produce V31, V39, V40, V41
  103. ;moved above
  104. ;movq mm7, dword ptr [ecx+8*10]
  105. pmulhw mm7, dword ptr [esi+8*10] ; V10
  106. ;slot
  107. movq mm0, dword ptr [ecx+8*6]
  108. ;slot
  109. pmulhw mm0, dword ptr [esi+8*6] ; V6
  110. ;slot
  111. movq mm5, dword ptr [ecx+8*2]
  112. movq mm3, mm7 ; duplicate V10
  113. pmulhw mm5, dword ptr [esi+8*2] ; V2
  114. ;slot
  115. movq mm4, dword ptr [ecx+8*14]
  116. psubsw mm7, mm0 ; V26
  117. pmulhw mm4, dword ptr [esi+8*14] ; V14
  118. paddsw mm3, mm0 ; V29 ; free mm0
  119. movq mm1, mm7 ; duplicate V26
  120. psraw mm3, 1 ; t91=t94
  121. pmulhw mm7, dword ptr x539f539f539f539f  ; V33
  122. psraw mm1, 1 ; t96
  123. movq mm0, mm5 ; duplicate V2
  124. psraw mm4, 2 ; t85=t87
  125. paddsw mm5, mm4 ; V27
  126. psubsw mm0, mm4 ; V28 ; free mm4
  127. movq mm2, mm0 ; duplicate V28
  128. psraw mm5, 1 ; t90=t93
  129. pmulhw mm0, dword ptr x4546454645464546  ; V35
  130. psraw mm2, 1 ; t97
  131. movq mm4, mm5 ; duplicate t90=t93
  132. psubsw mm1, mm2 ; V32 ; free mm2
  133. pmulhw mm1, dword ptr x61f861f861f861f8  ; V36
  134. psllw mm7, 1 ; t107
  135. paddsw mm5, mm3 ; V31
  136. psubsw mm4, mm3 ; V30 ; free mm3
  137. pmulhw mm4, dword ptr x5a825a825a825a82  ; V34
  138. nop ;slot
  139. psubsw mm0, mm1 ; V38
  140. psubsw mm1, mm7 ; V37 ; free mm7
  141. psllw mm1, 1 ; t114
  142. ;move from the next block
  143. movq mm3, mm6 ; duplicate V25
  144. ;move from the next block
  145. movq mm7, dword ptr [esi+8*4] ; V22
  146. psllw mm0, 1 ; t110
  147. psubsw mm0, mm5 ; V39 (mm5 still needed for next block)
  148. psllw mm4, 2 ; t112
  149. ;move from the next block
  150. movq mm2, dword ptr [esi+8*12] ; V23
  151. psubsw mm4, mm0 ; V40
  152. paddsw mm1, mm4 ; V41; free mm0
  153. ;move from the next block
  154. psllw mm2, 1 ; t117=t125
  155. ; column 0: output butterfly
  156. ;move above
  157. ;movq mm3, mm6 ; duplicate V25
  158. ;movq mm7, dword ptr [esi+8*4] ; V22
  159. ;movq mm2, dword ptr [esi+8*12]     ; V23
  160. ;psllw mm2, 1 ; t117=t125
  161. psubsw mm6, mm1 ; tm6
  162. paddsw mm3, mm1 ; tm8; free mm1
  163. movq mm1, mm7 ; duplicate V22
  164. paddsw mm7, mm5 ; tm0
  165. movq dword ptr [esi+8*8], mm3      ; tm8; free mm3
  166. psubsw mm1, mm5 ; tm14; free mm5
  167. movq dword ptr [esi+8*6], mm6 ; tm6; free mm6
  168. movq mm3, mm2 ; duplicate t117=t125
  169. movq mm6, dword ptr [esi+8*0] ; V24
  170. paddsw mm2, mm0 ; tm2
  171. movq dword ptr [esi+8*0], mm7       ; tm0; free mm7
  172. psubsw mm3, mm0 ; tm12; free mm0
  173. movq dword ptr [esi+8*14], mm1 ; tm14; free mm1
  174. psllw mm6, 1 ; t119=t123
  175. movq dword ptr [esi+8*2], mm2 ; tm2; free mm2
  176. movq mm0, mm6 ; duplicate t119=t123
  177. movq dword ptr [esi+8*12], mm3       ; tm12; free mm3
  178. paddsw mm6, mm4 ; tm4
  179. ;moved from next block
  180. movq mm1, dword ptr [ecx+8*5]
  181. psubsw mm0, mm4 ; tm10; free mm4
  182. ;moved from next block
  183. pmulhw mm1, dword ptr [esi+8*5] ; V5
  184. ;slot
  185. movq dword ptr [esi+8*4], mm6 ; tm4; free mm6
  186. ;slot
  187. movq dword ptr [esi+8*10], mm0      ; tm10; free mm0
  188. ;slot
  189. ; column 1: even part
  190. ; use V5, V13, V1, V9 to produce V56..V59
  191. ;moved to prev block
  192. ;movq mm1, dword ptr [ecx+8*5]
  193. ;pmulhw mm1, dword ptr [esi+8*5] ; V5
  194. movq mm7, dword ptr [ecx+8*13]
  195. psllw mm1, 1 ; t128=t130
  196. pmulhw mm7, dword ptr [esi+8*13] ; V13
  197. movq mm2, mm1 ; duplicate t128=t130
  198. movq mm3, dword ptr [ecx+8*1]
  199. ;slot
  200. pmulhw mm3, dword ptr [esi+8*1] ; V1
  201. ;slot
  202. movq mm5, dword ptr [ecx+8*9]
  203. psubsw mm1, mm7 ; V50
  204. pmulhw mm5, dword ptr [esi+8*9] ; V9
  205. paddsw mm2, mm7 ; V51
  206. pmulhw mm1, dword ptr x5a825a825a825a82 ; 23170 ->V52
  207. movq mm6, mm2 ; duplicate V51
  208. psraw mm2, 1 ; t138=t144
  209. movq mm4, mm3 ; duplicate V1
  210. psraw mm6, 2   ; t136
  211. paddsw mm3, mm5 ; V53
  212. psubsw mm4, mm5 ; V54 ;mm5 free
  213. movq mm7, mm3 ; duplicate V53
  214. ;moved from next block
  215. movq mm0, dword ptr [ecx+8*11]
  216. psraw mm4, 1 ; t140=t142
  217. psubsw mm1, mm6 ; V55 ; mm6 free
  218. paddsw mm3, mm2 ; V56
  219. movq mm5, mm4 ; duplicate t140=t142
  220. paddsw mm4, mm1 ; V57
  221. movq dword ptr [esi+8*5], mm3 ; V56
  222. psubsw mm5, mm1 ; V58; mm1 free
  223. movq dword ptr [esi+8*13], mm4 ; V57
  224. psubsw mm7, mm2 ; V59; mm2 free
  225. movq dword ptr [esi+8*9], mm5 ; V58
  226. ;slot
  227. ; keep mm7 alive all along the next block
  228. ;movq dword ptr [esi+8*1], mm7 ; V59
  229. ;moved above
  230. ;movq mm0, dword ptr [ecx+8*11]
  231. pmulhw mm0, dword ptr [esi+8*11] ; V11
  232. ;slot
  233. movq mm6, dword ptr [ecx+8*7]
  234. ;slot
  235. pmulhw mm6, dword ptr [esi+8*7] ; V7
  236. ;slot
  237. movq mm4, dword ptr [ecx+8*15]
  238. movq mm3, mm0 ; duplicate V11
  239. pmulhw mm4, dword ptr [esi+8*15] ; V15
  240. ;slot
  241. movq mm5, dword ptr [ecx+8*3]
  242. psllw mm6,1 ; t146=t152
  243. pmulhw mm5, dword ptr [esi+8*3] ; V3
  244. paddsw mm0, mm6 ; V63
  245. ; note that V15 computation has a correction step:
  246. ; this is a 'magic' constant that rebiases the results to be closer to the expected result
  247. ; this magic constant can be refined to reduce the error even more
  248. ; by doing the correction step in a later stage when the number is actually multiplied by 16
  249. paddw mm4, dword ptr x0005000200010001;
  250. psubsw mm3, mm6 ; V60 ; free mm6
  251. psraw mm0, 1 ; t154=t156
  252. movq mm1, mm3 ; duplicate V60
  253. pmulhw mm1, dword ptr x539f539f539f539f  ; V67
  254. movq mm6, mm5 ; duplicate V3
  255. psraw mm4, 2 ; t148=t150
  256. ;slot
  257. paddsw mm5, mm4 ; V61
  258. psubsw mm6, mm4 ; V62 ; free mm4
  259. movq mm4, mm5 ; duplicate V61
  260. psllw mm1, 1 ; t169
  261. paddsw mm5, mm0 ; V65 -> result
  262. psubsw mm4, mm0 ; V64 ; free mm0
  263. pmulhw mm4, dword ptr x5a825a825a825a82  ; V68
  264. psraw mm3, 1 ; t158
  265. psubsw mm3, mm6 ; V66
  266. movq mm2, mm5 ; duplicate V65
  267. pmulhw mm3, dword ptr x61f861f861f861f8  ; V70
  268. psllw mm6, 1 ; t165
  269. pmulhw mm6, dword ptr x4546454645464546  ; V69
  270. psraw mm2, 1 ; t172
  271. ;moved from next block
  272. movq mm0, dword ptr [esi+8*5] ; V56
  273. psllw mm4, 1 ; t174
  274. ;moved from next block
  275. psraw mm0, 1 ; t177=t188
  276. nop ; slot
  277. psubsw mm6, mm3 ; V72
  278. psubsw mm3, mm1 ; V71 ; free mm1
  279. psubsw mm6, mm2 ; V73 ; free mm2
  280. ;moved from next block
  281. psraw mm5, 1 ; t178=t189
  282. psubsw mm4, mm6 ; V74
  283. ;moved from next block
  284. movq mm1, mm0 ; duplicate t177=t188
  285. paddsw mm3, mm4 ; V75
  286. ;moved from next block
  287. paddsw mm0, mm5 ; tm1
  288. ;location 
  289. ;  5 - V56
  290. ; 13 - V57
  291. ;  9 - V58
  292. ;  X - V59, mm7
  293. ;  X - V65, mm5
  294. ;  X - V73, mm6
  295. ;  X - V74, mm4
  296. ;  X - V75, mm3
  297. ; free mm0, mm1 & mm2
  298. ;move above
  299. ;movq mm0, dword ptr [esi+8*5] ; V56
  300. ;psllw mm0, 1 ; t177=t188 ! new !!
  301. ;psllw mm5, 1 ; t178=t189 ! new !!
  302. ;movq mm1, mm0 ; duplicate t177=t188
  303. ;paddsw mm0, mm5 ; tm1
  304. movq mm2, dword ptr [esi+8*13]      ; V57
  305. psubsw mm1, mm5 ; tm15; free mm5
  306. movq dword ptr [esi+8*1], mm0       ; tm1; free mm0
  307. psraw mm7, 1 ; t182=t184 ! new !!
  308. ;save the store as used directly in the transpose
  309. ;movq dword ptr [esi+8*15], mm1 ; tm15; free mm1
  310. movq mm5, mm7                    ; duplicate t182=t184
  311. psubsw mm7, mm3 ; tm7
  312. paddsw mm5, mm3 ; tm9; free mm3
  313. ;slot
  314. movq mm0, dword ptr [esi+8*9] ; V58
  315. movq mm3, mm2 ; duplicate V57
  316. movq dword ptr [esi+8*7], mm7 ; tm7; free mm7
  317. psubsw mm3, mm6 ; tm13
  318. paddsw mm2, mm6 ; tm3 ; free mm6
  319. ; moved up from the transpose 
  320. movq mm7, mm3                  
  321. ; moved up from the transpose 
  322. punpcklwd mm3, mm1
  323. movq mm6, mm0 ; duplicate V58
  324. movq dword ptr [esi+8*3], mm2 ; tm3; free mm2
  325. paddsw mm0, mm4 ; tm5
  326. psubsw mm6, mm4 ; tm11; free mm4
  327. ; moved up from the transpose 
  328. punpckhwd mm7, mm1
  329. movq dword ptr [esi+8*5], mm0 ; tm5; free mm0
  330. ; moved up from the transpose 
  331. movq mm2, mm5 
  332. ; transpose - M4 part
  333. ;  ---------       ---------
  334. ; | M1 | M2 |     | M1'| M3'|
  335. ;  ---------  -->  ---------
  336. ; | M3 | M4 |     | M2'| M4'|
  337. ;  ---------       ---------
  338. ; Two alternatives: use full dword approach so the following code can be 
  339. ; scheduled before the transpose is done without stores, or use the faster
  340. ; half dword stores (when possible)
  341. movd dword ptr [esi+8*9+4], mm3  ; MS part of tmt9
  342. punpcklwd mm5, mm6
  343. movd dword ptr [esi+8*13+4], mm7 ; MS part of tmt13 
  344. punpckhwd mm2, mm6
  345. movd dword ptr [esi+8*9], mm5 ; LS part of tmt9 
  346. punpckhdq mm5, mm3 ; free mm3
  347. movd dword ptr [esi+8*13], mm2 ; LS part of tmt13
  348. punpckhdq mm2, mm7 ; free mm7
  349. ; moved up from the M3 transpose 
  350. movq mm0, dword ptr [esi+8*8] 
  351. ;slot
  352. ; moved up from the M3 transpose 
  353. movq mm1, dword ptr [esi+8*10] 
  354. ; moved up from the M3 transpose 
  355. movq mm3, mm0 
  356. ; shuffle the rest of the data, and write it with 2 dword writes
  357. movq dword ptr [esi+8*11], mm5  ; tmt11
  358. ; moved up from the M3 transpose 
  359. punpcklwd mm0, mm1
  360. movq dword ptr [esi+8*15], mm2 ; tmt15
  361. ; moved up from the M3 transpose 
  362. punpckhwd mm3, mm1
  363. ; transpose - M3 part
  364. ; moved up to previous code section
  365. ;movq mm0, dword ptr [esi+8*8] 
  366. ;movq mm1, dword ptr [esi+8*10] 
  367. ;movq mm3, mm0 
  368. ;punpcklwd mm0, mm1
  369. ;punpckhwd mm3, mm1
  370. movq mm6, dword ptr [esi+8*12] 
  371. ;slot
  372. movq mm4, dword ptr [esi+8*14] 
  373. movq mm2, mm6 
  374. ; shuffle the data and write out the lower parts of the transposed in 4 dwords
  375. punpcklwd mm6, mm4
  376. movq mm1, mm0
  377. punpckhdq mm1, mm6
  378. movq mm7, mm3
  379. punpckhwd mm2, mm4 ; free mm4
  380. ;slot
  381. punpckldq mm0, mm6 ; free mm6
  382. ;slot
  383. ;moved from next block
  384. movq mm4, dword ptr [esi+8*13] ; tmt13
  385. punpckldq mm3, mm2
  386. punpckhdq mm7, mm2 ; free mm2
  387. ;moved from next block
  388. movq mm5, mm3 ; duplicate tmt5
  389. ; column 1: even part (after transpose)
  390. ;moved above
  391. ;movq mm5, mm3 ; duplicate tmt5
  392. ;movq mm4, dword ptr [esi+8*13] ; tmt13
  393. psubsw mm3, mm4 ; V134
  394. ;slot
  395. pmulhw mm3, dword ptr x5a825a825a825a82 ; 23170 ->V136
  396. ;slot
  397. movq mm6, dword ptr [esi+8*9]   ; tmt9
  398. paddsw mm5, mm4 ; V135 ; mm4 free
  399. movq mm4, mm0 ; duplicate tmt1
  400. paddsw mm0, mm6 ; V137
  401. psubsw mm4, mm6 ; V138 ; mm6 free
  402. psllw mm3, 2 ; t290
  403. psubsw mm3, mm5 ; V139
  404. movq mm6, mm0 ; duplicate V137
  405. paddsw mm0, mm5 ; V140
  406. movq mm2, mm4 ; duplicate V138
  407. paddsw mm2, mm3 ; V141
  408. psubsw mm4, mm3 ; V142 ; mm3 free
  409. movq dword ptr [esi+8*9], mm0  ; V140
  410. psubsw mm6, mm5 ; V143 ; mm5 free
  411. ;moved from next block
  412. movq mm0, dword ptr[esi+8*11] ; tmt11
  413. ;slot
  414. movq dword ptr [esi+8*13], mm2  ; V141
  415. ;moved from next block
  416. movq mm2, mm0 ; duplicate tmt11
  417. ; column 1: odd part (after transpose)
  418. ;moved up to the prev block
  419. ;movq mm0, dword ptr[esi+8*11] ; tmt11
  420. ;movq mm2, mm0 ; duplicate tmt11
  421. movq mm5, dword ptr[esi+8*15] ; tmt15
  422. psubsw mm0, mm7 ; V144
  423. movq mm3, mm0 ; duplicate V144
  424. paddsw mm2, mm7 ; V147 ; free mm7
  425. pmulhw mm0, dword ptr x539f539f539f539f ; 21407-> V151
  426. movq mm7, mm1 ; duplicate tmt3
  427. paddsw mm7, mm5 ; V145
  428. psubsw mm1, mm5 ; V146 ; free mm5
  429. psubsw mm3, mm1 ; V150
  430. movq mm5, mm7 ; duplicate V145
  431. pmulhw mm1, dword ptr x4546454645464546 ; 17734-> V153
  432. psubsw mm5, mm2 ; V148
  433. pmulhw mm3, dword ptr x61f861f861f861f8 ; 25080-> V154
  434. psllw mm0, 2 ; t311
  435. pmulhw mm5, dword ptr x5a825a825a825a82 ; 23170-> V152
  436. paddsw mm7, mm2 ; V149 ; free mm2
  437. psllw mm1, 1 ; t313
  438. nop ; slot
  439. ;without the nop above - freeze here for one clock
  440. ;the nop cleans the mess a little bit
  441. movq mm2, mm3 ; duplicate V154
  442. psubsw mm3, mm0 ; V155 ; free mm0
  443. psubsw mm1, mm2 ; V156 ; free mm2
  444. ;moved from the next block
  445. movq mm2, mm6 ; duplicate V143
  446. ;moved from the next block
  447. movq mm0, dword ptr[esi+8*13] ; V141
  448. psllw mm1, 1 ; t315
  449. psubsw mm1, mm7 ; V157 (keep V149)
  450. psllw mm5, 2 ; t317
  451. psubsw mm5, mm1 ; V158
  452. psllw mm3, 1 ; t319
  453. paddsw mm3, mm5 ; V159
  454. ;slot
  455. ; column 1: output butterfly (after transform)
  456. ;moved to the prev block
  457. ;movq mm2, mm6 ; duplicate V143
  458. ;movq mm0, dword ptr[esi+8*13] ; V141
  459. psubsw mm2, mm3 ; V163
  460. paddsw mm6, mm3 ; V164 ; free mm3
  461. movq mm3, mm4 ; duplicate V142
  462. psubsw mm4, mm5 ; V165 ; free mm5
  463. movq dword ptr scratch7, mm2 ; out7
  464. psraw mm6, 4
  465. psraw mm4, 4
  466. paddsw mm3, mm5 ; V162
  467. movq mm2, dword ptr[esi+8*9] ; V140
  468. movq mm5, mm0 ; duplicate V141
  469. ;in order not to perculate this line up, we read [esi+8*9] very near to this location
  470. // (9)
  471. movq dword ptr [esi+8*9], mm6 ; out9
  472. paddsw mm0, mm1 ; V161
  473. movq dword ptr scratch5, mm3 ; out5
  474. psubsw mm5, mm1 ; V166 ; free mm1
  475. // (11)
  476. movq dword ptr[esi+8*11], mm4 ; out11
  477. psraw mm5, 4
  478. movq dword ptr scratch3, mm0 ; out3
  479. movq mm4, mm2 ; duplicate V140
  480. // (13)
  481. movq dword ptr[esi+8*13], mm5 ; out13
  482. paddsw mm2, mm7 ; V160
  483. ;moved from the next block
  484. movq mm0, dword ptr [esi+8*1] 
  485. psubsw mm4, mm7 ; V167 ; free mm7
  486. ;moved from the next block
  487. movq mm7, dword ptr [esi+8*3] 
  488. psraw mm4, 4
  489. movq dword ptr scratch1, mm2 ; out1
  490. ;moved from the next block
  491. movq mm1, mm0 
  492. // (15)
  493. movq dword ptr[esi+8*15], mm4 ; out15
  494. ;moved from the next block
  495. punpcklwd mm0, mm7
  496. ; transpose - M2 parts
  497. ;moved up to the prev block
  498. ;movq mm0, dword ptr [esi+8*1] 
  499. ;movq mm7, dword ptr [esi+8*3] 
  500. ;movq mm1, mm0 
  501. ;punpcklwd mm0, mm7
  502. movq mm5, dword ptr [esi+8*5] 
  503. punpckhwd mm1, mm7
  504. movq mm4, dword ptr [esi+8*7] 
  505. movq mm3, mm5 
  506. ; shuffle the data and write out the lower parts of the trasposed in 4 dwords
  507. movd dword ptr [esi+8*8], mm0  ; LS part of tmt8
  508. punpcklwd mm5, mm4
  509. movd dword ptr [esi+8*12], mm1  ; LS part of tmt12
  510. punpckhwd mm3, mm4
  511. movd dword ptr [esi+8*8+4], mm5  ; MS part of tmt8
  512. punpckhdq mm0, mm5 ; tmt10
  513. movd dword ptr [esi+8*12+4], mm3  ; MS part of tmt12
  514. punpckhdq mm1, mm3 ; tmt14
  515. ; transpose - M1 parts
  516. movq mm7, dword ptr [esi] 
  517. ;slot
  518. movq mm2, dword ptr [esi+8*2] 
  519. movq mm6, mm7 
  520. movq mm5, dword ptr [esi+8*4] 
  521. punpcklwd mm7, mm2
  522. movq mm4, dword ptr [esi+8*6] 
  523. punpckhwd mm6, mm2 ; free mm2
  524. movq mm3, mm5 
  525. punpcklwd mm5, mm4
  526. punpckhwd mm3, mm4 ; free mm4
  527. movq mm2, mm7
  528. movq mm4, mm6
  529. punpckldq mm7, mm5 ; tmt0
  530. punpckhdq mm2, mm5 ; tmt2 ; free mm5
  531. ;slot
  532. ; shuffle the rest of the data, and write it with 2 dword writes
  533. punpckldq mm6, mm3 ; tmt4
  534. ;move from next block
  535. movq mm5, mm2 ; duplicate tmt2
  536. punpckhdq mm4, mm3 ; tmt6 ; free mm3
  537. ;move from next block
  538. movq mm3, mm0 ; duplicate tmt10
  539. ; column 0: odd part (after transpose)
  540. ;moved up to prev block
  541. ;movq mm3, mm0 ; duplicate tmt10
  542. ;movq mm5, mm2 ; duplicate tmt2
  543. psubsw mm0, mm4 ; V110
  544. paddsw mm3, mm4 ; V113 ; free mm4
  545. movq mm4, mm0 ; duplicate V110
  546. paddsw mm2, mm1 ; V111
  547. pmulhw mm0, dword ptr x539f539f539f539f ; 21407-> V117
  548. psubsw mm5, mm1 ; V112 ; free mm1
  549. psubsw mm4, mm5 ; V116
  550. movq mm1, mm2 ; duplicate V111
  551. pmulhw mm5, dword ptr x4546454645464546 ; 17734-> V119
  552. psubsw mm2, mm3 ; V114
  553. pmulhw mm4, dword ptr x61f861f861f861f8 ; 25080-> V120
  554. paddsw mm1, mm3 ; V115 ; free mm3
  555. pmulhw mm2, dword ptr x5a825a825a825a82 ; 23170-> V118
  556. psllw mm0, 2 ; t266
  557. movq dword ptr[esi+8*0], mm1 ; save V115
  558. psllw mm5, 1 ; t268
  559. psubsw mm5, mm4 ; V122
  560. psubsw mm4, mm0 ; V121 ; free mm0
  561. psllw mm5, 1 ; t270
  562. ;slot
  563. psubsw mm5, mm1 ; V123 ; free mm1
  564. psllw mm2, 2 ; t272
  565. psubsw mm2, mm5 ; V124 (keep V123)
  566. psllw mm4, 1 ; t274
  567. movq dword ptr[esi+8*2], mm5 ; save V123 ; free mm5
  568. paddsw mm4, mm2 ; V125 (keep V124)
  569. ; column 0: even part (after transpose)
  570. movq mm0, dword ptr[esi+8*12] ; tmt12
  571. movq mm3, mm6 ; duplicate tmt4
  572. psubsw mm6, mm0 ; V100
  573. paddsw mm3, mm0 ; V101 ; free mm0
  574. pmulhw mm6, dword ptr x5a825a825a825a82  ; 23170 ->V102
  575. movq mm5, mm7 ; duplicate tmt0
  576. movq mm1, dword ptr[esi+8*8] ; tmt8
  577. ;slot
  578. paddsw mm7, mm1 ; V103
  579. psubsw mm5, mm1 ; V104 ; free mm1
  580. movq mm0, mm7 ; duplicate V103
  581. psllw mm6, 2 ; t245
  582. paddsw mm7, mm3 ; V106
  583. movq mm1, mm5 ; duplicate V104
  584. psubsw mm6, mm3 ; V105
  585. psubsw mm0, mm3 ; V109; free mm3   
  586. paddsw mm5, mm6 ; V107
  587. psubsw mm1, mm6 ; V108 ; free mm6
  588. ; column 0: output butterfly (after transform)
  589. movq mm3, mm1 ; duplicate V108
  590. paddsw mm1, mm2 ; out4
  591. psraw mm1, 4
  592. psubsw mm3, mm2 ; out10 ; free mm2
  593. psraw mm3, 4
  594. movq mm6, mm0 ; duplicate V109
  595. // (4)
  596. movq dword ptr[esi+8*4], mm1 ; out4 ; free mm1
  597. psubsw mm0, mm4 ; out6
  598. // (10)
  599. movq dword ptr[esi+8*10], mm3 ; out10 ; free mm3
  600. psraw mm0, 4
  601. paddsw mm6, mm4 ; out8 ; free mm4
  602. movq mm1, mm7 ; duplicate V106
  603. // (6)
  604. movq dword ptr[esi+8*6], mm0 ; out6 ; free mm0
  605. psraw mm6, 4
  606. movq mm4, dword ptr[esi+8*0]  ; V115
  607. ;slot
  608. // (8)
  609. movq dword ptr[esi+8*8], mm6 ; out8 ; free mm6
  610. movq mm2, mm5 ; duplicate V107
  611. movq mm3, dword ptr[esi+8*2]  ; V123
  612. paddsw mm7, mm4 ; out0
  613. ;moved up from next block
  614. movq mm0, dword ptr scratch3
  615. psraw mm7, 4
  616. ;moved up from next block
  617. movq mm6, dword ptr scratch5
  618. psubsw mm1, mm4 ; out14 ; free mm4
  619. paddsw mm5, mm3 ; out2
  620. psraw mm1, 4
  621. // (0)
  622. // movq dword ptr[esi], mm7 ; out0 ; free mm7
  623. psraw mm5, 4
  624. // (14)
  625. movq dword ptr[esi+8*14], mm1 ; out14 ; free mm1
  626. psubsw mm2, mm3 ; out12 ; free mm3
  627. // (2)
  628. // movq dword ptr[esi+8*2], mm5 ; out2 ; free mm5
  629. psraw mm2, 4
  630. ;moved up to the prev block
  631. movq mm4, dword ptr scratch7
  632. ;moved up to the prev block
  633. psraw mm0, 4
  634. // (12)
  635. //movq dword ptr[esi+8*12], mm2 ; out12 ; free mm2
  636. ;moved up to the prev block
  637. movq mm1, dword ptr scratch1
  638. psraw mm6, 4
  639. packsswb mm7,mm7 
  640. psraw mm1, 4
  641. movd [esi],mm7; //out0
  642. psraw mm4, 4
  643. packsswb mm1,mm1;
  644. // (3)
  645. //movq dword ptr [esi+8*3], mm0 ; out3
  646. // (5)
  647. //movq dword ptr [esi+8*5], mm6 ; out5
  648. // (7)
  649. //movq dword ptr [esi+8*7], mm4 ; out7
  650. // (1)
  651. //movq dword ptr [esi+8*1], mm1 ; out1
  652. // 将 16bit 变成 8bit
  653. // mm1=1,mm4=7,mm6=5,mm0=3,mm2=12,mm5=2,mm7=0
  654. packsswb mm7,[esi+8*4]; //mm7=4
  655. packsswb mm6,mm6;
  656. packsswb mm5,mm5;
  657. punpckhdq mm7,mm6;
  658. movd [esi+4*1],mm1; //out1   free mm1
  659. movd [esi+4*2],mm5; //out2   free mm5
  660. packsswb mm0,mm0;
  661. packsswb mm1,[esi+8*6]; //mm1=6
  662. packsswb mm4,mm4;
  663. movd [esi+4*3],mm0; //out3   free mm0
  664. punpckhdq mm1,mm4;
  665. packsswb mm3,[esi+8*8]; //mm3=8
  666. movq [esi+4*4],mm7; //out4,5 free mm6,mm7
  667. packsswb mm0,[esi+8*9]; //mm0=9
  668. packsswb mm6,[esi+8*10];//mm6=10
  669. movq [esi+4*6],mm1;     //out6,7 free mm1,mm4
  670. packsswb mm1,[esi+8*11];//mm1=11
  671. punpckhdq mm3,mm0;
  672. punpckhdq mm6,mm1;
  673. packsswb mm2,mm2;
  674. packsswb mm4,[esi+8*13];//mm4=13
  675. movq [esi+4*8],mm3;     //out8,9 free mm0,mm3
  676. punpckhdq mm2,mm4;
  677. packsswb mm0,[esi+8*14];//mm3=14
  678. packsswb mm5,[esi+8*15];//mm5=15
  679. movq [esi+4*10],mm6; //out10,11  free mm1,mm6
  680. punpckhdq mm0,mm5;
  681. movq [esi+4*12],mm2; //out12,13  free mm3,mm4
  682. movq [esi+4*14],mm0;
  683. emms;
  684. }
  685. }
  686. //---------------------------------------------------------------------------