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

Diff of /xvidcore/src/dct/x86_asm/fdct_sse2_skal.asm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1, Wed Oct 29 12:41:41 2003 UTC revision 1.2, Mon Mar 22 22:36:23 2004 UTC
# Line 0  Line 1 
1    ;/****************************************************************************
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$
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

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

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