[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.1.2.1, Wed Oct 29 12:41:41 2003 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    SECTION .rodata
145    
146    ALIGN 16
147    tan1:    times 8 dw 0x32ec    ; tan( pi/16)
148    tan2:    times 8 dw 0x6a0a    ; tan(2pi/16)  (=sqrt(2)-1)
149    tan3:    times 8 dw 0xab0e    ; tan(3pi/16)-1
150    sqrt2:   times 8 dw 0x5a82    ; 0.5/sqrt(2)
151    
152    ;-----------------------------------------------------------------------------
153    ; Inverse DCT tables
154    ;-----------------------------------------------------------------------------
155    
156    ALIGN 16
157    iTab1:
158      dw 0x4000, 0x539f, 0x4000, 0x22a3
159      dw 0x4000, 0xdd5d, 0x4000, 0xac61
160      dw 0x4000, 0x22a3, 0xc000, 0xac61
161      dw 0xc000, 0x539f, 0x4000, 0xdd5d
162      dw 0x58c5, 0x4b42, 0x4b42, 0xee58
163      dw 0x3249, 0xa73b, 0x11a8, 0xcdb7
164      dw 0x3249, 0x11a8, 0xa73b, 0xcdb7
165      dw 0x11a8, 0x4b42, 0x4b42, 0xa73b
166    
167    iTab2:
168      dw 0x58c5, 0x73fc, 0x58c5, 0x300b
169      dw 0x58c5, 0xcff5, 0x58c5, 0x8c04
170      dw 0x58c5, 0x300b, 0xa73b, 0x8c04
171      dw 0xa73b, 0x73fc, 0x58c5, 0xcff5
172      dw 0x7b21, 0x6862, 0x6862, 0xe782
173      dw 0x45bf, 0x84df, 0x187e, 0xba41
174      dw 0x45bf, 0x187e, 0x84df, 0xba41
175      dw 0x187e, 0x6862, 0x6862, 0x84df
176    
177    iTab3:
178      dw 0x539f, 0x6d41, 0x539f, 0x2d41
179      dw 0x539f, 0xd2bf, 0x539f, 0x92bf
180      dw 0x539f, 0x2d41, 0xac61, 0x92bf
181      dw 0xac61, 0x6d41, 0x539f, 0xd2bf
182      dw 0x73fc, 0x6254, 0x6254, 0xe8ee
183      dw 0x41b3, 0x8c04, 0x1712, 0xbe4d
184      dw 0x41b3, 0x1712, 0x8c04, 0xbe4d
185      dw 0x1712, 0x6254, 0x6254, 0x8c04
186    
187    iTab4:
188      dw 0x4b42, 0x6254, 0x4b42, 0x28ba
189      dw 0x4b42, 0xd746, 0x4b42, 0x9dac
190      dw 0x4b42, 0x28ba, 0xb4be, 0x9dac
191      dw 0xb4be, 0x6254, 0x4b42, 0xd746
192      dw 0x6862, 0x587e, 0x587e, 0xeb3d
193      dw 0x3b21, 0x979e, 0x14c3, 0xc4df
194      dw 0x3b21, 0x14c3, 0x979e, 0xc4df
195      dw 0x14c3, 0x587e, 0x587e, 0x979e
196    
197      ; the original rounding trick is by
198      ; Michel Lespinasse (hi Walken!) <walken@zoy.org>
199    
200    ALIGN 16
201    Idct_Rnd0: dd  65535, 65535, 65535, 65535
202    Idct_Rnd1: dd   3612,  3612,  3612,  3612
203    Idct_Rnd2: dd   2271,  2271,  2271,  2271
204    Idct_Rnd3: dd   1203,  1203,  1203,  1203
205    Idct_Rnd4: dd   1023,  1023,  1023,  1023
206    Idct_Rnd5: dd    102,   102,   102,   102
207    Idct_Rnd6: dd    398,   398,   398,   398
208    Idct_Rnd7: dd    469,   469,   469,   469
209    
210    Idct_Sparse_Rnd0: times 4 dw  (65535>>11)
211    Idct_Sparse_Rnd1: times 4 dw  ( 3612>>11)
212    Idct_Sparse_Rnd2: times 4 dw  ( 2271>>11)
213      ; other rounders are zero...
214    
215    ;-----------------------------------------------------------------------------
216    ; Forward DCT tables
217    ;-----------------------------------------------------------------------------
218    
219    ALIGN 16
220    fTab1:
221      dw 0x4000, 0x4000, 0x58c5, 0x4b42,
222      dw 0xdd5d, 0xac61, 0xa73b, 0xcdb7,
223      dw 0x4000, 0x4000, 0x3249, 0x11a8,
224      dw 0x539f, 0x22a3, 0x4b42, 0xee58,
225      dw 0x4000, 0xc000, 0x3249, 0xa73b,
226      dw 0x539f, 0xdd5d, 0x4b42, 0xa73b,
227      dw 0xc000, 0x4000, 0x11a8, 0x4b42,
228      dw 0x22a3, 0xac61, 0x11a8, 0xcdb7
229    
230    fTab2:
231      dw 0x58c5, 0x58c5, 0x7b21, 0x6862,
232      dw 0xcff5, 0x8c04, 0x84df, 0xba41,
233      dw 0x58c5, 0x58c5, 0x45bf, 0x187e,
234      dw 0x73fc, 0x300b, 0x6862, 0xe782,
235      dw 0x58c5, 0xa73b, 0x45bf, 0x84df,
236      dw 0x73fc, 0xcff5, 0x6862, 0x84df,
237      dw 0xa73b, 0x58c5, 0x187e, 0x6862,
238      dw 0x300b, 0x8c04, 0x187e, 0xba41
239    
240    fTab3:
241      dw 0x539f, 0x539f, 0x73fc, 0x6254,
242      dw 0xd2bf, 0x92bf, 0x8c04, 0xbe4d,
243      dw 0x539f, 0x539f, 0x41b3, 0x1712,
244      dw 0x6d41, 0x2d41, 0x6254, 0xe8ee,
245      dw 0x539f, 0xac61, 0x41b3, 0x8c04,
246      dw 0x6d41, 0xd2bf, 0x6254, 0x8c04,
247      dw 0xac61, 0x539f, 0x1712, 0x6254,
248      dw 0x2d41, 0x92bf, 0x1712, 0xbe4d
249    
250    fTab4:
251      dw 0x4b42, 0x4b42, 0x6862, 0x587e,
252      dw 0xd746, 0x9dac, 0x979e, 0xc4df,
253      dw 0x4b42, 0x4b42, 0x3b21, 0x14c3,
254      dw 0x6254, 0x28ba, 0x587e, 0xeb3d,
255      dw 0x4b42, 0xb4be, 0x3b21, 0x979e,
256      dw 0x6254, 0xd746, 0x587e, 0x979e,
257      dw 0xb4be, 0x4b42, 0x14c3, 0x587e,
258      dw 0x28ba, 0x9dac, 0x14c3, 0xc4df
259    
260    
261    ALIGN 16
262    Fdct_Rnd0: dw  6,8,8,8, 6,8,8,8
263    Fdct_Rnd1: dw  8,8,8,8, 8,8,8,8
264    Fdct_Rnd2: dw 10,8,8,8, 8,8,8,8
265    Rounder1:  dw  1,1,1,1, 1,1,1,1
266    
267    ;=============================================================================
268    ; Code
269    ;=============================================================================
270    
271    SECTION .text
272    
273    cglobal idct_sse2_skal
274    cglobal idct_sse2_sparse_skal
275    cglobal fdct_sse2_skal
276    
277    ;-----------------------------------------------------------------------------
278    ; Helper macro iMTX_MULT
279    ;-----------------------------------------------------------------------------
280    
281    %macro iMTX_MULT 4   ; %1=src, %2 = Table to use, %3=rounder, %4=Shift
282    
283      movdqa  xmm0, [ecx+%1*16]     ; xmm0 = [01234567]
284    
285      pshuflw xmm0, xmm0, 11011000b ; [0213]
286      pshufhw xmm0, xmm0, 11011000b ; [02134657]
287      pshufd  xmm4, xmm0, 00000000b ; [02020202]
288      pshufd  xmm5, xmm0, 10101010b ; [46464646]
289      pshufd  xmm6, xmm0, 01010101b ; [13131313]
290      pshufd  xmm7, xmm0, 11111111b ; [57575757]
291    
292      pmaddwd xmm4, [%2+ 0]   ; dot [M00,M01][M04,M05][M08,M09][M12,M13]
293      pmaddwd xmm5, [%2+16]   ; dot [M02,M03][M06,M07][M10,M11][M14,M15]
294      pmaddwd xmm6, [%2+32]   ; dot [M16,M17][M20,M21][M24,M25][M28,M29]
295      pmaddwd xmm7, [%2+48]   ; dot [M18,M19][M22,M23][M26,M27][M30,M31]
296      paddd   xmm4, [%3]      ; Round
297    
298      paddd   xmm6, xmm7      ; [b0|b1|b2|b3]
299      paddd   xmm4, xmm5      ; [a0|a1|a2|a3]
300    
301      movdqa  xmm7, xmm6
302      paddd   xmm6, xmm4      ; mm6=a+b
303      psubd   xmm4, xmm7      ; mm4=a-b
304      psrad   xmm6, %4        ; => out [0123]
305      psrad   xmm4, %4        ; => out [7654]
306    
307      packssdw xmm6, xmm4     ; [01237654]
308      pshufhw xmm6, xmm6, 00011011b ; [01234567]
309    
310      movdqa  [ecx+%1*16], xmm6
311    
312    %endmacro
313    
314    ;-----------------------------------------------------------------------------
315    ; Helper macro iLLM_PASS
316    ;-----------------------------------------------------------------------------
317    
318    %macro iLLM_PASS 1  ; %1: src/dst
319    
320      movdqa xmm0, [tan3]    ; t3-1
321      movdqa xmm3, [%1+16*3] ; x3
322      movdqa xmm1, xmm0       ; t3-1
323      movdqa xmm5, [%1+16*5] ; x5
324    
325      movdqa xmm4, [tan1]    ; t1
326      movdqa xmm6, [%1+16*1] ; x1
327      movdqa xmm7, [%1+16*7] ; x7
328      movdqa xmm2, xmm4       ; t1
329    
330      pmulhw xmm0, xmm3       ; x3*(t3-1)
331      pmulhw xmm1, xmm5       ; x5*(t3-1)
332      paddsw xmm0, xmm3       ; x3*t3
333      paddsw xmm1, xmm5       ; x5*t3
334      psubsw xmm0, xmm5       ; x3*t3-x5 = tm35
335      paddsw xmm1, xmm3       ; x3+x5*t3 = tp35
336    
337      pmulhw xmm4, xmm7       ; x7*t1
338      pmulhw xmm2, xmm6       ; x1*t1
339      paddsw xmm4, xmm6       ; x1+t1*x7 = tp17
340      psubsw xmm2, xmm7       ; x1*t1-x7 = tm17
341    
342    
343      movdqa xmm3, [sqrt2]
344      movdqa xmm7, xmm4
345      movdqa xmm6, xmm2
346      psubsw xmm4, xmm1       ; tp17-tp35 = t1
347      psubsw xmm2, xmm0       ; tm17-tm35 = b3
348      paddsw xmm1, xmm7       ; tp17+tp35 = b0
349      paddsw xmm0, xmm6       ; tm17+tm35 = t2
350    
351        ; xmm1 = b0, xmm2 = b3. preserved
352    
353      movdqa xmm6, xmm4
354      psubsw xmm4, xmm0       ; t1-t2
355      paddsw xmm0, xmm6       ; t1+t2
356    
357      pmulhw xmm4, xmm3       ; (t1-t2)/(2.sqrt2)
358      pmulhw xmm0, xmm3       ; (t1+t2)/(2.sqrt2)
359    
360      paddsw xmm0, xmm0       ; 2.(t1+t2) = b1
361      paddsw xmm4, xmm4       ; 2.(t1-t2) = b2
362    
363      movdqa xmm7, [tan2]    ; t2
364      movdqa xmm3, [%1+2*16] ; x2
365      movdqa xmm6, [%1+6*16] ; x6
366      movdqa xmm5, xmm7       ; t2
367    
368      pmulhw xmm7, xmm6       ; x6*t2
369      pmulhw xmm5, xmm3       ; x2*t2
370    
371      paddsw xmm7, xmm3       ; x2+x6*t2 = tp26
372      psubsw xmm5, xmm6       ; x2*t2-x6 = tm26
373    
374    
375      ; use:xmm3,xmm5,xmm6,xmm7   frozen: xmm0,xmm4,xmm1,xmm2
376    
377      movdqa xmm3, [%1+0*16] ; x0
378      movdqa xmm6, [%1+4*16] ; x4
379    
380      psubsw xmm3, xmm6   ; x0-x4 = tm04
381      paddsw xmm6, xmm6   ; 2.x4
382      paddsw xmm6, xmm3   ; x0+x4 = tp04
383    
384      psubsw xmm3, xmm5   ; tm04-tm26 = a2
385      psubsw xmm6, xmm7   ; tp04-tp26 = a3
386      paddsw xmm5, xmm5   ; 2.tm26
387      paddsw xmm7, xmm7   ; 2.tp26
388      paddsw xmm5, xmm3   ; tm04+tm26 = a1
389      paddsw xmm7, xmm6   ; tp04+tp26 = a0
390    
391      psubsw xmm5, xmm0   ; a1-b1
392      psubsw xmm3, xmm4   ; a2-b2
393      paddsw xmm0, xmm0   ; 2.b1
394      paddsw xmm4, xmm4   ; 2.b2
395      paddsw xmm0, xmm5   ; a1+b1
396      paddsw xmm4, xmm3   ; a2+b2
397    
398      psraw  xmm5, 6     ; out6
399      psraw  xmm3, 6     ; out5
400      psraw  xmm0, 6     ; out1
401      psraw  xmm4, 6     ; out2
402    
403      movdqa [%1+6*16], xmm5
404      movdqa [%1+5*16], xmm3
405      movdqa [%1+1*16], xmm0
406      movdqa [%1+2*16], xmm4
407    
408        ; reminder: xmm1=b0, xmm2=b3, xmm7=a0, xmm6=a3
409    
410      movdqa xmm0, xmm7
411      movdqa xmm4, xmm6
412      psubsw xmm7, xmm1   ; a0-b0
413      psubsw xmm6, xmm2   ; a3-b3
414      paddsw xmm1, xmm0   ; a0+b0
415      paddsw xmm2, xmm4   ; a3+b3
416    
417      psraw  xmm1, 6     ; out0
418      psraw  xmm7, 6     ; out7
419      psraw  xmm2, 6     ; out3
420      psraw  xmm6, 6     ; out4
421    
422      movdqa [%1+0*16], xmm1
423      movdqa [%1+3*16], xmm2
424      movdqa [%1+4*16], xmm6
425      movdqa [%1+7*16], xmm7
426    %endmacro
427    
428    ;-----------------------------------------------------------------------------
429    ; Function idct (the straight forward version)
430    ;-----------------------------------------------------------------------------
431    
432    ALIGN 16
433    idct_sse2_skal:
434      mov ecx, [esp+4]
435      iMTX_MULT  0, iTab1, Idct_Rnd0, 11
436      iMTX_MULT  1, iTab2, Idct_Rnd1, 11
437      iMTX_MULT  2, iTab3, Idct_Rnd2, 11
438      iMTX_MULT  3, iTab4, Idct_Rnd3, 11
439      iMTX_MULT  4, iTab1, Idct_Rnd4, 11
440      iMTX_MULT  5, iTab4, Idct_Rnd5, 11
441      iMTX_MULT  6, iTab3, Idct_Rnd6, 11
442      iMTX_MULT  7, iTab2, Idct_Rnd7, 11
443      iLLM_PASS ecx+0
444      ret
445    
446    ;-----------------------------------------------------------------------------
447    ; Helper macro TEST_ROW (test a null row)
448    ;-----------------------------------------------------------------------------
449    
450    %macro TEST_ROW 2     ; %1:src,  %2:label x8
451      mov eax, [%1   ]
452      mov edx, [%1+ 8]
453      or  eax, [%1+ 4]
454      or  edx, [%1+12]
455      or  eax, edx
456      jz near %2
457    %endmacro
458    
459    ;-----------------------------------------------------------------------------
460    ; Function idct (this one skips null rows)
461    ;-----------------------------------------------------------------------------
462    
463    ALIGN 16
464    idct_sse2_sparse_skal:
465    
466      mov ecx, [esp+ 4]  ; Src
467    
468      TEST_ROW ecx, .Row0_Round
469      iMTX_MULT  0, iTab1, Idct_Rnd0, 11
470      jmp .Row1
471    .Row0_Round
472      movq mm0, [Idct_Sparse_Rnd0]
473      movq [ecx  ], mm0
474      movq [ecx+8], mm0
475    
476    .Row1
477      TEST_ROW ecx+16, .Row1_Round
478      iMTX_MULT  1, iTab2, Idct_Rnd1, 11
479      jmp .Row2
480    .Row1_Round
481      movq mm0, [Idct_Sparse_Rnd1]
482      movq [ecx+16  ], mm0
483      movq [ecx+16+8], mm0
484    
485    .Row2
486      TEST_ROW ecx+32, .Row2_Round
487      iMTX_MULT  2, iTab3, Idct_Rnd2, 11
488      jmp .Row3
489    .Row2_Round
490      movq mm0, [Idct_Sparse_Rnd2]
491      movq [ecx+32  ], mm0
492      movq [ecx+32+8], mm0
493    
494    .Row3
495      TEST_ROW ecx+48, .Row4
496      iMTX_MULT  3, iTab4, Idct_Rnd3, 11
497      jmp .Row4
498    
499    .Row4
500      TEST_ROW ecx+64, .Row5
501      iMTX_MULT  4, iTab1, Idct_Rnd4, 11
502      jmp .Row5
503    
504    .Row5
505      TEST_ROW ecx+80, .Row6
506      iMTX_MULT  5, iTab4, Idct_Rnd5, 11
507    
508    .Row6
509      TEST_ROW ecx+96, .Row7
510      iMTX_MULT  6, iTab3, Idct_Rnd6, 11
511    
512    .Row7
513      TEST_ROW ecx+112, .End
514      iMTX_MULT  7, iTab2, Idct_Rnd7, 11
515    .End
516    
517      iLLM_PASS ecx+0
518      ret
519    
520    ;-----------------------------------------------------------------------------
521    ; Helper macro fLLM_PASS
522    ;-----------------------------------------------------------------------------
523    
524    %macro fLLM_PASS 2  ; %1: src/dst, %2:Shift
525    
526      movdqa xmm0, [%1+0*16]   ; In0
527      movdqa xmm2, [%1+2*16]   ; In2
528      movdqa xmm3, xmm0
529      movdqa xmm4, xmm2
530      movdqa xmm7, [%1+7*16]   ; In7
531      movdqa xmm5, [%1+5*16]   ; In5
532    
533      psubsw xmm0, xmm7         ; t7 = In0-In7
534      paddsw xmm7, xmm3         ; t0 = In0+In7
535      psubsw xmm2, xmm5         ; t5 = In2-In5
536      paddsw xmm5, xmm4         ; t2 = In2+In5
537    
538      movdqa xmm3, [%1+3*16]   ; In3
539      movdqa xmm4, [%1+4*16]   ; In4
540      movdqa xmm1, xmm3
541      psubsw xmm3, xmm4         ; t4 = In3-In4
542      paddsw xmm4, xmm1         ; t3 = In3+In4
543      movdqa xmm6, [%1+6*16]   ; In6
544      movdqa xmm1, [%1+1*16]   ; In1
545      psubsw xmm1, xmm6         ; t6 = In1-In6
546      paddsw xmm6, [%1+1*16]   ; t1 = In1+In6
547    
548      psubsw xmm7, xmm4         ; tm03 = t0-t3
549      psubsw xmm6, xmm5         ; tm12 = t1-t2
550      paddsw xmm4, xmm4         ; 2.t3
551      paddsw xmm5, xmm5         ; 2.t2
552      paddsw xmm4, xmm7         ; tp03 = t0+t3
553      paddsw xmm5, xmm6         ; tp12 = t1+t2
554    
555      psllw  xmm2, %2+1        ; shift t5 (shift +1 to..
556      psllw  xmm1, %2+1        ; shift t6  ..compensate cos4/2)
557      psllw  xmm4, %2          ; shift t3
558      psllw  xmm5, %2          ; shift t2
559      psllw  xmm7, %2          ; shift t0
560      psllw  xmm6, %2          ; shift t1
561      psllw  xmm3, %2          ; shift t4
562      psllw  xmm0, %2          ; shift t7
563    
564      psubsw xmm4, xmm5         ; out4 = tp03-tp12
565      psubsw xmm1, xmm2         ; xmm1: t6-t5
566      paddsw xmm5, xmm5
567      paddsw xmm2, xmm2
568      paddsw xmm5, xmm4         ; out0 = tp03+tp12
569      movdqa [%1+4*16], xmm4   ; => out4
570      paddsw xmm2, xmm1         ; xmm2: t6+t5
571      movdqa [%1+0*16], xmm5   ; => out0
572    
573      movdqa xmm4, [tan2]      ; xmm4 <= tan2
574      pmulhw xmm4, xmm7         ; tm03*tan2
575      movdqa xmm5, [tan2]      ; xmm5 <= tan2
576      psubsw xmm4, xmm6         ; out6 = tm03*tan2 - tm12
577      pmulhw xmm5, xmm6         ; tm12*tan2
578      paddsw xmm5, xmm7         ; out2 = tm12*tan2 + tm03
579    
580      movdqa xmm6, [sqrt2]
581      movdqa xmm7, [Rounder1]
582    
583      pmulhw xmm2, xmm6         ; xmm2: tp65 = (t6 + t5)*cos4
584      por    xmm5, xmm7         ; correct out2
585      por    xmm4, xmm7         ; correct out6
586      pmulhw xmm1, xmm6         ; xmm1: tm65 = (t6 - t5)*cos4
587      por    xmm2, xmm7         ; correct tp65
588    
589      movdqa [%1+2*16], xmm5   ; => out2
590      movdqa xmm5, xmm3         ; save t4
591      movdqa [%1+6*16], xmm4   ; => out6
592      movdqa xmm4, xmm0         ; save t7
593    
594      psubsw xmm3, xmm1         ; xmm3: tm465 = t4 - tm65
595      psubsw xmm0, xmm2         ; xmm0: tm765 = t7 - tp65
596      paddsw xmm2, xmm4         ; xmm2: tp765 = t7 + tp65
597      paddsw xmm1, xmm5         ; xmm1: tp465 = t4 + tm65
598    
599      movdqa xmm4, [tan3]      ; tan3 - 1
600      movdqa xmm5, [tan1]      ; tan1
601    
602      movdqa xmm7, xmm3         ; save tm465
603      pmulhw xmm3, xmm4         ; tm465*(tan3-1)
604      movdqa xmm6, xmm1         ; save tp465
605      pmulhw xmm1, xmm5         ; tp465*tan1
606    
607      paddsw xmm3, xmm7         ; tm465*tan3
608      pmulhw xmm4, xmm0         ; tm765*(tan3-1)
609      paddsw xmm4, xmm0         ; tm765*tan3
610      pmulhw xmm5, xmm2         ; tp765*tan1
611    
612      paddsw xmm1, xmm2         ; out1 = tp765 + tp465*tan1
613      psubsw xmm0, xmm3         ; out3 = tm765 - tm465*tan3
614      paddsw xmm7, xmm4         ; out5 = tm465 + tm765*tan3
615      psubsw xmm5, xmm6         ; out7 =-tp465 + tp765*tan1
616    
617      movdqa [%1+1*16], xmm1   ; => out1
618      movdqa [%1+3*16], xmm0   ; => out3
619      movdqa [%1+5*16], xmm7   ; => out5
620      movdqa [%1+7*16], xmm5   ; => out7
621    
622    %endmacro
623    
624    ;-----------------------------------------------------------------------------
625    ;Helper macro fMTX_MULT
626    ;-----------------------------------------------------------------------------
627    
628    %macro fMTX_MULT 3   ; %1=src, %2 = Coeffs, %3=rounders
629    
630      movdqa   xmm0, [ecx+%1*16+0]   ; xmm0 = [0123][4567]
631      pshufhw  xmm1, xmm0, 00011011b ; xmm1 = [----][7654]
632      pshufd   xmm0, xmm0, 01000100b
633      pshufd   xmm1, xmm1, 11101110b
634    
635      movdqa   xmm2, xmm0
636      paddsw  xmm0, xmm1              ; xmm0 = [a0 a1 a2 a3]
637      psubsw  xmm2, xmm1              ; xmm2 = [b0 b1 b2 b3]
638    
639      punpckldq xmm0, xmm2            ; xmm0 = [a0 a1 b0 b1][a2 a3 b2 b3]
640      pshufd    xmm2, xmm0, 01001110b ; xmm2 = [a2 a3 b2 b3][a0 a1 b0 b1]
641    
642        ;  [M00 M01    M16 M17] [M06 M07    M22 M23]  x mm0 = [0 /1 /2'/3']
643        ;  [M02 M03    M18 M19] [M04 M05    M20 M21]  x mm2 = [0'/1'/2 /3 ]
644        ;  [M08 M09    M24 M25] [M14 M15    M30 M31]  x mm0 = [4 /5 /6'/7']
645        ;  [M10 M11    M26 M27] [M12 M13    M28 M29]  x mm2 = [4'/5'/6 /7 ]
646    
647      movdqa  xmm1, [%2+16]
648      movdqa  xmm3, [%2+32]
649      pmaddwd xmm1, xmm2
650      pmaddwd xmm3, xmm0
651      pmaddwd xmm2, [%2+48]
652      pmaddwd xmm0, [%2+ 0]
653    
654      paddd   xmm0, xmm1             ;  [ out0 | out1 ][ out2 | out3 ]
655      paddd   xmm2, xmm3             ;  [ out4 | out5 ][ out6 | out7 ]
656      psrad   xmm0, 16
657      psrad   xmm2, 16
658    
659      packssdw xmm0, xmm2            ;  [ out0 .. out7 ]
660      paddsw   xmm0, [%3]            ;  Round
661    
662      psraw    xmm0, 4               ; => [-2048, 2047]
663    
664      movdqa  [ecx+%1*16+0], xmm0
665    %endmacro
666    
667    ;-----------------------------------------------------------------------------
668    ; Function Forward DCT
669    ;-----------------------------------------------------------------------------
670    
671    ALIGN 16
672    fdct_sse2_skal:
673      mov ecx, [esp+4]
674      fLLM_PASS ecx+0, 3
675      fMTX_MULT  0, fTab1, Fdct_Rnd0
676      fMTX_MULT  1, fTab2, Fdct_Rnd2
677      fMTX_MULT  2, fTab3, Fdct_Rnd1
678      fMTX_MULT  3, fTab4, Fdct_Rnd1
679      fMTX_MULT  4, fTab1, Fdct_Rnd0
680      fMTX_MULT  5, fTab4, Fdct_Rnd1
681      fMTX_MULT  6, fTab3, Fdct_Rnd1
682      fMTX_MULT  7, fTab2, Fdct_Rnd1
683      ret

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

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