Parent Directory | Revision Log
Revision 1.6 - (view) (download)
1 : | edgomez | 1.2 | ;/**************************************************************************** |
2 : | ; * | ||
3 : | ; * XVID MPEG-4 VIDEO CODEC | ||
4 : | ; * - MMX and XMM forward discrete cosine transform - | ||
5 : | ; * | ||
6 : | ; * Copyright(C) 2002 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 : | edgomez | 1.5 | %ifdef MARK_FUNCS |
31 : | edgomez | 1.6 | global _%1:function %1.endfunc-%1 |
32 : | %define %1 _%1:function %1.endfunc-%1 | ||
33 : | edgomez | 1.5 | %else |
34 : | global _%1 | ||
35 : | %define %1 _%1 | ||
36 : | %endif | ||
37 : | edgomez | 1.2 | %else |
38 : | edgomez | 1.5 | %ifdef MARK_FUNCS |
39 : | edgomez | 1.6 | global %1:function %1.endfunc-%1 |
40 : | edgomez | 1.5 | %else |
41 : | global %1 | ||
42 : | %endif | ||
43 : | edgomez | 1.2 | %endif |
44 : | %endmacro | ||
45 : | |||
46 : | ;;; Define this if you want an unrolled version of the code | ||
47 : | %define UNROLLED_LOOP | ||
48 : | |||
49 : | ;============================================================================= | ||
50 : | ; | ||
51 : | ; Vertical pass is an implementation of the scheme: | ||
52 : | ; Loeffler C., Ligtenberg A., and Moschytz C.S.: | ||
53 : | ; Practical Fast 1D DCT Algorithm with Eleven Multiplications, | ||
54 : | ; Proc. ICASSP 1989, 988-991. | ||
55 : | ; | ||
56 : | ; Horizontal pass is a double 4x4 vector/matrix multiplication, | ||
57 : | ; (see also Intel's Application Note 922: | ||
58 : | ; http://developer.intel.com/vtune/cbts/strmsimd/922down.htm | ||
59 : | ; Copyright (C) 1999 Intel Corporation) | ||
60 : | ; | ||
61 : | ; Notes: | ||
62 : | ; * tan(3pi/16) is greater than 0.5, and would use the | ||
63 : | ; sign bit when turned into 16b fixed-point precision. So, | ||
64 : | ; we use the trick: x*tan3 = x*(tan3-1)+x | ||
65 : | ; | ||
66 : | ; * There's only one SSE-specific instruction (pshufw). | ||
67 : | ; Porting to SSE2 also seems straightforward. | ||
68 : | ; | ||
69 : | ; * There's still 1 or 2 ticks to save in fLLM_PASS, but | ||
70 : | ; I prefer having a readable code, instead of a tightly | ||
71 : | ; scheduled one... | ||
72 : | ; | ||
73 : | ; * Quantization stage (as well as pre-transposition for the | ||
74 : | ; idct way back) can be included in the fTab* constants | ||
75 : | ; (with induced loss of precision, somehow) | ||
76 : | ; | ||
77 : | ; * Some more details at: http://skal.planet-d.net/coding/dct.html | ||
78 : | ; | ||
79 : | ;============================================================================= | ||
80 : | ; | ||
81 : | ; idct-like IEEE errors: | ||
82 : | ; | ||
83 : | ; ========================= | ||
84 : | ; Peak error: 1.0000 | ||
85 : | ; Peak MSE: 0.0365 | ||
86 : | ; Overall MSE: 0.0201 | ||
87 : | ; Peak ME: 0.0265 | ||
88 : | ; Overall ME: 0.0006 | ||
89 : | ; | ||
90 : | ; == Mean square errors == | ||
91 : | ; 0.000 0.001 0.001 0.002 0.000 0.002 0.001 0.000 [0.001] | ||
92 : | ; 0.035 0.029 0.032 0.032 0.031 0.032 0.034 0.035 [0.032] | ||
93 : | ; 0.026 0.028 0.027 0.027 0.025 0.028 0.028 0.025 [0.027] | ||
94 : | ; 0.037 0.032 0.031 0.030 0.028 0.029 0.026 0.031 [0.030] | ||
95 : | ; 0.000 0.001 0.001 0.002 0.000 0.002 0.001 0.001 [0.001] | ||
96 : | ; 0.025 0.024 0.022 0.022 0.022 0.022 0.023 0.023 [0.023] | ||
97 : | ; 0.026 0.028 0.025 0.028 0.030 0.025 0.026 0.027 [0.027] | ||
98 : | ; 0.021 0.020 0.020 0.022 0.020 0.022 0.017 0.019 [0.020] | ||
99 : | ; | ||
100 : | ; == Abs Mean errors == | ||
101 : | ; 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 [0.000] | ||
102 : | ; 0.020 0.001 0.003 0.003 0.000 0.004 0.002 0.003 [0.002] | ||
103 : | ; 0.000 0.001 0.001 0.001 0.001 0.004 0.000 0.000 [0.000] | ||
104 : | ; 0.027 0.001 0.000 0.002 0.002 0.002 0.001 0.000 [0.003] | ||
105 : | ; 0.000 0.000 0.000 0.000 0.000 0.001 0.000 0.001 [-0.000] | ||
106 : | ; 0.001 0.003 0.001 0.001 0.002 0.001 0.000 0.000 [-0.000] | ||
107 : | ; 0.000 0.002 0.002 0.001 0.001 0.002 0.001 0.000 [-0.000] | ||
108 : | ; 0.000 0.002 0.001 0.002 0.001 0.002 0.001 0.001 [-0.000] | ||
109 : | ; | ||
110 : | ;============================================================================= | ||
111 : | |||
112 : | ;============================================================================= | ||
113 : | ; Read only data | ||
114 : | ;============================================================================= | ||
115 : | |||
116 : | %ifdef FORMAT_COFF | ||
117 : | edgomez | 1.3 | SECTION .rodata |
118 : | edgomez | 1.2 | %else |
119 : | edgomez | 1.3 | SECTION .rodata align=16 |
120 : | edgomez | 1.2 | %endif |
121 : | |||
122 : | ALIGN 16 | ||
123 : | tan1: | ||
124 : | dw 0x32ec,0x32ec,0x32ec,0x32ec ; tan( pi/16) | ||
125 : | tan2: | ||
126 : | dw 0x6a0a,0x6a0a,0x6a0a,0x6a0a ; tan(2pi/16) (=sqrt(2)-1) | ||
127 : | tan3: | ||
128 : | dw 0xab0e,0xab0e,0xab0e,0xab0e ; tan(3pi/16)-1 | ||
129 : | sqrt2: | ||
130 : | dw 0x5a82,0x5a82,0x5a82,0x5a82 ; 0.5/sqrt(2) | ||
131 : | |||
132 : | ALIGN 16 | ||
133 : | fdct_table: | ||
134 : | ;fTab1: | ||
135 : | dw 0x4000, 0x4000, 0x58c5, 0x4b42 | ||
136 : | dw 0x4000, 0x4000, 0x3249, 0x11a8 | ||
137 : | dw 0x539f, 0x22a3, 0x4b42, 0xee58 | ||
138 : | dw 0xdd5d, 0xac61, 0xa73b, 0xcdb7 | ||
139 : | dw 0x4000, 0xc000, 0x3249, 0xa73b | ||
140 : | dw 0xc000, 0x4000, 0x11a8, 0x4b42 | ||
141 : | dw 0x22a3, 0xac61, 0x11a8, 0xcdb7 | ||
142 : | dw 0x539f, 0xdd5d, 0x4b42, 0xa73b | ||
143 : | |||
144 : | ;fTab2: | ||
145 : | dw 0x58c5, 0x58c5, 0x7b21, 0x6862 | ||
146 : | dw 0x58c5, 0x58c5, 0x45bf, 0x187e | ||
147 : | dw 0x73fc, 0x300b, 0x6862, 0xe782 | ||
148 : | dw 0xcff5, 0x8c04, 0x84df, 0xba41 | ||
149 : | dw 0x58c5, 0xa73b, 0x45bf, 0x84df | ||
150 : | dw 0xa73b, 0x58c5, 0x187e, 0x6862 | ||
151 : | dw 0x300b, 0x8c04, 0x187e, 0xba41 | ||
152 : | dw 0x73fc, 0xcff5, 0x6862, 0x84df | ||
153 : | |||
154 : | ;fTab3: | ||
155 : | dw 0x539f, 0x539f, 0x73fc, 0x6254 | ||
156 : | dw 0x539f, 0x539f, 0x41b3, 0x1712 | ||
157 : | dw 0x6d41, 0x2d41, 0x6254, 0xe8ee | ||
158 : | dw 0xd2bf, 0x92bf, 0x8c04, 0xbe4d | ||
159 : | dw 0x539f, 0xac61, 0x41b3, 0x8c04 | ||
160 : | dw 0xac61, 0x539f, 0x1712, 0x6254 | ||
161 : | dw 0x2d41, 0x92bf, 0x1712, 0xbe4d | ||
162 : | dw 0x6d41, 0xd2bf, 0x6254, 0x8c04 | ||
163 : | |||
164 : | ;fTab4: | ||
165 : | dw 0x4b42, 0x4b42, 0x6862, 0x587e | ||
166 : | dw 0x4b42, 0x4b42, 0x3b21, 0x14c3 | ||
167 : | dw 0x6254, 0x28ba, 0x587e, 0xeb3d | ||
168 : | dw 0xd746, 0x9dac, 0x979e, 0xc4df | ||
169 : | dw 0x4b42, 0xb4be, 0x3b21, 0x979e | ||
170 : | dw 0xb4be, 0x4b42, 0x14c3, 0x587e | ||
171 : | dw 0x28ba, 0x9dac, 0x14c3, 0xc4df | ||
172 : | dw 0x6254, 0xd746, 0x587e, 0x979e | ||
173 : | |||
174 : | ;fTab1: | ||
175 : | dw 0x4000, 0x4000, 0x58c5, 0x4b42 | ||
176 : | dw 0x4000, 0x4000, 0x3249, 0x11a8 | ||
177 : | dw 0x539f, 0x22a3, 0x4b42, 0xee58 | ||
178 : | dw 0xdd5d, 0xac61, 0xa73b, 0xcdb7 | ||
179 : | dw 0x4000, 0xc000, 0x3249, 0xa73b | ||
180 : | dw 0xc000, 0x4000, 0x11a8, 0x4b42 | ||
181 : | dw 0x22a3, 0xac61, 0x11a8, 0xcdb7 | ||
182 : | dw 0x539f, 0xdd5d, 0x4b42, 0xa73b | ||
183 : | |||
184 : | ;fTab4: | ||
185 : | dw 0x4b42, 0x4b42, 0x6862, 0x587e | ||
186 : | dw 0x4b42, 0x4b42, 0x3b21, 0x14c3 | ||
187 : | dw 0x6254, 0x28ba, 0x587e, 0xeb3d | ||
188 : | dw 0xd746, 0x9dac, 0x979e, 0xc4df | ||
189 : | dw 0x4b42, 0xb4be, 0x3b21, 0x979e | ||
190 : | dw 0xb4be, 0x4b42, 0x14c3, 0x587e | ||
191 : | dw 0x28ba, 0x9dac, 0x14c3, 0xc4df | ||
192 : | dw 0x6254, 0xd746, 0x587e, 0x979e | ||
193 : | |||
194 : | ;fTab3: | ||
195 : | dw 0x539f, 0x539f, 0x73fc, 0x6254 | ||
196 : | dw 0x539f, 0x539f, 0x41b3, 0x1712 | ||
197 : | dw 0x6d41, 0x2d41, 0x6254, 0xe8ee | ||
198 : | dw 0xd2bf, 0x92bf, 0x8c04, 0xbe4d | ||
199 : | dw 0x539f, 0xac61, 0x41b3, 0x8c04 | ||
200 : | dw 0xac61, 0x539f, 0x1712, 0x6254 | ||
201 : | dw 0x2d41, 0x92bf, 0x1712, 0xbe4d | ||
202 : | dw 0x6d41, 0xd2bf, 0x6254, 0x8c04 | ||
203 : | |||
204 : | ;fTab2: | ||
205 : | dw 0x58c5, 0x58c5, 0x7b21, 0x6862 | ||
206 : | dw 0x58c5, 0x58c5, 0x45bf, 0x187e | ||
207 : | dw 0x73fc, 0x300b, 0x6862, 0xe782 | ||
208 : | dw 0xcff5, 0x8c04, 0x84df, 0xba41 | ||
209 : | dw 0x58c5, 0xa73b, 0x45bf, 0x84df | ||
210 : | dw 0xa73b, 0x58c5, 0x187e, 0x6862 | ||
211 : | dw 0x300b, 0x8c04, 0x187e, 0xba41 | ||
212 : | dw 0x73fc, 0xcff5, 0x6862, 0x84df | ||
213 : | |||
214 : | ALIGN 16 | ||
215 : | fdct_rounding_1: | ||
216 : | dw 6, 8, 8, 8 | ||
217 : | dw 10, 8, 8, 8 | ||
218 : | dw 8, 8, 8, 8 | ||
219 : | dw 8, 8, 8, 8 | ||
220 : | dw 6, 8, 8, 8 | ||
221 : | dw 8, 8, 8, 8 | ||
222 : | dw 8, 8, 8, 8 | ||
223 : | dw 8, 8, 8, 8 | ||
224 : | |||
225 : | ALIGN 16 | ||
226 : | fdct_rounding_2: | ||
227 : | dw 6, 8, 8, 8 | ||
228 : | dw 8, 8, 8, 8 | ||
229 : | dw 8, 8, 8, 8 | ||
230 : | dw 8, 8, 8, 8 | ||
231 : | dw 6, 8, 8, 8 | ||
232 : | dw 8, 8, 8, 8 | ||
233 : | dw 8, 8, 8, 8 | ||
234 : | dw 8, 8, 8, 8 | ||
235 : | |||
236 : | ALIGN 16 | ||
237 : | MMX_One: | ||
238 : | dw 1, 1, 1, 1 | ||
239 : | |||
240 : | ;============================================================================= | ||
241 : | ; Helper Macros for real code | ||
242 : | ;============================================================================= | ||
243 : | |||
244 : | ;----------------------------------------------------------------------------- | ||
245 : | ; FDCT LLM vertical pass (~39c) | ||
246 : | ; %1=dst, %2=src, %3:Shift | ||
247 : | ;----------------------------------------------------------------------------- | ||
248 : | |||
249 : | %macro fLLM_PASS 3 | ||
250 : | movq mm0, [%2+0*16] ; In0 | ||
251 : | movq mm2, [%2+2*16] ; In2 | ||
252 : | movq mm3, mm0 | ||
253 : | movq mm4, mm2 | ||
254 : | movq mm7, [%2+7*16] ; In7 | ||
255 : | movq mm5, [%2+5*16] ; In5 | ||
256 : | |||
257 : | psubsw mm0, mm7 ; t7 = In0-In7 | ||
258 : | paddsw mm7, mm3 ; t0 = In0+In7 | ||
259 : | psubsw mm2, mm5 ; t5 = In2-In5 | ||
260 : | paddsw mm5, mm4 ; t2 = In2+In5 | ||
261 : | |||
262 : | movq mm3, [%2+3*16] ; In3 | ||
263 : | movq mm4, [%2+4*16] ; In4 | ||
264 : | movq mm1, mm3 | ||
265 : | psubsw mm3, mm4 ; t4 = In3-In4 | ||
266 : | paddsw mm4, mm1 ; t3 = In3+In4 | ||
267 : | movq mm6, [%2+6*16] ; In6 | ||
268 : | movq mm1, [%2+1*16] ; In1 | ||
269 : | psubsw mm1, mm6 ; t6 = In1-In6 | ||
270 : | paddsw mm6, [%2+1*16] ; t1 = In1+In6 | ||
271 : | |||
272 : | psubsw mm7, mm4 ; tm03 = t0-t3 | ||
273 : | psubsw mm6, mm5 ; tm12 = t1-t2 | ||
274 : | paddsw mm4, mm4 ; 2.t3 | ||
275 : | paddsw mm5, mm5 ; 2.t2 | ||
276 : | paddsw mm4, mm7 ; tp03 = t0+t3 | ||
277 : | paddsw mm5, mm6 ; tp12 = t1+t2 | ||
278 : | |||
279 : | psllw mm2, %3+1 ; shift t5 (shift +1 to.. | ||
280 : | psllw mm1, %3+1 ; shift t6 ..compensate cos4/2) | ||
281 : | psllw mm4, %3 ; shift t3 | ||
282 : | psllw mm5, %3 ; shift t2 | ||
283 : | psllw mm7, %3 ; shift t0 | ||
284 : | psllw mm6, %3 ; shift t1 | ||
285 : | psllw mm3, %3 ; shift t4 | ||
286 : | psllw mm0, %3 ; shift t7 | ||
287 : | |||
288 : | psubsw mm4, mm5 ; out4 = tp03-tp12 | ||
289 : | psubsw mm1, mm2 ; mm1: t6-t5 | ||
290 : | paddsw mm5, mm5 | ||
291 : | paddsw mm2, mm2 | ||
292 : | paddsw mm5, mm4 ; out0 = tp03+tp12 | ||
293 : | movq [%1+4*16], mm4 ; => out4 | ||
294 : | paddsw mm2, mm1 ; mm2: t6+t5 | ||
295 : | movq [%1+0*16], mm5 ; => out0 | ||
296 : | |||
297 : | movq mm4, [tan2] ; mm4 <= tan2 | ||
298 : | pmulhw mm4, mm7 ; tm03*tan2 | ||
299 : | movq mm5, [tan2] ; mm5 <= tan2 | ||
300 : | psubsw mm4, mm6 ; out6 = tm03*tan2 - tm12 | ||
301 : | pmulhw mm5, mm6 ; tm12*tan2 | ||
302 : | paddsw mm5, mm7 ; out2 = tm12*tan2 + tm03 | ||
303 : | |||
304 : | movq mm6, [sqrt2] | ||
305 : | movq mm7, [MMX_One] | ||
306 : | |||
307 : | pmulhw mm2, mm6 ; mm2: tp65 = (t6 + t5)*cos4 | ||
308 : | por mm5, mm7 ; correct out2 | ||
309 : | por mm4, mm7 ; correct out6 | ||
310 : | pmulhw mm1, mm6 ; mm1: tm65 = (t6 - t5)*cos4 | ||
311 : | por mm2, mm7 ; correct tp65 | ||
312 : | |||
313 : | movq [%1+2*16], mm5 ; => out2 | ||
314 : | movq mm5, mm3 ; save t4 | ||
315 : | movq [%1+6*16], mm4 ; => out6 | ||
316 : | movq mm4, mm0 ; save t7 | ||
317 : | |||
318 : | psubsw mm3, mm1 ; mm3: tm465 = t4 - tm65 | ||
319 : | psubsw mm0, mm2 ; mm0: tm765 = t7 - tp65 | ||
320 : | paddsw mm2, mm4 ; mm2: tp765 = t7 + tp65 | ||
321 : | paddsw mm1, mm5 ; mm1: tp465 = t4 + tm65 | ||
322 : | |||
323 : | movq mm4, [tan3] ; tan3 - 1 | ||
324 : | movq mm5, [tan1] ; tan1 | ||
325 : | |||
326 : | movq mm7, mm3 ; save tm465 | ||
327 : | pmulhw mm3, mm4 ; tm465*(tan3-1) | ||
328 : | movq mm6, mm1 ; save tp465 | ||
329 : | pmulhw mm1, mm5 ; tp465*tan1 | ||
330 : | |||
331 : | paddsw mm3, mm7 ; tm465*tan3 | ||
332 : | pmulhw mm4, mm0 ; tm765*(tan3-1) | ||
333 : | paddsw mm4, mm0 ; tm765*tan3 | ||
334 : | pmulhw mm5, mm2 ; tp765*tan1 | ||
335 : | |||
336 : | paddsw mm1, mm2 ; out1 = tp765 + tp465*tan1 | ||
337 : | psubsw mm0, mm3 ; out3 = tm765 - tm465*tan3 | ||
338 : | paddsw mm7, mm4 ; out5 = tm465 + tm765*tan3 | ||
339 : | psubsw mm5, mm6 ; out7 =-tp465 + tp765*tan1 | ||
340 : | |||
341 : | movq [%1+1*16], mm1 ; => out1 | ||
342 : | movq [%1+3*16], mm0 ; => out3 | ||
343 : | movq [%1+5*16], mm7 ; => out5 | ||
344 : | movq [%1+7*16], mm5 ; => out7 | ||
345 : | %endmacro | ||
346 : | |||
347 : | ;----------------------------------------------------------------------------- | ||
348 : | ; fMTX_MULT_XMM (~20c) | ||
349 : | ; %1=dst, %2=src, %3 = Coeffs, %4/%5=rounders | ||
350 : | ;----------------------------------------------------------------------------- | ||
351 : | |||
352 : | %macro fMTX_MULT_XMM 5 | ||
353 : | movq mm0, [%2 + 0] ; mm0 = [0123] | ||
354 : | ; the 'pshufw' below is the only SSE instruction. | ||
355 : | ; For MMX-only version, it should be emulated with | ||
356 : | ; some 'punpck' soup... | ||
357 : | pshufw mm1, [%2 + 8], 00011011b ; mm1 = [7654] | ||
358 : | movq mm7, mm0 | ||
359 : | |||
360 : | paddsw mm0, mm1 ; mm0 = [a0 a1 a2 a3] | ||
361 : | psubsw mm7, mm1 ; mm7 = [b0 b1 b2 b3] | ||
362 : | |||
363 : | movq mm1, mm0 | ||
364 : | punpckldq mm0, mm7 ; mm0 = [a0 a1 b0 b1] | ||
365 : | punpckhdq mm1, mm7 ; mm1 = [b2 b3 a2 a3] | ||
366 : | |||
367 : | movq mm2, qword [%3 + 0] ; [ M00 M01 M16 M17] | ||
368 : | movq mm3, qword [%3 + 8] ; [ M02 M03 M18 M19] | ||
369 : | pmaddwd mm2, mm0 ; [a0.M00+a1.M01 | b0.M16+b1.M17] | ||
370 : | movq mm4, qword [%3 + 16] ; [ M04 M05 M20 M21] | ||
371 : | pmaddwd mm3, mm1 ; [a2.M02+a3.M03 | b2.M18+b3.M19] | ||
372 : | movq mm5, qword [%3 + 24] ; [ M06 M07 M22 M23] | ||
373 : | pmaddwd mm4, mm0 ; [a0.M04+a1.M05 | b0.M20+b1.M21] | ||
374 : | movq mm6, qword [%3 + 32] ; [ M08 M09 M24 M25] | ||
375 : | pmaddwd mm5, mm1 ; [a2.M06+a3.M07 | b2.M22+b3.M23] | ||
376 : | movq mm7, qword [%3 + 40] ; [ M10 M11 M26 M27] | ||
377 : | pmaddwd mm6, mm0 ; [a0.M08+a1.M09 | b0.M24+b1.M25] | ||
378 : | paddd mm2, mm3 ; [ out0 | out1 ] | ||
379 : | pmaddwd mm7, mm1 ; [a0.M10+a1.M11 | b0.M26+b1.M27] | ||
380 : | psrad mm2, 16 | ||
381 : | pmaddwd mm0, qword [%3 + 48] ; [a0.M12+a1.M13 | b0.M28+b1.M29] | ||
382 : | paddd mm4, mm5 ; [ out2 | out3 ] | ||
383 : | pmaddwd mm1, qword [%3 + 56] ; [a0.M14+a1.M15 | b0.M30+b1.M31] | ||
384 : | psrad mm4, 16 | ||
385 : | |||
386 : | paddd mm6, mm7 ; [ out4 | out5 ] | ||
387 : | psrad mm6, 16 | ||
388 : | paddd mm0, mm1 ; [ out6 | out7 ] | ||
389 : | psrad mm0, 16 | ||
390 : | |||
391 : | packssdw mm2, mm4 ; [ out0|out1|out2|out3 ] | ||
392 : | paddsw mm2, [%4] ; Round | ||
393 : | packssdw mm6, mm0 ; [ out4|out5|out6|out7 ] | ||
394 : | paddsw mm6, [%5] ; Round | ||
395 : | |||
396 : | psraw mm2, 4 ; => [-2048, 2047] | ||
397 : | psraw mm6, 4 | ||
398 : | |||
399 : | movq [%1 + 0], mm2 | ||
400 : | movq [%1 + 8], mm6 | ||
401 : | %endmacro | ||
402 : | |||
403 : | ;----------------------------------------------------------------------------- | ||
404 : | ; fMTX_MULT_MMX (~22c) | ||
405 : | ; %1=dst, %2=src, %3 = Coeffs, %4/%5=rounders | ||
406 : | ;----------------------------------------------------------------------------- | ||
407 : | |||
408 : | %macro fMTX_MULT_MMX 5 | ||
409 : | ; MMX-only version (no 'pshufw'. ~10% overall slower than SSE) | ||
410 : | movd mm1, [%2 + 8 + 4] ; [67..] | ||
411 : | movq mm0, [%2 + 0] ; mm0 = [0123] | ||
412 : | movq mm7, mm0 | ||
413 : | punpcklwd mm1, [%2 + 8] ; [6475] | ||
414 : | movq mm2, mm1 | ||
415 : | psrlq mm1, 32 ; [75..] | ||
416 : | punpcklwd mm1,mm2 ; [7654] | ||
417 : | |||
418 : | paddsw mm0, mm1 ; mm0 = [a0 a1 a2 a3] | ||
419 : | psubsw mm7, mm1 ; mm7 = [b0 b1 b2 b3] | ||
420 : | |||
421 : | movq mm1, mm0 | ||
422 : | punpckldq mm0, mm7 ; mm0 = [a0 a1 b0 b1] | ||
423 : | punpckhdq mm1, mm7 ; mm1 = [b2 b3 a2 a3] | ||
424 : | |||
425 : | movq mm2, qword [%3 + 0] ; [ M00 M01 M16 M17] | ||
426 : | movq mm3, qword [%3 + 8] ; [ M02 M03 M18 M19] | ||
427 : | pmaddwd mm2, mm0 ; [a0.M00+a1.M01 | b0.M16+b1.M17] | ||
428 : | movq mm4, qword [%3 + 16] ; [ M04 M05 M20 M21] | ||
429 : | pmaddwd mm3, mm1 ; [a2.M02+a3.M03 | b2.M18+b3.M19] | ||
430 : | movq mm5, qword [%3 + 24] ; [ M06 M07 M22 M23] | ||
431 : | pmaddwd mm4, mm0 ; [a0.M04+a1.M05 | b0.M20+b1.M21] | ||
432 : | movq mm6, qword [%3 + 32] ; [ M08 M09 M24 M25] | ||
433 : | pmaddwd mm5, mm1 ; [a2.M06+a3.M07 | b2.M22+b3.M23] | ||
434 : | movq mm7, qword [%3 + 40] ; [ M10 M11 M26 M27] | ||
435 : | pmaddwd mm6, mm0 ; [a0.M08+a1.M09 | b0.M24+b1.M25] | ||
436 : | paddd mm2, mm3 ; [ out0 | out1 ] | ||
437 : | pmaddwd mm7, mm1 ; [a0.M10+a1.M11 | b0.M26+b1.M27] | ||
438 : | psrad mm2, 16 | ||
439 : | pmaddwd mm0, qword [%3 + 48] ; [a0.M12+a1.M13 | b0.M28+b1.M29] | ||
440 : | paddd mm4, mm5 ; [ out2 | out3 ] | ||
441 : | pmaddwd mm1, qword [%3 + 56] ; [a0.M14+a1.M15 | b0.M30+b1.M31] | ||
442 : | psrad mm4, 16 | ||
443 : | |||
444 : | paddd mm6, mm7 ; [ out4 | out5 ] | ||
445 : | psrad mm6, 16 | ||
446 : | paddd mm0, mm1 ; [ out6 | out7 ] | ||
447 : | psrad mm0, 16 | ||
448 : | |||
449 : | packssdw mm2, mm4 ; [ out0|out1|out2|out3 ] | ||
450 : | paddsw mm2, [%4] ; Round | ||
451 : | packssdw mm6, mm0 ; [ out4|out5|out6|out7 ] | ||
452 : | paddsw mm6, [%5] ; Round | ||
453 : | |||
454 : | psraw mm2, 4 ; => [-2048, 2047] | ||
455 : | psraw mm6, 4 | ||
456 : | |||
457 : | movq [%1 + 0], mm2 | ||
458 : | movq [%1 + 8], mm6 | ||
459 : | %endmacro | ||
460 : | |||
461 : | ;----------------------------------------------------------------------------- | ||
462 : | ; MAKE_FDCT_FUNC | ||
463 : | ; %1 funcname, %2 macro for row dct | ||
464 : | ;----------------------------------------------------------------------------- | ||
465 : | |||
466 : | %macro MAKE_FDCT_FUNC 2 | ||
467 : | ALIGN 16 | ||
468 : | cglobal %1 | ||
469 : | %1: | ||
470 : | %ifdef UNROLLED_LOOP | ||
471 : | mov ecx, [esp + 4] | ||
472 : | %else | ||
473 : | push ebx | ||
474 : | push edi | ||
475 : | mov ecx, [esp + 8 + 4] | ||
476 : | %endif | ||
477 : | |||
478 : | fLLM_PASS ecx+0, ecx+0, 3 | ||
479 : | fLLM_PASS ecx+8, ecx+8, 3 | ||
480 : | |||
481 : | %ifdef UNROLLED_LOOP | ||
482 : | %assign i 0 | ||
483 : | %rep 8 | ||
484 : | %2 ecx+i*16, ecx+i*16, fdct_table+i*64, fdct_rounding_1+i*8, fdct_rounding_2+i*8 | ||
485 : | %assign i i+1 | ||
486 : | %endrep | ||
487 : | %else | ||
488 : | mov eax, 8 | ||
489 : | mov edx, fdct_table | ||
490 : | mov ebx, fdct_rounding_1 | ||
491 : | mov edi, fdct_rounding_2 | ||
492 : | .loop | ||
493 : | %2 ecx, ecx, edx, ebx, edi | ||
494 : | edgomez | 1.4 | add ecx, 2*8 |
495 : | edgomez | 1.2 | add edx, 2*32 |
496 : | add ebx, 2*4 | ||
497 : | add edi, 2*4 | ||
498 : | dec eax | ||
499 : | jne .loop | ||
500 : | |||
501 : | pop edi | ||
502 : | pop ebx | ||
503 : | %endif | ||
504 : | |||
505 : | ret | ||
506 : | edgomez | 1.6 | .endfunc |
507 : | edgomez | 1.2 | %endmacro |
508 : | |||
509 : | ;============================================================================= | ||
510 : | ; Code | ||
511 : | ;============================================================================= | ||
512 : | |||
513 : | SECTION .text | ||
514 : | |||
515 : | ;----------------------------------------------------------------------------- | ||
516 : | ; void fdct_mmx_skal(int16_t block[64]]; | ||
517 : | ;----------------------------------------------------------------------------- | ||
518 : | |||
519 : | MAKE_FDCT_FUNC fdct_mmx_skal, fMTX_MULT_MMX | ||
520 : | |||
521 : | ;----------------------------------------------------------------------------- | ||
522 : | ; void fdct_xmm_skal(int16_t block[64]]; | ||
523 : | ;----------------------------------------------------------------------------- | ||
524 : | |||
525 : | MAKE_FDCT_FUNC fdct_xmm_skal, fMTX_MULT_XMM |
No admin address has been configured | ViewVC Help |
Powered by ViewVC 1.0.4 |