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 |