[svn] / trunk / xvidcore / src / image / x86_asm / qpel_mmx.asm Repository:
ViewVC logotype

Annotation of /trunk/xvidcore/src/image/x86_asm/qpel_mmx.asm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1790 - (view) (download)

1 : edgomez 1382 ;/*****************************************************************************
2 :     ; *
3 :     ; * XVID MPEG-4 VIDEO CODEC
4 :     ; * - Quarter-pixel interpolation -
5 :     ; * Copyright(C) 2002 Pascal Massimino <skal@planet-d.net>
6 :     ; *
7 :     ; * This file is part of XviD, a free MPEG-4 video encoder/decoder
8 :     ; *
9 :     ; * XviD is free software; you can redistribute it and/or modify it
10 :     ; * under the terms of the GNU General Public License as published by
11 :     ; * the Free Software Foundation; either version 2 of the License, or
12 :     ; * (at your option) any later version.
13 :     ; *
14 :     ; * This program is distributed in the hope that it will be useful,
15 :     ; * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 :     ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 :     ; * GNU General Public License for more details.
18 :     ; *
19 :     ; * You should have received a copy of the GNU General Public License
20 :     ; * along with this program; if not, write to the Free Software
21 :     ; * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 :     ; *
23 : Isibaar 1790 ; * $Id: qpel_mmx.asm,v 1.6 2008-08-19 09:06:48 Isibaar Exp $
24 : edgomez 1382 ; *
25 :     ; *************************************************************************/
26 :    
27 :     ;/**************************************************************************
28 :     ; *
29 :     ; * History:
30 :     ; *
31 :     ; * 22.10.2002 initial coding. unoptimized 'proof of concept',
32 :     ; * just to heft the qpel filtering. - Skal -
33 :     ; *
34 :     ; *************************************************************************/
35 :    
36 :    
37 :     %define USE_TABLES ; in order to use xvid_FIR_x_x_x_x tables
38 :     ; instead of xvid_Expand_mmx...
39 :    
40 :    
41 :     bits 32
42 :    
43 :     %macro cglobal 1
44 :     %ifdef PREFIX
45 : edgomez 1535 %ifdef MARK_FUNCS
46 : edgomez 1540 global _%1:function %1.endfunc-%1
47 :     %define %1 _%1:function %1.endfunc-%1
48 : edgomez 1535 %else
49 :     global _%1
50 :     %define %1 _%1
51 :     %endif
52 : edgomez 1382 %else
53 : edgomez 1535 %ifdef MARK_FUNCS
54 : edgomez 1540 global %1:function %1.endfunc-%1
55 : edgomez 1535 %else
56 :     global %1
57 :     %endif
58 : edgomez 1382 %endif
59 :     %endmacro
60 :     %macro cextern 1
61 :     %ifdef PREFIX
62 :     extern _%1
63 :     %define %1 _%1
64 :     %else
65 :     extern %1
66 :     %endif
67 :     %endmacro
68 :    
69 :    
70 :     ;//////////////////////////////////////////////////////////////////////
71 :     ;// Declarations
72 :     ;// all signatures are:
73 :     ;// void XXX(uint8_t *dst, const uint8_t *src,
74 :     ;// int32_t length, int32_t stride, int32_t rounding)
75 :     ;//////////////////////////////////////////////////////////////////////
76 :    
77 :     cglobal xvid_H_Pass_16_mmx
78 :     cglobal xvid_H_Pass_Avrg_16_mmx
79 :     cglobal xvid_H_Pass_Avrg_Up_16_mmx
80 :     cglobal xvid_V_Pass_16_mmx
81 :     cglobal xvid_V_Pass_Avrg_16_mmx
82 :     cglobal xvid_V_Pass_Avrg_Up_16_mmx
83 :     cglobal xvid_H_Pass_8_mmx
84 :     cglobal xvid_H_Pass_Avrg_8_mmx
85 :     cglobal xvid_H_Pass_Avrg_Up_8_mmx
86 :     cglobal xvid_V_Pass_8_mmx
87 :     cglobal xvid_V_Pass_Avrg_8_mmx
88 :     cglobal xvid_V_Pass_Avrg_Up_8_mmx
89 :    
90 :     cglobal xvid_H_Pass_Add_16_mmx
91 :     cglobal xvid_H_Pass_Avrg_Add_16_mmx
92 :     cglobal xvid_H_Pass_Avrg_Up_Add_16_mmx
93 :     cglobal xvid_V_Pass_Add_16_mmx
94 :     cglobal xvid_V_Pass_Avrg_Add_16_mmx
95 :     cglobal xvid_V_Pass_Avrg_Up_Add_16_mmx
96 :     cglobal xvid_H_Pass_8_Add_mmx
97 :     cglobal xvid_H_Pass_Avrg_8_Add_mmx
98 :     cglobal xvid_H_Pass_Avrg_Up_8_Add_mmx
99 :     cglobal xvid_V_Pass_8_Add_mmx
100 :     cglobal xvid_V_Pass_Avrg_8_Add_mmx
101 :     cglobal xvid_V_Pass_Avrg_Up_8_Add_mmx
102 :    
103 :     cextern xvid_Expand_mmx
104 :    
105 :     %ifdef USE_TABLES
106 :    
107 :     cextern xvid_FIR_1_0_0_0
108 :     cextern xvid_FIR_3_1_0_0
109 :     cextern xvid_FIR_6_3_1_0
110 :     cextern xvid_FIR_14_3_2_1
111 :     cextern xvid_FIR_20_6_3_1
112 :     cextern xvid_FIR_20_20_6_3
113 :     cextern xvid_FIR_23_19_6_3
114 :     cextern xvid_FIR_7_20_20_6
115 :     cextern xvid_FIR_6_20_20_6
116 :     cextern xvid_FIR_6_20_20_7
117 :     cextern xvid_FIR_3_6_20_20
118 :     cextern xvid_FIR_3_6_19_23
119 :     cextern xvid_FIR_1_3_6_20
120 :     cextern xvid_FIR_1_2_3_14
121 :     cextern xvid_FIR_0_1_3_6
122 :     cextern xvid_FIR_0_0_1_3
123 :     cextern xvid_FIR_0_0_0_1
124 :    
125 :     %endif
126 :    
127 :     ;//////////////////////////////////////////////////////////////////////
128 :    
129 :     %ifdef FORMAT_COFF
130 : edgomez 1519 SECTION .rodata
131 : edgomez 1382 %else
132 : edgomez 1519 SECTION .rodata align=16
133 : edgomez 1382 %endif
134 :    
135 :     align 16
136 :     Rounder1_MMX:
137 :     times 4 dw 1
138 :     Rounder0_MMX:
139 :     times 4 dw 0
140 :    
141 :     align 16
142 :     Rounder_QP_MMX
143 :     times 4 dw 16
144 :     times 4 dw 15
145 :    
146 :     %ifndef USE_TABLES
147 :    
148 :     align 16
149 :    
150 :     ; H-Pass table shared by 16x? and 8x? filters
151 :    
152 :     FIR_R0: dw 14, -3, 2, -1
153 :     align 16
154 :     FIR_R1: dw 23, 19, -6, 3, -1, 0, 0, 0
155 :    
156 :     FIR_R2: dw -7, 20, 20, -6, 3, -1, 0, 0
157 :    
158 :     FIR_R3: dw 3, -6, 20, 20, -6, 3, -1, 0
159 :    
160 :     FIR_R4: dw -1, 3, -6, 20, 20, -6, 3, -1
161 :    
162 :     FIR_R5: dw 0, -1, 3, -6, 20, 20, -6, 3, -1, 0, 0, 0
163 :     align 16
164 :     FIR_R6: dw 0, 0, -1, 3, -6, 20, 20, -6, 3, -1, 0, 0
165 :     align 16
166 :     FIR_R7: dw 0, 0, 0, -1, 3, -6, 20, 20, -6, 3, -1, 0
167 :     align 16
168 :     FIR_R8: dw -1, 3, -6, 20, 20, -6, 3, -1
169 :    
170 :     FIR_R9: dw 0, -1, 3, -6, 20, 20, -6, 3, -1, 0, 0, 0
171 :     align 16
172 :     FIR_R10: dw 0, 0, -1, 3, -6, 20, 20, -6, 3, -1, 0, 0
173 :     align 16
174 :     FIR_R11: dw 0, 0, 0, -1, 3, -6, 20, 20, -6, 3, -1, 0
175 :     align 16
176 :     FIR_R12: dw -1, 3, -6, 20, 20, -6, 3, -1
177 :    
178 :     FIR_R13: dw 0, -1, 3, -6, 20, 20, -6, 3
179 :    
180 :     FIR_R14: dw 0, 0, -1, 3, -6, 20, 20, -7
181 :    
182 :     FIR_R15: dw 0, 0, 0, -1, 3, -6, 19, 23
183 :    
184 :     FIR_R16: dw -1, 2, -3, 14
185 :    
186 :     %endif ; !USE_TABLES
187 :    
188 :     ; V-Pass taps
189 :    
190 :     align 16
191 :     FIR_Cm7: times 4 dw -7
192 :     FIR_Cm6: times 4 dw -6
193 :     FIR_Cm3: times 4 dw -3
194 :     FIR_Cm1: times 4 dw -1
195 :     FIR_C2: times 4 dw 2
196 :     FIR_C3: times 4 dw 3
197 :     FIR_C14: times 4 dw 14
198 :     FIR_C19: times 4 dw 19
199 :     FIR_C20: times 4 dw 20
200 :     FIR_C23: times 4 dw 23
201 :    
202 :     SECTION .text
203 :    
204 :     ;//////////////////////////////////////////////////////////////////////
205 :     ;// Here we go with the Q-Pel mess.
206 :     ;// For horizontal passes, we process 4 *output* pixel in parallel
207 :     ;// For vertical ones, we process 4 *input* pixel in parallel.
208 :     ;//////////////////////////////////////////////////////////////////////
209 :    
210 :     %macro PROLOG_NO_AVRG 0
211 :     push esi
212 :     push edi
213 :     push ebp
214 :     mov edi, [esp+16 + 0*4] ; Dst
215 :     mov esi, [esp+16 + 1*4] ; Src
216 :     mov ecx, [esp+16 + 2*4] ; Size
217 :     mov ebp, [esp+16 + 3*4] ; BpS
218 :     mov eax, [esp+16 + 4*4] ; Rnd
219 :     and eax, 1
220 :     movq mm7, [Rounder_QP_MMX+eax*8] ; rounder
221 :     %endmacro
222 :    
223 :     %macro EPILOG_NO_AVRG 0
224 :     pop ebp
225 :     pop edi
226 :     pop esi
227 :     ret
228 :     %endmacro
229 :    
230 :     %macro PROLOG_AVRG 0
231 :     push ebx
232 :     push esi
233 :     push edi
234 :     push ebp
235 :     mov edi, [esp+20 + 0*4] ; Dst
236 :     mov esi, [esp+20 + 1*4] ; Src
237 :     mov ecx, [esp+20 + 2*4] ; Size
238 :     mov ebp, [esp+20 + 3*4] ; BpS
239 :     mov eax, [esp+20 + 4*4] ; Rnd
240 :     and eax, 1
241 :     movq mm7, [Rounder_QP_MMX+eax*8] ; rounder
242 :     lea ebx, [Rounder1_MMX+eax*8] ; *Rounder2
243 :     %endmacro
244 :    
245 :     %macro EPILOG_AVRG 0
246 :     pop ebp
247 :     pop edi
248 :     pop esi
249 :     pop ebx
250 :     ret
251 :     %endmacro
252 :    
253 :     ;//////////////////////////////////////////////////////////////////////
254 :     ;//
255 :     ;// All horizontal passes
256 :     ;//
257 :     ;//////////////////////////////////////////////////////////////////////
258 :    
259 :     ; macros for USE_TABLES
260 :    
261 :     %macro TLOAD 2 ; %1,%2: src pixels
262 :     movzx eax, byte [esi+%1]
263 :     movzx edx, byte [esi+%2]
264 :     movq mm0, [xvid_FIR_14_3_2_1 + eax*8 ]
265 :     movq mm3, [xvid_FIR_1_2_3_14 + edx*8 ]
266 :     paddw mm0, mm7
267 :     paddw mm3, mm7
268 :     %endmacro
269 :    
270 :     %macro TACCUM2 5 ;%1:src pixel/%2-%3:Taps tables/ %4-%5:dst regs
271 :     movzx eax, byte [esi+%1]
272 :     paddw %4, [%2 + eax*8]
273 :     paddw %5, [%3 + eax*8]
274 :     %endmacro
275 :    
276 :     %macro TACCUM3 7 ;%1:src pixel/%2-%4:Taps tables/%5-%7:dst regs
277 :     movzx eax, byte [esi+%1]
278 :     paddw %5, [%2 + eax*8]
279 :     paddw %6, [%3 + eax*8]
280 :     paddw %7, [%4 + eax*8]
281 :     %endmacro
282 :    
283 :     ;//////////////////////////////////////////////////////////////////////
284 :    
285 :     ; macros without USE_TABLES
286 :    
287 :     %macro LOAD 2 ; %1,%2: src pixels
288 :     movzx eax, byte [esi+%1]
289 :     movzx edx, byte [esi+%2]
290 :     movq mm0, [xvid_Expand_mmx + eax*8]
291 :     movq mm3, [xvid_Expand_mmx + edx*8]
292 :     pmullw mm0, [FIR_R0 ]
293 :     pmullw mm3, [FIR_R16]
294 :     paddw mm0, mm7
295 :     paddw mm3, mm7
296 :     %endmacro
297 :    
298 :     %macro ACCUM2 4 ;src pixel/Taps/dst regs #1-#2
299 :     movzx eax, byte [esi+%1]
300 :     movq mm4, [xvid_Expand_mmx + eax*8]
301 :     movq mm5, mm4
302 :     pmullw mm4, [%2]
303 :     pmullw mm5, [%2+8]
304 :     paddw %3, mm4
305 :     paddw %4, mm5
306 :     %endmacro
307 :    
308 :     %macro ACCUM3 5 ;src pixel/Taps/dst regs #1-#2-#3
309 :     movzx eax, byte [esi+%1]
310 :     movq mm4, [xvid_Expand_mmx + eax*8]
311 :     movq mm5, mm4
312 :     movq mm6, mm5
313 :     pmullw mm4, [%2 ]
314 :     pmullw mm5, [%2+ 8]
315 :     pmullw mm6, [%2+16]
316 :     paddw %3, mm4
317 :     paddw %4, mm5
318 :     paddw %5, mm6
319 :     %endmacro
320 :    
321 :     ;//////////////////////////////////////////////////////////////////////
322 :    
323 :     %macro MIX 3 ; %1:reg, %2:src, %3:rounder
324 :     pxor mm6, mm6
325 :     movq mm4, [%2]
326 :     movq mm1, %1
327 :     movq mm5, mm4
328 :     punpcklbw %1, mm6
329 :     punpcklbw mm4, mm6
330 :     punpckhbw mm1, mm6
331 :     punpckhbw mm5, mm6
332 :     movq mm6, [%3] ; rounder #2
333 :     paddusw %1, mm4
334 :     paddusw mm1, mm5
335 :     paddusw %1, mm6
336 :     paddusw mm1, mm6
337 :     psrlw %1, 1
338 :     psrlw mm1, 1
339 :     packuswb %1, mm1
340 :     %endmacro
341 :    
342 :     ;//////////////////////////////////////////////////////////////////////
343 :    
344 :     %macro H_PASS_16 2 ; %1:src-op (0=NONE,1=AVRG,2=AVRG-UP), %2:dst-op (NONE/AVRG)
345 :    
346 :     %if (%2==0) && (%1==0)
347 :     PROLOG_NO_AVRG
348 :     %else
349 :     PROLOG_AVRG
350 :     %endif
351 :    
352 :     .Loop
353 :    
354 :     ; mm0..mm3 serves as a 4x4 delay line
355 :    
356 :     %ifndef USE_TABLES
357 :    
358 :     LOAD 0, 16 ; special case for 1rst/last pixel
359 :     movq mm1, mm7
360 :     movq mm2, mm7
361 :    
362 :     ACCUM2 1, FIR_R1, mm0, mm1
363 :     ACCUM2 2, FIR_R2, mm0, mm1
364 :     ACCUM2 3, FIR_R3, mm0, mm1
365 :     ACCUM2 4, FIR_R4, mm0, mm1
366 :    
367 :     ACCUM3 5, FIR_R5, mm0, mm1, mm2
368 :     ACCUM3 6, FIR_R6, mm0, mm1, mm2
369 :     ACCUM3 7, FIR_R7, mm0, mm1, mm2
370 :     ACCUM2 8, FIR_R8, mm1, mm2
371 :     ACCUM3 9, FIR_R9, mm1, mm2, mm3
372 :     ACCUM3 10, FIR_R10,mm1, mm2, mm3
373 :     ACCUM3 11, FIR_R11,mm1, mm2, mm3
374 :    
375 :     ACCUM2 12, FIR_R12, mm2, mm3
376 :     ACCUM2 13, FIR_R13, mm2, mm3
377 :     ACCUM2 14, FIR_R14, mm2, mm3
378 :     ACCUM2 15, FIR_R15, mm2, mm3
379 :    
380 :     %else
381 :    
382 :     TLOAD 0, 16 ; special case for 1rst/last pixel
383 :     movq mm1, mm7
384 :     movq mm2, mm7
385 :    
386 :     TACCUM2 1, xvid_FIR_23_19_6_3, xvid_FIR_1_0_0_0 , mm0, mm1
387 :     TACCUM2 2, xvid_FIR_7_20_20_6, xvid_FIR_3_1_0_0 , mm0, mm1
388 :     TACCUM2 3, xvid_FIR_3_6_20_20, xvid_FIR_6_3_1_0 , mm0, mm1
389 :     TACCUM2 4, xvid_FIR_1_3_6_20 , xvid_FIR_20_6_3_1, mm0, mm1
390 :    
391 :     TACCUM3 5, xvid_FIR_0_1_3_6 , xvid_FIR_20_20_6_3, xvid_FIR_1_0_0_0 , mm0, mm1, mm2
392 :     TACCUM3 6, xvid_FIR_0_0_1_3 , xvid_FIR_6_20_20_6, xvid_FIR_3_1_0_0 , mm0, mm1, mm2
393 :     TACCUM3 7, xvid_FIR_0_0_0_1 , xvid_FIR_3_6_20_20, xvid_FIR_6_3_1_0 , mm0, mm1, mm2
394 :    
395 :     TACCUM2 8, xvid_FIR_1_3_6_20 , xvid_FIR_20_6_3_1 , mm1, mm2
396 :    
397 :     TACCUM3 9, xvid_FIR_0_1_3_6 , xvid_FIR_20_20_6_3, xvid_FIR_1_0_0_0, mm1, mm2, mm3
398 :     TACCUM3 10, xvid_FIR_0_0_1_3 , xvid_FIR_6_20_20_6, xvid_FIR_3_1_0_0, mm1, mm2, mm3
399 :     TACCUM3 11, xvid_FIR_0_0_0_1 , xvid_FIR_3_6_20_20, xvid_FIR_6_3_1_0, mm1, mm2, mm3
400 :    
401 :     TACCUM2 12, xvid_FIR_1_3_6_20, xvid_FIR_20_6_3_1 , mm2, mm3
402 :     TACCUM2 13, xvid_FIR_0_1_3_6 , xvid_FIR_20_20_6_3, mm2, mm3
403 :     TACCUM2 14, xvid_FIR_0_0_1_3 , xvid_FIR_6_20_20_7, mm2, mm3
404 :     TACCUM2 15, xvid_FIR_0_0_0_1 , xvid_FIR_3_6_19_23, mm2, mm3
405 :    
406 :     %endif
407 :    
408 :     psraw mm0, 5
409 :     psraw mm1, 5
410 :     psraw mm2, 5
411 :     psraw mm3, 5
412 :     packuswb mm0, mm1
413 :     packuswb mm2, mm3
414 :    
415 :     %if (%1==1)
416 :     MIX mm0, esi, ebx
417 :     %elif (%1==2)
418 :     MIX mm0, esi+1, ebx
419 :     %endif
420 :     %if (%2==1)
421 :     MIX mm0, edi, Rounder1_MMX
422 :     %endif
423 :    
424 :     %if (%1==1)
425 :     MIX mm2, esi+8, ebx
426 :     %elif (%1==2)
427 :     MIX mm2, esi+9, ebx
428 :     %endif
429 :     %if (%2==1)
430 :     MIX mm2, edi+8, Rounder1_MMX
431 :     %endif
432 :    
433 :     lea esi, [esi+ebp]
434 :    
435 :     movq [edi+0], mm0
436 :     movq [edi+8], mm2
437 :    
438 :     add edi, ebp
439 :     dec ecx
440 :     jg .Loop
441 :    
442 :     %if (%2==0) && (%1==0)
443 :     EPILOG_NO_AVRG
444 :     %else
445 :     EPILOG_AVRG
446 :     %endif
447 :    
448 :     %endmacro
449 :    
450 :    
451 :     ;//////////////////////////////////////////////////////////////////////
452 :    
453 :     %macro H_PASS_8 2 ; %1:src-op (0=NONE,1=AVRG,2=AVRG-UP), %2:dst-op (NONE/AVRG)
454 :    
455 :     %if (%2==0) && (%1==0)
456 :     PROLOG_NO_AVRG
457 :     %else
458 :     PROLOG_AVRG
459 :     %endif
460 :    
461 :     .Loop
462 :     ; mm0..mm3 serves as a 4x4 delay line
463 :    
464 :     %ifndef USE_TABLES
465 :    
466 :     LOAD 0, 8 ; special case for 1rst/last pixel
467 :     ACCUM2 1, FIR_R1, mm0, mm3
468 :     ACCUM2 2, FIR_R2, mm0, mm3
469 :     ACCUM2 3, FIR_R3, mm0, mm3
470 :     ACCUM2 4, FIR_R4, mm0, mm3
471 :    
472 :     ACCUM2 5, FIR_R13, mm0, mm3
473 :     ACCUM2 6, FIR_R14, mm0, mm3
474 :     ACCUM2 7, FIR_R15, mm0, mm3
475 :    
476 :     %else
477 :    
478 :     %if 0 ; test with no unrolling
479 :    
480 :     TLOAD 0, 8 ; special case for 1rst/last pixel
481 :     TACCUM2 1, xvid_FIR_23_19_6_3, xvid_FIR_1_0_0_0 , mm0, mm3
482 :     TACCUM2 2, xvid_FIR_7_20_20_6, xvid_FIR_3_1_0_0 , mm0, mm3
483 :     TACCUM2 3, xvid_FIR_3_6_20_20, xvid_FIR_6_3_1_0 , mm0, mm3
484 :     TACCUM2 4, xvid_FIR_1_3_6_20 , xvid_FIR_20_6_3_1 , mm0, mm3
485 :     TACCUM2 5, xvid_FIR_0_1_3_6 , xvid_FIR_20_20_6_3, mm0, mm3
486 :     TACCUM2 6, xvid_FIR_0_0_1_3 , xvid_FIR_6_20_20_7, mm0, mm3
487 :     TACCUM2 7, xvid_FIR_0_0_0_1 , xvid_FIR_3_6_19_23, mm0, mm3
488 :    
489 :     %else ; test with unrolling (little faster, but not much)
490 :    
491 :     movzx eax, byte [esi]
492 :     movzx edx, byte [esi+8]
493 :     movq mm0, [xvid_FIR_14_3_2_1 + eax*8 ]
494 :     movzx eax, byte [esi+1]
495 :     movq mm3, [xvid_FIR_1_2_3_14 + edx*8 ]
496 :     paddw mm0, mm7
497 :     paddw mm3, mm7
498 :    
499 :     movzx edx, byte [esi+2]
500 :     paddw mm0, [xvid_FIR_23_19_6_3 + eax*8]
501 :     paddw mm3, [xvid_FIR_1_0_0_0 + eax*8]
502 :    
503 :     movzx eax, byte [esi+3]
504 :     paddw mm0, [xvid_FIR_7_20_20_6 + edx*8]
505 :     paddw mm3, [xvid_FIR_3_1_0_0 + edx*8]
506 :    
507 :     movzx edx, byte [esi+4]
508 :     paddw mm0, [xvid_FIR_3_6_20_20 + eax*8]
509 :     paddw mm3, [xvid_FIR_6_3_1_0 + eax*8]
510 :    
511 :     movzx eax, byte [esi+5]
512 :     paddw mm0, [xvid_FIR_1_3_6_20 + edx*8]
513 :     paddw mm3, [xvid_FIR_20_6_3_1 + edx*8]
514 :    
515 :     movzx edx, byte [esi+6]
516 :     paddw mm0, [xvid_FIR_0_1_3_6 + eax*8]
517 :     paddw mm3, [xvid_FIR_20_20_6_3 + eax*8]
518 :    
519 :     movzx eax, byte [esi+7]
520 :     paddw mm0, [xvid_FIR_0_0_1_3 + edx*8]
521 :     paddw mm3, [xvid_FIR_6_20_20_7 + edx*8]
522 :    
523 :     paddw mm0, [xvid_FIR_0_0_0_1 + eax*8]
524 :     paddw mm3, [xvid_FIR_3_6_19_23 + eax*8]
525 :    
526 :     %endif
527 :    
528 :     %endif ; !USE_TABLES
529 :    
530 :     psraw mm0, 5
531 :     psraw mm3, 5
532 :     packuswb mm0, mm3
533 :    
534 :     %if (%1==1)
535 :     MIX mm0, esi, ebx
536 :     %elif (%1==2)
537 :     MIX mm0, esi+1, ebx
538 :     %endif
539 :     %if (%2==1)
540 :     MIX mm0, edi, Rounder1_MMX
541 :     %endif
542 :    
543 :     movq [edi], mm0
544 :    
545 :     add edi, ebp
546 :     add esi, ebp
547 :     dec ecx
548 :     jg .Loop
549 :    
550 :     %if (%2==0) && (%1==0)
551 :     EPILOG_NO_AVRG
552 :     %else
553 :     EPILOG_AVRG
554 :     %endif
555 :    
556 :     %endmacro
557 :    
558 :     ;//////////////////////////////////////////////////////////////////////
559 :     ;// 16x? copy Functions
560 :    
561 :     xvid_H_Pass_16_mmx:
562 :     H_PASS_16 0, 0
563 : edgomez 1540 .endfunc
564 : edgomez 1382 xvid_H_Pass_Avrg_16_mmx:
565 :     H_PASS_16 1, 0
566 : edgomez 1540 .endfunc
567 : edgomez 1382 xvid_H_Pass_Avrg_Up_16_mmx:
568 :     H_PASS_16 2, 0
569 : edgomez 1540 .endfunc
570 : edgomez 1382
571 :     ;//////////////////////////////////////////////////////////////////////
572 :     ;// 8x? copy Functions
573 :    
574 :     xvid_H_Pass_8_mmx:
575 :     H_PASS_8 0, 0
576 : edgomez 1540 .endfunc
577 : edgomez 1382 xvid_H_Pass_Avrg_8_mmx:
578 :     H_PASS_8 1, 0
579 : edgomez 1540 .endfunc
580 : edgomez 1382 xvid_H_Pass_Avrg_Up_8_mmx:
581 :     H_PASS_8 2, 0
582 : edgomez 1540 .endfunc
583 : edgomez 1382
584 :     ;//////////////////////////////////////////////////////////////////////
585 :     ;// 16x? avrg Functions
586 :    
587 :     xvid_H_Pass_Add_16_mmx:
588 :     H_PASS_16 0, 1
589 : edgomez 1540 .endfunc
590 : edgomez 1382 xvid_H_Pass_Avrg_Add_16_mmx:
591 :     H_PASS_16 1, 1
592 : edgomez 1540 .endfunc
593 : edgomez 1382 xvid_H_Pass_Avrg_Up_Add_16_mmx:
594 :     H_PASS_16 2, 1
595 : edgomez 1540 .endfunc
596 : edgomez 1382
597 :     ;//////////////////////////////////////////////////////////////////////
598 :     ;// 8x? avrg Functions
599 :    
600 :     xvid_H_Pass_8_Add_mmx:
601 :     H_PASS_8 0, 1
602 : edgomez 1540 .endfunc
603 : edgomez 1382 xvid_H_Pass_Avrg_8_Add_mmx:
604 :     H_PASS_8 1, 1
605 : edgomez 1540 .endfunc
606 : edgomez 1382 xvid_H_Pass_Avrg_Up_8_Add_mmx:
607 :     H_PASS_8 2, 1
608 : edgomez 1540 .endfunc
609 : edgomez 1382
610 :    
611 :    
612 :     ;//////////////////////////////////////////////////////////////////////
613 :     ;//
614 :     ;// All vertical passes
615 :     ;//
616 :     ;//////////////////////////////////////////////////////////////////////
617 :    
618 :     %macro V_LOAD 1 ; %1=Last?
619 :    
620 :     movd mm4, [edx]
621 :     pxor mm6, mm6
622 :     %if (%1==0)
623 :     add edx, ebp
624 :     %endif
625 :     punpcklbw mm4, mm6
626 :    
627 :     %endmacro
628 :    
629 :     %macro V_ACC1 2 ; %1:reg; 2:tap
630 :     pmullw mm4, [%2]
631 :     paddw %1, mm4
632 :     %endmacro
633 :    
634 :     %macro V_ACC2 4 ; %1-%2: regs, %3-%4: taps
635 :     movq mm5, mm4
636 :     movq mm6, mm4
637 :     pmullw mm5, [%3]
638 :     pmullw mm6, [%4]
639 :     paddw %1, mm5
640 :     paddw %2, mm6
641 :     %endmacro
642 :    
643 :     %macro V_ACC2l 4 ; %1-%2: regs, %3-%4: taps
644 :     movq mm5, mm4
645 :     pmullw mm5, [%3]
646 :     pmullw mm4, [%4]
647 :     paddw %1, mm5
648 :     paddw %2, mm4
649 :     %endmacro
650 :    
651 :     %macro V_ACC4 8 ; %1-%4: regs, %5-%8: taps
652 :     V_ACC2 %1,%2, %5,%6
653 :     V_ACC2l %3,%4, %7,%8
654 :     %endmacro
655 :    
656 :    
657 :     %macro V_MIX 3 ; %1:dst-reg, %2:src, %3: rounder
658 :     pxor mm6, mm6
659 :     movq mm4, [%2]
660 :     punpcklbw %1, mm6
661 :     punpcklbw mm4, mm6
662 :     paddusw %1, mm4
663 :     paddusw %1, [%3]
664 :     psrlw %1, 1
665 :     packuswb %1, %1
666 :     %endmacro
667 :    
668 :     %macro V_STORE 4 ; %1-%2: mix ops, %3: reg, %4:last?
669 :    
670 :     psraw %3, 5
671 :     packuswb %3, %3
672 :    
673 :     %if (%1==1)
674 :     V_MIX %3, esi, ebx
675 :     add esi, ebp
676 :     %elif (%1==2)
677 :     add esi, ebp
678 :     V_MIX %3, esi, ebx
679 :     %endif
680 :     %if (%2==1)
681 :     V_MIX %3, edi, Rounder1_MMX
682 :     %endif
683 :    
684 :     movd eax, %3
685 :     mov [edi], eax
686 :    
687 :     %if (%4==0)
688 :     add edi, ebp
689 :     %endif
690 :    
691 :     %endmacro
692 :    
693 :     ;//////////////////////////////////////////////////////////////////////
694 :    
695 :     %macro V_PASS_16 2 ; %1:src-op (0=NONE,1=AVRG,2=AVRG-UP), %2:dst-op (NONE/AVRG)
696 :    
697 :     %if (%2==0) && (%1==0)
698 :     PROLOG_NO_AVRG
699 :     %else
700 :     PROLOG_AVRG
701 :     %endif
702 :    
703 :     ; we process one stripe of 4x16 pixel each time.
704 :     ; the size (3rd argument) is meant to be a multiple of 4
705 :     ; mm0..mm3 serves as a 4x4 delay line
706 :    
707 :     .Loop
708 :    
709 :     push edi
710 :     push esi ; esi is preserved for src-mixing
711 :     mov edx, esi
712 :    
713 :     ; ouput rows [0..3], from input rows [0..8]
714 :    
715 :     movq mm0, mm7
716 :     movq mm1, mm7
717 :     movq mm2, mm7
718 :     movq mm3, mm7
719 :    
720 :     V_LOAD 0
721 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_C14, FIR_Cm3, FIR_C2, FIR_Cm1
722 :     V_LOAD 0
723 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_C23, FIR_C19, FIR_Cm6, FIR_C3
724 :     V_LOAD 0
725 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_Cm7, FIR_C20, FIR_C20, FIR_Cm6
726 :     V_LOAD 0
727 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_C3, FIR_Cm6, FIR_C20, FIR_C20
728 :     V_LOAD 0
729 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_Cm1, FIR_C3, FIR_Cm6, FIR_C20
730 :     V_STORE %1, %2, mm0, 0
731 :    
732 :     V_LOAD 0
733 :     V_ACC2 mm1, mm2, FIR_Cm1, FIR_C3
734 :     V_ACC1 mm3, FIR_Cm6
735 :     V_STORE %1, %2, mm1, 0
736 :    
737 :     V_LOAD 0
738 :     V_ACC2l mm2, mm3, FIR_Cm1, FIR_C3
739 :     V_STORE %1, %2, mm2, 0
740 :    
741 :     V_LOAD 1
742 :     V_ACC1 mm3, FIR_Cm1
743 :     V_STORE %1, %2, mm3, 0
744 :    
745 :     ; ouput rows [4..7], from input rows [1..11] (!!)
746 :    
747 :     mov esi, [esp]
748 :     lea edx, [esi+ebp]
749 :    
750 :     lea esi, [esi+4*ebp] ; for src-mixing
751 :     push esi ; this will be the new value for next round
752 :    
753 :     movq mm0, mm7
754 :     movq mm1, mm7
755 :     movq mm2, mm7
756 :     movq mm3, mm7
757 :    
758 :     V_LOAD 0
759 :     V_ACC1 mm0, FIR_Cm1
760 :    
761 :     V_LOAD 0
762 :     V_ACC2l mm0, mm1, FIR_C3, FIR_Cm1
763 :    
764 :     V_LOAD 0
765 :     V_ACC2 mm0, mm1, FIR_Cm6, FIR_C3
766 :     V_ACC1 mm2, FIR_Cm1
767 :    
768 :     V_LOAD 0
769 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_C20, FIR_Cm6, FIR_C3, FIR_Cm1
770 :     V_LOAD 0
771 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_C20, FIR_C20, FIR_Cm6, FIR_C3
772 :     V_LOAD 0
773 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_Cm6, FIR_C20, FIR_C20, FIR_Cm6
774 :     V_LOAD 0
775 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_C3, FIR_Cm6, FIR_C20, FIR_C20
776 :     V_LOAD 0
777 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_Cm1, FIR_C3, FIR_Cm6, FIR_C20
778 :     V_STORE %1, %2, mm0, 0
779 :    
780 :     V_LOAD 0
781 :     V_ACC2 mm1, mm2, FIR_Cm1, FIR_C3
782 :     V_ACC1 mm3, FIR_Cm6
783 :     V_STORE %1, %2, mm1, 0
784 :    
785 :     V_LOAD 0
786 :     V_ACC2l mm2, mm3, FIR_Cm1, FIR_C3
787 :     V_STORE %1, %2, mm2, 0
788 :    
789 :     V_LOAD 1
790 :     V_ACC1 mm3, FIR_Cm1
791 :     V_STORE %1, %2, mm3, 0
792 :    
793 :     ; ouput rows [8..11], from input rows [5..15]
794 :    
795 :     pop esi
796 :     lea edx, [esi+ebp]
797 :    
798 :     lea esi, [esi+4*ebp] ; for src-mixing
799 :     push esi ; this will be the new value for next round
800 :    
801 :     movq mm0, mm7
802 :     movq mm1, mm7
803 :     movq mm2, mm7
804 :     movq mm3, mm7
805 :    
806 :     V_LOAD 0
807 :     V_ACC1 mm0, FIR_Cm1
808 :    
809 :     V_LOAD 0
810 :     V_ACC2l mm0, mm1, FIR_C3, FIR_Cm1
811 :    
812 :     V_LOAD 0
813 :     V_ACC2 mm0, mm1, FIR_Cm6, FIR_C3
814 :     V_ACC1 mm2, FIR_Cm1
815 :    
816 :     V_LOAD 0
817 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_C20, FIR_Cm6, FIR_C3, FIR_Cm1
818 :     V_LOAD 0
819 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_C20, FIR_C20, FIR_Cm6, FIR_C3
820 :     V_LOAD 0
821 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_Cm6, FIR_C20, FIR_C20, FIR_Cm6
822 :     V_LOAD 0
823 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_C3, FIR_Cm6, FIR_C20, FIR_C20
824 :     V_LOAD 0
825 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_Cm1, FIR_C3, FIR_Cm6, FIR_C20
826 :    
827 :     V_STORE %1, %2, mm0, 0
828 :    
829 :     V_LOAD 0
830 :     V_ACC2 mm1, mm2, FIR_Cm1, FIR_C3
831 :     V_ACC1 mm3, FIR_Cm6
832 :     V_STORE %1, %2, mm1, 0
833 :    
834 :     V_LOAD 0
835 :     V_ACC2l mm2, mm3, FIR_Cm1, FIR_C3
836 :     V_STORE %1, %2, mm2, 0
837 :    
838 :     V_LOAD 1
839 :     V_ACC1 mm3, FIR_Cm1
840 :     V_STORE %1, %2, mm3, 0
841 :    
842 :    
843 :     ; ouput rows [12..15], from input rows [9.16]
844 :    
845 :     pop esi
846 :     lea edx, [esi+ebp]
847 :    
848 :     %if (%1!=0)
849 :     lea esi, [esi+4*ebp] ; for src-mixing
850 :     %endif
851 :    
852 :     movq mm0, mm7
853 :     movq mm1, mm7
854 :     movq mm2, mm7
855 :     movq mm3, mm7
856 :    
857 :     V_LOAD 0
858 :     V_ACC1 mm3, FIR_Cm1
859 :    
860 :     V_LOAD 0
861 :     V_ACC2l mm2, mm3, FIR_Cm1, FIR_C3
862 :    
863 :     V_LOAD 0
864 :     V_ACC2 mm1, mm2, FIR_Cm1, FIR_C3
865 :     V_ACC1 mm3, FIR_Cm6
866 :    
867 :     V_LOAD 0
868 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_Cm1, FIR_C3, FIR_Cm6, FIR_C20
869 :     V_LOAD 0
870 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_C3, FIR_Cm6, FIR_C20, FIR_C20
871 :     V_LOAD 0
872 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_Cm7, FIR_C20, FIR_C20, FIR_Cm6
873 :     V_LOAD 0
874 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_C23, FIR_C19, FIR_Cm6, FIR_C3
875 :     V_LOAD 1
876 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_C14, FIR_Cm3, FIR_C2, FIR_Cm1
877 :    
878 :     V_STORE %1, %2, mm3, 0
879 :     V_STORE %1, %2, mm2, 0
880 :     V_STORE %1, %2, mm1, 0
881 :     V_STORE %1, %2, mm0, 1
882 :    
883 :     ; ... next 4 columns
884 :    
885 :     pop esi
886 :     pop edi
887 :     add esi, 4
888 :     add edi, 4
889 :     sub ecx, 4
890 :     jg .Loop
891 :    
892 :     %if (%2==0) && (%1==0)
893 :     EPILOG_NO_AVRG
894 :     %else
895 :     EPILOG_AVRG
896 :     %endif
897 :    
898 :     %endmacro
899 :    
900 :     ;//////////////////////////////////////////////////////////////////////
901 :    
902 :     %macro V_PASS_8 2 ; %1:src-op (0=NONE,1=AVRG,2=AVRG-UP), %2:dst-op (NONE/AVRG)
903 :    
904 :     %if (%2==0) && (%1==0)
905 :     PROLOG_NO_AVRG
906 :     %else
907 :     PROLOG_AVRG
908 :     %endif
909 :    
910 :     ; we process one stripe of 4x8 pixel each time
911 :     ; the size (3rd argument) is meant to be a multiple of 4
912 :     ; mm0..mm3 serves as a 4x4 delay line
913 :     .Loop
914 :    
915 :     push edi
916 :     push esi ; esi is preserved for src-mixing
917 :     mov edx, esi
918 :    
919 :     ; ouput rows [0..3], from input rows [0..8]
920 :    
921 :     movq mm0, mm7
922 :     movq mm1, mm7
923 :     movq mm2, mm7
924 :     movq mm3, mm7
925 :    
926 :     V_LOAD 0
927 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_C14, FIR_Cm3, FIR_C2, FIR_Cm1
928 :     V_LOAD 0
929 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_C23, FIR_C19, FIR_Cm6, FIR_C3
930 :     V_LOAD 0
931 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_Cm7, FIR_C20, FIR_C20, FIR_Cm6
932 :     V_LOAD 0
933 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_C3, FIR_Cm6, FIR_C20, FIR_C20
934 :     V_LOAD 0
935 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_Cm1, FIR_C3, FIR_Cm6, FIR_C20
936 :     V_STORE %1, %2, mm0, 0
937 :    
938 :     V_LOAD 0
939 :     V_ACC2 mm1, mm2, FIR_Cm1, FIR_C3
940 :     V_ACC1 mm3, FIR_Cm6
941 :    
942 :     V_STORE %1, %2, mm1, 0
943 :    
944 :     V_LOAD 0
945 :     V_ACC2l mm2, mm3, FIR_Cm1, FIR_C3
946 :     V_STORE %1, %2, mm2, 0
947 :    
948 :     V_LOAD 1
949 :     V_ACC1 mm3, FIR_Cm1
950 :     V_STORE %1, %2, mm3, 0
951 :    
952 :     ; ouput rows [4..7], from input rows [1..9]
953 :    
954 :     mov esi, [esp]
955 :     lea edx, [esi+ebp]
956 :    
957 :     %if (%1!=0)
958 :     lea esi, [esi+4*ebp] ; for src-mixing
959 :     %endif
960 :    
961 :     movq mm0, mm7
962 :     movq mm1, mm7
963 :     movq mm2, mm7
964 :     movq mm3, mm7
965 :    
966 :     V_LOAD 0
967 :     V_ACC1 mm3, FIR_Cm1
968 :    
969 :     V_LOAD 0
970 :     V_ACC2l mm2, mm3, FIR_Cm1, FIR_C3
971 :    
972 :     V_LOAD 0
973 :     V_ACC2 mm1, mm2, FIR_Cm1, FIR_C3
974 :     V_ACC1 mm3, FIR_Cm6
975 :    
976 :     V_LOAD 0
977 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_Cm1, FIR_C3, FIR_Cm6, FIR_C20
978 :     V_LOAD 0
979 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_C3, FIR_Cm6, FIR_C20, FIR_C20
980 :     V_LOAD 0
981 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_Cm7, FIR_C20, FIR_C20, FIR_Cm6
982 :     V_LOAD 0
983 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_C23, FIR_C19, FIR_Cm6, FIR_C3
984 :     V_LOAD 1
985 :     V_ACC4 mm0, mm1, mm2, mm3, FIR_C14, FIR_Cm3, FIR_C2, FIR_Cm1
986 :    
987 :     V_STORE %1, %2, mm3, 0
988 :     V_STORE %1, %2, mm2, 0
989 :     V_STORE %1, %2, mm1, 0
990 :     V_STORE %1, %2, mm0, 1
991 :    
992 :     ; ... next 4 columns
993 :    
994 :     pop esi
995 :     pop edi
996 :     add esi, 4
997 :     add edi, 4
998 :     sub ecx, 4
999 :     jg .Loop
1000 :    
1001 :     %if (%2==0) && (%1==0)
1002 :     EPILOG_NO_AVRG
1003 :     %else
1004 :     EPILOG_AVRG
1005 :     %endif
1006 :    
1007 :     %endmacro
1008 :    
1009 :    
1010 :     ;//////////////////////////////////////////////////////////////////////
1011 :     ;// 16x? copy Functions
1012 :    
1013 :     xvid_V_Pass_16_mmx:
1014 :     V_PASS_16 0, 0
1015 : edgomez 1540 .endfunc
1016 : edgomez 1382 xvid_V_Pass_Avrg_16_mmx:
1017 :     V_PASS_16 1, 0
1018 : edgomez 1540 .endfunc
1019 : edgomez 1382 xvid_V_Pass_Avrg_Up_16_mmx:
1020 :     V_PASS_16 2, 0
1021 : edgomez 1540 .endfunc
1022 : edgomez 1382
1023 :     ;//////////////////////////////////////////////////////////////////////
1024 :     ;// 8x? copy Functions
1025 :    
1026 :     xvid_V_Pass_8_mmx:
1027 :     V_PASS_8 0, 0
1028 : edgomez 1540 .endfunc
1029 : edgomez 1382 xvid_V_Pass_Avrg_8_mmx:
1030 :     V_PASS_8 1, 0
1031 : edgomez 1540 .endfunc
1032 : edgomez 1382 xvid_V_Pass_Avrg_Up_8_mmx:
1033 :     V_PASS_8 2, 0
1034 : edgomez 1540 .endfunc
1035 : edgomez 1382
1036 :     ;//////////////////////////////////////////////////////////////////////
1037 :     ;// 16x? avrg Functions
1038 :    
1039 :     xvid_V_Pass_Add_16_mmx:
1040 :     V_PASS_16 0, 1
1041 : edgomez 1540 .endfunc
1042 : edgomez 1382 xvid_V_Pass_Avrg_Add_16_mmx:
1043 :     V_PASS_16 1, 1
1044 : edgomez 1540 .endfunc
1045 : edgomez 1382 xvid_V_Pass_Avrg_Up_Add_16_mmx:
1046 :     V_PASS_16 2, 1
1047 : edgomez 1540 .endfunc
1048 : edgomez 1382
1049 :     ;//////////////////////////////////////////////////////////////////////
1050 :     ;// 8x? avrg Functions
1051 :    
1052 :     xvid_V_Pass_8_Add_mmx:
1053 :     V_PASS_8 0, 1
1054 : edgomez 1540 .endfunc
1055 : edgomez 1382 xvid_V_Pass_Avrg_8_Add_mmx:
1056 :     V_PASS_8 1, 1
1057 : edgomez 1540 .endfunc
1058 : edgomez 1382 xvid_V_Pass_Avrg_Up_8_Add_mmx:
1059 :     V_PASS_8 2, 1
1060 : edgomez 1540 .endfunc
1061 : edgomez 1382
1062 :     ;//////////////////////////////////////////////////////////////////////
1063 : Isibaar 1790
1064 :     %ifidn __OUTPUT_FORMAT__,elf
1065 :     section ".note.GNU-stack" noalloc noexec nowrite progbits
1066 :     %endif
1067 :    

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