[svn] / trunk / xvidcore / src / dct / x86_asm / fdct_sse2_skal.asm Repository:
ViewVC logotype

Annotation of /trunk/xvidcore/src/dct/x86_asm/fdct_sse2_skal.asm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1382 - (view) (download)

1 : edgomez 1382 ;/****************************************************************************
2 :     ; *
3 :     ; * XVID MPEG-4 VIDEO CODEC
4 :     ; * - SSE2 forward discrete cosine transform -
5 :     ; *
6 :     ; * Copyright(C) 2003 Pascal Massimino <skal@planet-d.net>
7 :     ; *
8 :     ; * This program is free software; you can redistribute it and/or modify it
9 :     ; * under the terms of the GNU General Public License as published by
10 :     ; * the Free Software Foundation; either version 2 of the License, or
11 :     ; * (at your option) any later version.
12 :     ; *
13 :     ; * This program is distributed in the hope that it will be useful,
14 :     ; * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 :     ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 :     ; * GNU General Public License for more details.
17 :     ; *
18 :     ; * You should have received a copy of the GNU General Public License
19 :     ; * along with this program; if not, write to the Free Software
20 :     ; * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 :     ; *
22 :     ; * $Id: fdct_sse2_skal.asm,v 1.2 2004-03-22 22:36:23 edgomez Exp $
23 :     ; *
24 :     ; ***************************************************************************/
25 :    
26 :     BITS 32
27 :    
28 :     %macro cglobal 1
29 :     %ifdef PREFIX
30 :     global _%1
31 :     %define %1 _%1
32 :     %else
33 :     global %1
34 :     %endif
35 :     %endmacro
36 :    
37 :     ;-----------------------------------------------------------------------------
38 :     ;
39 :     ; -=FDCT=-
40 :     ;
41 :     ; Vertical pass is an implementation of the scheme:
42 :     ; Loeffler C., Ligtenberg A., and Moschytz C.S.:
43 :     ; Practical Fast 1D DCT Algorithm with Eleven Multiplications,
44 :     ; Proc. ICASSP 1989, 988-991.
45 :     ;
46 :     ; Horizontal pass is a double 4x4 vector/matrix multiplication,
47 :     ; (see also Intel's Application Note 922:
48 :     ; http://developer.intel.com/vtune/cbts/strmsimd/922down.htm
49 :     ; Copyright (C) 1999 Intel Corporation)
50 :     ;
51 :     ; Notes:
52 :     ; * tan(3pi/16) is greater than 0.5, and would use the
53 :     ; sign bit when turned into 16b fixed-point precision. So,
54 :     ; we use the trick: x*tan3 = x*(tan3-1)+x
55 :     ;
56 :     ; * There's only one SSE-specific instruction (pshufw).
57 :     ;
58 :     ; * There's still 1 or 2 ticks to save in fLLM_PASS, but
59 :     ; I prefer having a readable code, instead of a tightly
60 :     ; scheduled one...
61 :     ;
62 :     ; * Quantization stage (as well as pre-transposition for the
63 :     ; idct way back) can be included in the fTab* constants
64 :     ; (with induced loss of precision, somehow)
65 :     ;
66 :     ; * Some more details at: http://skal.planet-d.net/coding/dct.html
67 :     ;
68 :     ;
69 :     ;//////////////////////////////////////////////////////////////////////
70 :     ;
71 :     ; == Mean square errors ==
72 :     ; 0.000 0.001 0.001 0.002 0.000 0.002 0.001 0.000 [0.001]
73 :     ; 0.035 0.029 0.032 0.032 0.031 0.032 0.034 0.035 [0.032]
74 :     ; 0.026 0.028 0.027 0.027 0.025 0.028 0.028 0.025 [0.027]
75 :     ; 0.037 0.032 0.031 0.030 0.028 0.029 0.026 0.031 [0.030]
76 :     ; 0.000 0.001 0.001 0.002 0.000 0.002 0.001 0.001 [0.001]
77 :     ; 0.025 0.024 0.022 0.022 0.022 0.022 0.023 0.023 [0.023]
78 :     ; 0.026 0.028 0.025 0.028 0.030 0.025 0.026 0.027 [0.027]
79 :     ; 0.021 0.020 0.020 0.022 0.020 0.022 0.017 0.019 [0.020]
80 :     ;
81 :     ; == Abs Mean errors ==
82 :     ; 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 [0.000]
83 :     ; 0.020 0.001 0.003 0.003 0.000 0.004 0.002 0.003 [0.002]
84 :     ; 0.000 0.001 0.001 0.001 0.001 0.004 0.000 0.000 [0.000]
85 :     ; 0.027 0.001 0.000 0.002 0.002 0.002 0.001 0.000 [0.003]
86 :     ; 0.000 0.000 0.000 0.000 0.000 0.001 0.000 0.001 [-0.000]
87 :     ; 0.001 0.003 0.001 0.001 0.002 0.001 0.000 0.000 [-0.000]
88 :     ; 0.000 0.002 0.002 0.001 0.001 0.002 0.001 0.000 [-0.000]
89 :     ; 0.000 0.002 0.001 0.002 0.001 0.002 0.001 0.001 [-0.000]
90 :     ;
91 :     ; =========================
92 :     ; Peak error: 1.0000
93 :     ; Peak MSE: 0.0365
94 :     ; Overall MSE: 0.0201
95 :     ; Peak ME: 0.0265
96 :     ; Overall ME: 0.0006
97 :     ;
98 :     ;-----------------------------------------------------------------------------
99 :     ;
100 :     ; -=IDCT=-
101 :     ;
102 :     ; A little slower than fdct, because the final stages (butterflies and
103 :     ; descaling) require some unpairable shifting and packing, all on
104 :     ; the same CPU unit.
105 :     ;
106 :     ; THIS IDCT IS NOT IEEE-COMPLIANT: IT WILL FAIL THE [-300,300]
107 :     ; INPUT RANGE TEST (because of overflow). But the [-256,255] one
108 :     ; is OK, and I'm fine with it (for now;)
109 :     ;
110 :     ; == Mean square errors ==
111 :     ; 0.007 0.006 0.005 0.007 0.006 0.007 0.005 0.007 [0.006]
112 :     ; 0.006 0.008 0.007 0.007 0.007 0.008 0.008 0.008 [0.007]
113 :     ; 0.008 0.008 0.008 0.008 0.007 0.009 0.010 0.007 [0.008]
114 :     ; 0.007 0.007 0.006 0.007 0.008 0.007 0.006 0.008 [0.007]
115 :     ; 0.007 0.006 0.006 0.006 0.006 0.005 0.006 0.006 [0.006]
116 :     ; 0.008 0.007 0.006 0.008 0.007 0.008 0.009 0.009 [0.008]
117 :     ; 0.008 0.006 0.010 0.008 0.008 0.008 0.007 0.007 [0.008]
118 :     ; 0.007 0.006 0.006 0.007 0.007 0.006 0.006 0.007 [0.006]
119 :     ;
120 :     ; == Abs Mean errors ==
121 :     ; 0.001 0.000 0.000 0.001 0.001 0.000 0.000 0.000 [0.000]
122 :     ; 0.000 0.002 0.002 0.000 0.001 0.001 0.000 0.002 [0.000]
123 :     ; 0.001 0.002 0.001 0.001 0.001 0.001 0.000 0.001 [-0.001]
124 :     ; 0.000 0.002 0.000 0.000 0.001 0.000 0.000 0.001 [-0.000]
125 :     ; 0.000 0.001 0.001 0.001 0.000 0.001 0.000 0.001 [0.000]
126 :     ; 0.000 0.001 0.001 0.001 0.001 0.000 0.001 0.000 [0.000]
127 :     ; 0.001 0.001 0.002 0.001 0.001 0.002 0.001 0.001 [0.001]
128 :     ; 0.000 0.000 0.001 0.000 0.000 0.000 0.000 0.000 [0.000]
129 :     ;
130 :     ; =========================
131 :     ;
132 :     ; Peak error: 1.0000
133 :     ; Peak MSE: 0.0096
134 :     ; Overall MSE: 0.0070
135 :     ; Peak ME: 0.0024
136 :     ; Overall ME: 0.0001
137 :     ;
138 :     ;-----------------------------------------------------------------------------
139 :    
140 :     ;=============================================================================
141 :     ; Read only data
142 :     ;=============================================================================
143 :    
144 :     %ifdef FORMAT_COFF
145 :     SECTION .rodata data
146 :     %else
147 :     SECTION .rodata data align=16
148 :     %endif
149 :    
150 :     ALIGN 16
151 :     tan1: times 8 dw 0x32ec ; tan( pi/16)
152 :     tan2: times 8 dw 0x6a0a ; tan(2pi/16) (=sqrt(2)-1)
153 :     tan3: times 8 dw 0xab0e ; tan(3pi/16)-1
154 :     sqrt2: times 8 dw 0x5a82 ; 0.5/sqrt(2)
155 :    
156 :     ;-----------------------------------------------------------------------------
157 :     ; Inverse DCT tables
158 :     ;-----------------------------------------------------------------------------
159 :    
160 :     ALIGN 16
161 :     iTab1:
162 :     dw 0x4000, 0x539f, 0x4000, 0x22a3
163 :     dw 0x4000, 0xdd5d, 0x4000, 0xac61
164 :     dw 0x4000, 0x22a3, 0xc000, 0xac61
165 :     dw 0xc000, 0x539f, 0x4000, 0xdd5d
166 :     dw 0x58c5, 0x4b42, 0x4b42, 0xee58
167 :     dw 0x3249, 0xa73b, 0x11a8, 0xcdb7
168 :     dw 0x3249, 0x11a8, 0xa73b, 0xcdb7
169 :     dw 0x11a8, 0x4b42, 0x4b42, 0xa73b
170 :    
171 :     iTab2:
172 :     dw 0x58c5, 0x73fc, 0x58c5, 0x300b
173 :     dw 0x58c5, 0xcff5, 0x58c5, 0x8c04
174 :     dw 0x58c5, 0x300b, 0xa73b, 0x8c04
175 :     dw 0xa73b, 0x73fc, 0x58c5, 0xcff5
176 :     dw 0x7b21, 0x6862, 0x6862, 0xe782
177 :     dw 0x45bf, 0x84df, 0x187e, 0xba41
178 :     dw 0x45bf, 0x187e, 0x84df, 0xba41
179 :     dw 0x187e, 0x6862, 0x6862, 0x84df
180 :    
181 :     iTab3:
182 :     dw 0x539f, 0x6d41, 0x539f, 0x2d41
183 :     dw 0x539f, 0xd2bf, 0x539f, 0x92bf
184 :     dw 0x539f, 0x2d41, 0xac61, 0x92bf
185 :     dw 0xac61, 0x6d41, 0x539f, 0xd2bf
186 :     dw 0x73fc, 0x6254, 0x6254, 0xe8ee
187 :     dw 0x41b3, 0x8c04, 0x1712, 0xbe4d
188 :     dw 0x41b3, 0x1712, 0x8c04, 0xbe4d
189 :     dw 0x1712, 0x6254, 0x6254, 0x8c04
190 :    
191 :     iTab4:
192 :     dw 0x4b42, 0x6254, 0x4b42, 0x28ba
193 :     dw 0x4b42, 0xd746, 0x4b42, 0x9dac
194 :     dw 0x4b42, 0x28ba, 0xb4be, 0x9dac
195 :     dw 0xb4be, 0x6254, 0x4b42, 0xd746
196 :     dw 0x6862, 0x587e, 0x587e, 0xeb3d
197 :     dw 0x3b21, 0x979e, 0x14c3, 0xc4df
198 :     dw 0x3b21, 0x14c3, 0x979e, 0xc4df
199 :     dw 0x14c3, 0x587e, 0x587e, 0x979e
200 :    
201 :     ; the original rounding trick is by
202 :     ; Michel Lespinasse (hi Walken!) <walken@zoy.org>
203 :    
204 :     ALIGN 16
205 :     Idct_Rnd0: dd 65535, 65535, 65535, 65535
206 :     Idct_Rnd1: dd 3612, 3612, 3612, 3612
207 :     Idct_Rnd2: dd 2271, 2271, 2271, 2271
208 :     Idct_Rnd3: dd 1203, 1203, 1203, 1203
209 :     Idct_Rnd4: dd 1023, 1023, 1023, 1023
210 :     Idct_Rnd5: dd 102, 102, 102, 102
211 :     Idct_Rnd6: dd 398, 398, 398, 398
212 :     Idct_Rnd7: dd 469, 469, 469, 469
213 :    
214 :     Idct_Sparse_Rnd0: times 4 dw (65535>>11)
215 :     Idct_Sparse_Rnd1: times 4 dw ( 3612>>11)
216 :     Idct_Sparse_Rnd2: times 4 dw ( 2271>>11)
217 :     ; other rounders are zero...
218 :    
219 :     ;-----------------------------------------------------------------------------
220 :     ; Forward DCT tables
221 :     ;-----------------------------------------------------------------------------
222 :    
223 :     ALIGN 16
224 :     fTab1:
225 :     dw 0x4000, 0x4000, 0x58c5, 0x4b42,
226 :     dw 0xdd5d, 0xac61, 0xa73b, 0xcdb7,
227 :     dw 0x4000, 0x4000, 0x3249, 0x11a8,
228 :     dw 0x539f, 0x22a3, 0x4b42, 0xee58,
229 :     dw 0x4000, 0xc000, 0x3249, 0xa73b,
230 :     dw 0x539f, 0xdd5d, 0x4b42, 0xa73b,
231 :     dw 0xc000, 0x4000, 0x11a8, 0x4b42,
232 :     dw 0x22a3, 0xac61, 0x11a8, 0xcdb7
233 :    
234 :     fTab2:
235 :     dw 0x58c5, 0x58c5, 0x7b21, 0x6862,
236 :     dw 0xcff5, 0x8c04, 0x84df, 0xba41,
237 :     dw 0x58c5, 0x58c5, 0x45bf, 0x187e,
238 :     dw 0x73fc, 0x300b, 0x6862, 0xe782,
239 :     dw 0x58c5, 0xa73b, 0x45bf, 0x84df,
240 :     dw 0x73fc, 0xcff5, 0x6862, 0x84df,
241 :     dw 0xa73b, 0x58c5, 0x187e, 0x6862,
242 :     dw 0x300b, 0x8c04, 0x187e, 0xba41
243 :    
244 :     fTab3:
245 :     dw 0x539f, 0x539f, 0x73fc, 0x6254,
246 :     dw 0xd2bf, 0x92bf, 0x8c04, 0xbe4d,
247 :     dw 0x539f, 0x539f, 0x41b3, 0x1712,
248 :     dw 0x6d41, 0x2d41, 0x6254, 0xe8ee,
249 :     dw 0x539f, 0xac61, 0x41b3, 0x8c04,
250 :     dw 0x6d41, 0xd2bf, 0x6254, 0x8c04,
251 :     dw 0xac61, 0x539f, 0x1712, 0x6254,
252 :     dw 0x2d41, 0x92bf, 0x1712, 0xbe4d
253 :    
254 :     fTab4:
255 :     dw 0x4b42, 0x4b42, 0x6862, 0x587e,
256 :     dw 0xd746, 0x9dac, 0x979e, 0xc4df,
257 :     dw 0x4b42, 0x4b42, 0x3b21, 0x14c3,
258 :     dw 0x6254, 0x28ba, 0x587e, 0xeb3d,
259 :     dw 0x4b42, 0xb4be, 0x3b21, 0x979e,
260 :     dw 0x6254, 0xd746, 0x587e, 0x979e,
261 :     dw 0xb4be, 0x4b42, 0x14c3, 0x587e,
262 :     dw 0x28ba, 0x9dac, 0x14c3, 0xc4df
263 :    
264 :    
265 :     ALIGN 16
266 :     Fdct_Rnd0: dw 6,8,8,8, 6,8,8,8
267 :     Fdct_Rnd1: dw 8,8,8,8, 8,8,8,8
268 :     Fdct_Rnd2: dw 10,8,8,8, 8,8,8,8
269 :     Rounder1: dw 1,1,1,1, 1,1,1,1
270 :    
271 :     ;=============================================================================
272 :     ; Code
273 :     ;=============================================================================
274 :    
275 :     SECTION .text
276 :    
277 :     cglobal idct_sse2_skal
278 :     cglobal idct_sse2_sparse_skal
279 :     cglobal fdct_sse2_skal
280 :    
281 :     ;-----------------------------------------------------------------------------
282 :     ; Helper macro iMTX_MULT
283 :     ;-----------------------------------------------------------------------------
284 :    
285 :     %macro iMTX_MULT 4 ; %1=src, %2 = Table to use, %3=rounder, %4=Shift
286 :    
287 :     movdqa xmm0, [ecx+%1*16] ; xmm0 = [01234567]
288 :    
289 :     pshuflw xmm0, xmm0, 11011000b ; [0213]
290 :     pshufhw xmm0, xmm0, 11011000b ; [02134657]
291 :     pshufd xmm4, xmm0, 00000000b ; [02020202]
292 :     pshufd xmm5, xmm0, 10101010b ; [46464646]
293 :     pshufd xmm6, xmm0, 01010101b ; [13131313]
294 :     pshufd xmm7, xmm0, 11111111b ; [57575757]
295 :    
296 :     pmaddwd xmm4, [%2+ 0] ; dot [M00,M01][M04,M05][M08,M09][M12,M13]
297 :     pmaddwd xmm5, [%2+16] ; dot [M02,M03][M06,M07][M10,M11][M14,M15]
298 :     pmaddwd xmm6, [%2+32] ; dot [M16,M17][M20,M21][M24,M25][M28,M29]
299 :     pmaddwd xmm7, [%2+48] ; dot [M18,M19][M22,M23][M26,M27][M30,M31]
300 :     paddd xmm4, [%3] ; Round
301 :    
302 :     paddd xmm6, xmm7 ; [b0|b1|b2|b3]
303 :     paddd xmm4, xmm5 ; [a0|a1|a2|a3]
304 :    
305 :     movdqa xmm7, xmm6
306 :     paddd xmm6, xmm4 ; mm6=a+b
307 :     psubd xmm4, xmm7 ; mm4=a-b
308 :     psrad xmm6, %4 ; => out [0123]
309 :     psrad xmm4, %4 ; => out [7654]
310 :    
311 :     packssdw xmm6, xmm4 ; [01237654]
312 :     pshufhw xmm6, xmm6, 00011011b ; [01234567]
313 :    
314 :     movdqa [ecx+%1*16], xmm6
315 :    
316 :     %endmacro
317 :    
318 :     ;-----------------------------------------------------------------------------
319 :     ; Helper macro iLLM_PASS
320 :     ;-----------------------------------------------------------------------------
321 :    
322 :     %macro iLLM_PASS 1 ; %1: src/dst
323 :    
324 :     movdqa xmm0, [tan3] ; t3-1
325 :     movdqa xmm3, [%1+16*3] ; x3
326 :     movdqa xmm1, xmm0 ; t3-1
327 :     movdqa xmm5, [%1+16*5] ; x5
328 :    
329 :     movdqa xmm4, [tan1] ; t1
330 :     movdqa xmm6, [%1+16*1] ; x1
331 :     movdqa xmm7, [%1+16*7] ; x7
332 :     movdqa xmm2, xmm4 ; t1
333 :    
334 :     pmulhw xmm0, xmm3 ; x3*(t3-1)
335 :     pmulhw xmm1, xmm5 ; x5*(t3-1)
336 :     paddsw xmm0, xmm3 ; x3*t3
337 :     paddsw xmm1, xmm5 ; x5*t3
338 :     psubsw xmm0, xmm5 ; x3*t3-x5 = tm35
339 :     paddsw xmm1, xmm3 ; x3+x5*t3 = tp35
340 :    
341 :     pmulhw xmm4, xmm7 ; x7*t1
342 :     pmulhw xmm2, xmm6 ; x1*t1
343 :     paddsw xmm4, xmm6 ; x1+t1*x7 = tp17
344 :     psubsw xmm2, xmm7 ; x1*t1-x7 = tm17
345 :    
346 :    
347 :     movdqa xmm3, [sqrt2]
348 :     movdqa xmm7, xmm4
349 :     movdqa xmm6, xmm2
350 :     psubsw xmm4, xmm1 ; tp17-tp35 = t1
351 :     psubsw xmm2, xmm0 ; tm17-tm35 = b3
352 :     paddsw xmm1, xmm7 ; tp17+tp35 = b0
353 :     paddsw xmm0, xmm6 ; tm17+tm35 = t2
354 :    
355 :     ; xmm1 = b0, xmm2 = b3. preserved
356 :    
357 :     movdqa xmm6, xmm4
358 :     psubsw xmm4, xmm0 ; t1-t2
359 :     paddsw xmm0, xmm6 ; t1+t2
360 :    
361 :     pmulhw xmm4, xmm3 ; (t1-t2)/(2.sqrt2)
362 :     pmulhw xmm0, xmm3 ; (t1+t2)/(2.sqrt2)
363 :    
364 :     paddsw xmm0, xmm0 ; 2.(t1+t2) = b1
365 :     paddsw xmm4, xmm4 ; 2.(t1-t2) = b2
366 :    
367 :     movdqa xmm7, [tan2] ; t2
368 :     movdqa xmm3, [%1+2*16] ; x2
369 :     movdqa xmm6, [%1+6*16] ; x6
370 :     movdqa xmm5, xmm7 ; t2
371 :    
372 :     pmulhw xmm7, xmm6 ; x6*t2
373 :     pmulhw xmm5, xmm3 ; x2*t2
374 :    
375 :     paddsw xmm7, xmm3 ; x2+x6*t2 = tp26
376 :     psubsw xmm5, xmm6 ; x2*t2-x6 = tm26
377 :    
378 :    
379 :     ; use:xmm3,xmm5,xmm6,xmm7 frozen: xmm0,xmm4,xmm1,xmm2
380 :    
381 :     movdqa xmm3, [%1+0*16] ; x0
382 :     movdqa xmm6, [%1+4*16] ; x4
383 :    
384 :     psubsw xmm3, xmm6 ; x0-x4 = tm04
385 :     paddsw xmm6, xmm6 ; 2.x4
386 :     paddsw xmm6, xmm3 ; x0+x4 = tp04
387 :    
388 :     psubsw xmm3, xmm5 ; tm04-tm26 = a2
389 :     psubsw xmm6, xmm7 ; tp04-tp26 = a3
390 :     paddsw xmm5, xmm5 ; 2.tm26
391 :     paddsw xmm7, xmm7 ; 2.tp26
392 :     paddsw xmm5, xmm3 ; tm04+tm26 = a1
393 :     paddsw xmm7, xmm6 ; tp04+tp26 = a0
394 :    
395 :     psubsw xmm5, xmm0 ; a1-b1
396 :     psubsw xmm3, xmm4 ; a2-b2
397 :     paddsw xmm0, xmm0 ; 2.b1
398 :     paddsw xmm4, xmm4 ; 2.b2
399 :     paddsw xmm0, xmm5 ; a1+b1
400 :     paddsw xmm4, xmm3 ; a2+b2
401 :    
402 :     psraw xmm5, 6 ; out6
403 :     psraw xmm3, 6 ; out5
404 :     psraw xmm0, 6 ; out1
405 :     psraw xmm4, 6 ; out2
406 :    
407 :     movdqa [%1+6*16], xmm5
408 :     movdqa [%1+5*16], xmm3
409 :     movdqa [%1+1*16], xmm0
410 :     movdqa [%1+2*16], xmm4
411 :    
412 :     ; reminder: xmm1=b0, xmm2=b3, xmm7=a0, xmm6=a3
413 :    
414 :     movdqa xmm0, xmm7
415 :     movdqa xmm4, xmm6
416 :     psubsw xmm7, xmm1 ; a0-b0
417 :     psubsw xmm6, xmm2 ; a3-b3
418 :     paddsw xmm1, xmm0 ; a0+b0
419 :     paddsw xmm2, xmm4 ; a3+b3
420 :    
421 :     psraw xmm1, 6 ; out0
422 :     psraw xmm7, 6 ; out7
423 :     psraw xmm2, 6 ; out3
424 :     psraw xmm6, 6 ; out4
425 :    
426 :     movdqa [%1+0*16], xmm1
427 :     movdqa [%1+3*16], xmm2
428 :     movdqa [%1+4*16], xmm6
429 :     movdqa [%1+7*16], xmm7
430 :     %endmacro
431 :    
432 :     ;-----------------------------------------------------------------------------
433 :     ; Function idct (the straight forward version)
434 :     ;-----------------------------------------------------------------------------
435 :    
436 :     ALIGN 16
437 :     idct_sse2_skal:
438 :     mov ecx, [esp+4]
439 :     iMTX_MULT 0, iTab1, Idct_Rnd0, 11
440 :     iMTX_MULT 1, iTab2, Idct_Rnd1, 11
441 :     iMTX_MULT 2, iTab3, Idct_Rnd2, 11
442 :     iMTX_MULT 3, iTab4, Idct_Rnd3, 11
443 :     iMTX_MULT 4, iTab1, Idct_Rnd4, 11
444 :     iMTX_MULT 5, iTab4, Idct_Rnd5, 11
445 :     iMTX_MULT 6, iTab3, Idct_Rnd6, 11
446 :     iMTX_MULT 7, iTab2, Idct_Rnd7, 11
447 :     iLLM_PASS ecx+0
448 :     ret
449 :    
450 :     ;-----------------------------------------------------------------------------
451 :     ; Helper macro TEST_ROW (test a null row)
452 :     ;-----------------------------------------------------------------------------
453 :    
454 :     %macro TEST_ROW 2 ; %1:src, %2:label x8
455 :     mov eax, [%1 ]
456 :     mov edx, [%1+ 8]
457 :     or eax, [%1+ 4]
458 :     or edx, [%1+12]
459 :     or eax, edx
460 :     jz near %2
461 :     %endmacro
462 :    
463 :     ;-----------------------------------------------------------------------------
464 :     ; Function idct (this one skips null rows)
465 :     ;-----------------------------------------------------------------------------
466 :    
467 :     ALIGN 16
468 :     idct_sse2_sparse_skal:
469 :    
470 :     mov ecx, [esp+ 4] ; Src
471 :    
472 :     TEST_ROW ecx, .Row0_Round
473 :     iMTX_MULT 0, iTab1, Idct_Rnd0, 11
474 :     jmp .Row1
475 :     .Row0_Round
476 :     movq mm0, [Idct_Sparse_Rnd0]
477 :     movq [ecx ], mm0
478 :     movq [ecx+8], mm0
479 :    
480 :     .Row1
481 :     TEST_ROW ecx+16, .Row1_Round
482 :     iMTX_MULT 1, iTab2, Idct_Rnd1, 11
483 :     jmp .Row2
484 :     .Row1_Round
485 :     movq mm0, [Idct_Sparse_Rnd1]
486 :     movq [ecx+16 ], mm0
487 :     movq [ecx+16+8], mm0
488 :    
489 :     .Row2
490 :     TEST_ROW ecx+32, .Row2_Round
491 :     iMTX_MULT 2, iTab3, Idct_Rnd2, 11
492 :     jmp .Row3
493 :     .Row2_Round
494 :     movq mm0, [Idct_Sparse_Rnd2]
495 :     movq [ecx+32 ], mm0
496 :     movq [ecx+32+8], mm0
497 :    
498 :     .Row3
499 :     TEST_ROW ecx+48, .Row4
500 :     iMTX_MULT 3, iTab4, Idct_Rnd3, 11
501 :     jmp .Row4
502 :    
503 :     .Row4
504 :     TEST_ROW ecx+64, .Row5
505 :     iMTX_MULT 4, iTab1, Idct_Rnd4, 11
506 :     jmp .Row5
507 :    
508 :     .Row5
509 :     TEST_ROW ecx+80, .Row6
510 :     iMTX_MULT 5, iTab4, Idct_Rnd5, 11
511 :    
512 :     .Row6
513 :     TEST_ROW ecx+96, .Row7
514 :     iMTX_MULT 6, iTab3, Idct_Rnd6, 11
515 :    
516 :     .Row7
517 :     TEST_ROW ecx+112, .End
518 :     iMTX_MULT 7, iTab2, Idct_Rnd7, 11
519 :     .End
520 :    
521 :     iLLM_PASS ecx+0
522 :     ret
523 :    
524 :     ;-----------------------------------------------------------------------------
525 :     ; Helper macro fLLM_PASS
526 :     ;-----------------------------------------------------------------------------
527 :    
528 :     %macro fLLM_PASS 2 ; %1: src/dst, %2:Shift
529 :    
530 :     movdqa xmm0, [%1+0*16] ; In0
531 :     movdqa xmm2, [%1+2*16] ; In2
532 :     movdqa xmm3, xmm0
533 :     movdqa xmm4, xmm2
534 :     movdqa xmm7, [%1+7*16] ; In7
535 :     movdqa xmm5, [%1+5*16] ; In5
536 :    
537 :     psubsw xmm0, xmm7 ; t7 = In0-In7
538 :     paddsw xmm7, xmm3 ; t0 = In0+In7
539 :     psubsw xmm2, xmm5 ; t5 = In2-In5
540 :     paddsw xmm5, xmm4 ; t2 = In2+In5
541 :    
542 :     movdqa xmm3, [%1+3*16] ; In3
543 :     movdqa xmm4, [%1+4*16] ; In4
544 :     movdqa xmm1, xmm3
545 :     psubsw xmm3, xmm4 ; t4 = In3-In4
546 :     paddsw xmm4, xmm1 ; t3 = In3+In4
547 :     movdqa xmm6, [%1+6*16] ; In6
548 :     movdqa xmm1, [%1+1*16] ; In1
549 :     psubsw xmm1, xmm6 ; t6 = In1-In6
550 :     paddsw xmm6, [%1+1*16] ; t1 = In1+In6
551 :    
552 :     psubsw xmm7, xmm4 ; tm03 = t0-t3
553 :     psubsw xmm6, xmm5 ; tm12 = t1-t2
554 :     paddsw xmm4, xmm4 ; 2.t3
555 :     paddsw xmm5, xmm5 ; 2.t2
556 :     paddsw xmm4, xmm7 ; tp03 = t0+t3
557 :     paddsw xmm5, xmm6 ; tp12 = t1+t2
558 :    
559 :     psllw xmm2, %2+1 ; shift t5 (shift +1 to..
560 :     psllw xmm1, %2+1 ; shift t6 ..compensate cos4/2)
561 :     psllw xmm4, %2 ; shift t3
562 :     psllw xmm5, %2 ; shift t2
563 :     psllw xmm7, %2 ; shift t0
564 :     psllw xmm6, %2 ; shift t1
565 :     psllw xmm3, %2 ; shift t4
566 :     psllw xmm0, %2 ; shift t7
567 :    
568 :     psubsw xmm4, xmm5 ; out4 = tp03-tp12
569 :     psubsw xmm1, xmm2 ; xmm1: t6-t5
570 :     paddsw xmm5, xmm5
571 :     paddsw xmm2, xmm2
572 :     paddsw xmm5, xmm4 ; out0 = tp03+tp12
573 :     movdqa [%1+4*16], xmm4 ; => out4
574 :     paddsw xmm2, xmm1 ; xmm2: t6+t5
575 :     movdqa [%1+0*16], xmm5 ; => out0
576 :    
577 :     movdqa xmm4, [tan2] ; xmm4 <= tan2
578 :     pmulhw xmm4, xmm7 ; tm03*tan2
579 :     movdqa xmm5, [tan2] ; xmm5 <= tan2
580 :     psubsw xmm4, xmm6 ; out6 = tm03*tan2 - tm12
581 :     pmulhw xmm5, xmm6 ; tm12*tan2
582 :     paddsw xmm5, xmm7 ; out2 = tm12*tan2 + tm03
583 :    
584 :     movdqa xmm6, [sqrt2]
585 :     movdqa xmm7, [Rounder1]
586 :    
587 :     pmulhw xmm2, xmm6 ; xmm2: tp65 = (t6 + t5)*cos4
588 :     por xmm5, xmm7 ; correct out2
589 :     por xmm4, xmm7 ; correct out6
590 :     pmulhw xmm1, xmm6 ; xmm1: tm65 = (t6 - t5)*cos4
591 :     por xmm2, xmm7 ; correct tp65
592 :    
593 :     movdqa [%1+2*16], xmm5 ; => out2
594 :     movdqa xmm5, xmm3 ; save t4
595 :     movdqa [%1+6*16], xmm4 ; => out6
596 :     movdqa xmm4, xmm0 ; save t7
597 :    
598 :     psubsw xmm3, xmm1 ; xmm3: tm465 = t4 - tm65
599 :     psubsw xmm0, xmm2 ; xmm0: tm765 = t7 - tp65
600 :     paddsw xmm2, xmm4 ; xmm2: tp765 = t7 + tp65
601 :     paddsw xmm1, xmm5 ; xmm1: tp465 = t4 + tm65
602 :    
603 :     movdqa xmm4, [tan3] ; tan3 - 1
604 :     movdqa xmm5, [tan1] ; tan1
605 :    
606 :     movdqa xmm7, xmm3 ; save tm465
607 :     pmulhw xmm3, xmm4 ; tm465*(tan3-1)
608 :     movdqa xmm6, xmm1 ; save tp465
609 :     pmulhw xmm1, xmm5 ; tp465*tan1
610 :    
611 :     paddsw xmm3, xmm7 ; tm465*tan3
612 :     pmulhw xmm4, xmm0 ; tm765*(tan3-1)
613 :     paddsw xmm4, xmm0 ; tm765*tan3
614 :     pmulhw xmm5, xmm2 ; tp765*tan1
615 :    
616 :     paddsw xmm1, xmm2 ; out1 = tp765 + tp465*tan1
617 :     psubsw xmm0, xmm3 ; out3 = tm765 - tm465*tan3
618 :     paddsw xmm7, xmm4 ; out5 = tm465 + tm765*tan3
619 :     psubsw xmm5, xmm6 ; out7 =-tp465 + tp765*tan1
620 :    
621 :     movdqa [%1+1*16], xmm1 ; => out1
622 :     movdqa [%1+3*16], xmm0 ; => out3
623 :     movdqa [%1+5*16], xmm7 ; => out5
624 :     movdqa [%1+7*16], xmm5 ; => out7
625 :    
626 :     %endmacro
627 :    
628 :     ;-----------------------------------------------------------------------------
629 :     ;Helper macro fMTX_MULT
630 :     ;-----------------------------------------------------------------------------
631 :    
632 :     %macro fMTX_MULT 3 ; %1=src, %2 = Coeffs, %3=rounders
633 :    
634 :     movdqa xmm0, [ecx+%1*16+0] ; xmm0 = [0123][4567]
635 :     pshufhw xmm1, xmm0, 00011011b ; xmm1 = [----][7654]
636 :     pshufd xmm0, xmm0, 01000100b
637 :     pshufd xmm1, xmm1, 11101110b
638 :    
639 :     movdqa xmm2, xmm0
640 :     paddsw xmm0, xmm1 ; xmm0 = [a0 a1 a2 a3]
641 :     psubsw xmm2, xmm1 ; xmm2 = [b0 b1 b2 b3]
642 :    
643 :     punpckldq xmm0, xmm2 ; xmm0 = [a0 a1 b0 b1][a2 a3 b2 b3]
644 :     pshufd xmm2, xmm0, 01001110b ; xmm2 = [a2 a3 b2 b3][a0 a1 b0 b1]
645 :    
646 :     ; [M00 M01 M16 M17] [M06 M07 M22 M23] x mm0 = [0 /1 /2'/3']
647 :     ; [M02 M03 M18 M19] [M04 M05 M20 M21] x mm2 = [0'/1'/2 /3 ]
648 :     ; [M08 M09 M24 M25] [M14 M15 M30 M31] x mm0 = [4 /5 /6'/7']
649 :     ; [M10 M11 M26 M27] [M12 M13 M28 M29] x mm2 = [4'/5'/6 /7 ]
650 :    
651 :     movdqa xmm1, [%2+16]
652 :     movdqa xmm3, [%2+32]
653 :     pmaddwd xmm1, xmm2
654 :     pmaddwd xmm3, xmm0
655 :     pmaddwd xmm2, [%2+48]
656 :     pmaddwd xmm0, [%2+ 0]
657 :    
658 :     paddd xmm0, xmm1 ; [ out0 | out1 ][ out2 | out3 ]
659 :     paddd xmm2, xmm3 ; [ out4 | out5 ][ out6 | out7 ]
660 :     psrad xmm0, 16
661 :     psrad xmm2, 16
662 :    
663 :     packssdw xmm0, xmm2 ; [ out0 .. out7 ]
664 :     paddsw xmm0, [%3] ; Round
665 :    
666 :     psraw xmm0, 4 ; => [-2048, 2047]
667 :    
668 :     movdqa [ecx+%1*16+0], xmm0
669 :     %endmacro
670 :    
671 :     ;-----------------------------------------------------------------------------
672 :     ; Function Forward DCT
673 :     ;-----------------------------------------------------------------------------
674 :    
675 :     ALIGN 16
676 :     fdct_sse2_skal:
677 :     mov ecx, [esp+4]
678 :     fLLM_PASS ecx+0, 3
679 :     fMTX_MULT 0, fTab1, Fdct_Rnd0
680 :     fMTX_MULT 1, fTab2, Fdct_Rnd2
681 :     fMTX_MULT 2, fTab3, Fdct_Rnd1
682 :     fMTX_MULT 3, fTab4, Fdct_Rnd1
683 :     fMTX_MULT 4, fTab1, Fdct_Rnd0
684 :     fMTX_MULT 5, fTab4, Fdct_Rnd1
685 :     fMTX_MULT 6, fTab3, Fdct_Rnd1
686 :     fMTX_MULT 7, fTab2, Fdct_Rnd1
687 :     ret

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4