[svn] / branches / release-1_2-branch / xvidcore / src / image / x86_asm / interpolate8x8_mmx.asm Repository:
ViewVC logotype

Annotation of /branches/release-1_2-branch/xvidcore/src/image/x86_asm/interpolate8x8_mmx.asm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1793 - (view) (download)
Original Path: trunk/xvidcore/src/image/x86_asm/interpolate8x8_mmx.asm

1 : edgomez 1382 ;/*****************************************************************************
2 : Isibaar 262 ; *
3 : edgomez 1382 ; * XVID MPEG-4 VIDEO CODEC
4 :     ; * - mmx 8x8 block-based halfpel interpolation -
5 : Isibaar 262 ; *
6 : edgomez 1382 ; * Copyright(C) 2001 Peter Ross <pross@xvid.org>
7 :     ; * 2002 Michael Militzer <isibaar@xvid.org>
8 : Isibaar 262 ; *
9 : edgomez 1382 ; * This program is free software ; you can redistribute it and/or modify
10 :     ; * it 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 : Isibaar 262 ; *
14 : edgomez 1382 ; * 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 : Isibaar 262 ; *
19 : edgomez 1382 ; * 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 : Isibaar 262 ; *
23 : edgomez 1382 ; ****************************************************************************/
24 : Isibaar 262
25 : edgomez 1382 BITS 32
26 : edgomez 851
27 : edgomez 1382 %macro cglobal 1
28 : Isibaar 262 %ifdef PREFIX
29 : edgomez 1535 %ifdef MARK_FUNCS
30 : edgomez 1540 global _%1:function %1.endfunc-%1
31 :     %define %1 _%1:function %1.endfunc-%1
32 : Isibaar 1793 %define ENDFUNC .endfunc
33 : edgomez 1535 %else
34 :     global _%1
35 :     %define %1 _%1
36 : Isibaar 1793 %define ENDFUNC
37 : edgomez 1535 %endif
38 : Isibaar 262 %else
39 : edgomez 1535 %ifdef MARK_FUNCS
40 : edgomez 1540 global %1:function %1.endfunc-%1
41 : Isibaar 1793 %define ENDFUNC .endfunc
42 : edgomez 1535 %else
43 :     global %1
44 : Isibaar 1793 %define ENDFUNC
45 : edgomez 1535 %endif
46 : Isibaar 262 %endif
47 :     %endmacro
48 :    
49 : edgomez 1382 ;=============================================================================
50 :     ; Read only data
51 :     ;=============================================================================
52 : Isibaar 262
53 : edgomez 1382 %ifdef FORMAT_COFF
54 : edgomez 1519 SECTION .rodata
55 : edgomez 1382 %else
56 : edgomez 1519 SECTION .rodata align=16
57 : edgomez 1382 %endif
58 : Isibaar 262
59 : edgomez 1382 ;-----------------------------------------------------------------------------
60 : edgomez 851 ; (16 - r) rounding table
61 : edgomez 1382 ;-----------------------------------------------------------------------------
62 : edgomez 851
63 : edgomez 1382 ALIGN 16
64 :     rounding_lowpass_mmx:
65 :     times 4 dw 16
66 :     times 4 dw 15
67 : edgomez 851
68 : edgomez 1382 ;-----------------------------------------------------------------------------
69 : Isibaar 262 ; (1 - r) rounding table
70 : edgomez 1382 ;-----------------------------------------------------------------------------
71 : Isibaar 262
72 : edgomez 1382 rounding1_mmx:
73 :     times 4 dw 1
74 :     times 4 dw 0
75 : Isibaar 262
76 : edgomez 1382 ;-----------------------------------------------------------------------------
77 :     ; (2 - r) rounding table
78 :     ;-----------------------------------------------------------------------------
79 : Isibaar 262
80 : edgomez 1382 rounding2_mmx:
81 :     times 4 dw 2
82 :     times 4 dw 1
83 : Isibaar 262
84 : edgomez 1382 mmx_one:
85 :     times 8 db 1
86 : Isibaar 262
87 : edgomez 1382 mmx_two:
88 :     times 8 db 2
89 : edgomez 851
90 : edgomez 1382 mmx_three:
91 :     times 8 db 3
92 : edgomez 851
93 : edgomez 1382 mmx_five:
94 :     times 4 dw 5
95 : edgomez 851
96 : edgomez 1382 mmx_mask:
97 :     times 8 db 254
98 : edgomez 851
99 : edgomez 1382 mmx_mask2:
100 :     times 8 db 252
101 : edgomez 851
102 : edgomez 1382 ;=============================================================================
103 :     ; Code
104 :     ;=============================================================================
105 : Isibaar 262
106 : edgomez 1382 SECTION .text
107 :    
108 :     cglobal interpolate8x8_halfpel_h_mmx
109 :     cglobal interpolate8x8_halfpel_v_mmx
110 :     cglobal interpolate8x8_halfpel_hv_mmx
111 : edgomez 1530
112 : suxen_drol 1632 cglobal interpolate8x4_halfpel_h_mmx
113 :     cglobal interpolate8x4_halfpel_v_mmx
114 :     cglobal interpolate8x4_halfpel_hv_mmx
115 :    
116 : edgomez 1382 cglobal interpolate8x8_avg4_mmx
117 :     cglobal interpolate8x8_avg2_mmx
118 : edgomez 1530
119 : edgomez 1382 cglobal interpolate8x8_6tap_lowpass_h_mmx
120 :     cglobal interpolate8x8_6tap_lowpass_v_mmx
121 :    
122 : edgomez 1530 cglobal interpolate8x8_halfpel_add_mmx
123 :     cglobal interpolate8x8_halfpel_h_add_mmx
124 :     cglobal interpolate8x8_halfpel_v_add_mmx
125 :     cglobal interpolate8x8_halfpel_hv_add_mmx
126 :    
127 : Isibaar 262 %macro CALC_AVG 6
128 : edgomez 1382 punpcklbw %3, %6
129 :     punpckhbw %4, %6
130 : Isibaar 262
131 : edgomez 1382 paddusw %1, %3 ; mm01 += mm23
132 :     paddusw %2, %4
133 :     paddusw %1, %5 ; mm01 += rounding
134 :     paddusw %2, %5
135 : Isibaar 262
136 : edgomez 1382 psrlw %1, 1 ; mm01 >>= 1
137 :     psrlw %2, 1
138 : Isibaar 262 %endmacro
139 :    
140 :    
141 : edgomez 1382 ;-----------------------------------------------------------------------------
142 : Isibaar 262 ;
143 :     ; void interpolate8x8_halfpel_h_mmx(uint8_t * const dst,
144 : edgomez 1382 ; const uint8_t * const src,
145 :     ; const uint32_t stride,
146 :     ; const uint32_t rounding);
147 : Isibaar 262 ;
148 : edgomez 1382 ;-----------------------------------------------------------------------------
149 : Isibaar 262
150 :     %macro COPY_H_MMX 0
151 : edgomez 1382 movq mm0, [esi]
152 :     movq mm2, [esi + 1]
153 :     movq mm1, mm0
154 :     movq mm3, mm2
155 : Isibaar 262
156 : edgomez 1382 punpcklbw mm0, mm6 ; mm01 = [src]
157 :     punpckhbw mm1, mm6 ; mm23 = [src + 1]
158 : Isibaar 262
159 : edgomez 1382 CALC_AVG mm0, mm1, mm2, mm3, mm7, mm6
160 : Isibaar 262
161 : edgomez 1382 packuswb mm0, mm1
162 :     movq [edi], mm0 ; [dst] = mm01
163 : Isibaar 262
164 : edgomez 1382 add esi, edx ; src += stride
165 :     add edi, edx ; dst += stride
166 : Isibaar 262 %endmacro
167 :    
168 : edgomez 1382 ALIGN 16
169 :     interpolate8x8_halfpel_h_mmx:
170 : Isibaar 262
171 : edgomez 1382 push esi
172 :     push edi
173 :     mov eax, [esp + 8 + 16] ; rounding
174 : Isibaar 262
175 : edgomez 1382 movq mm7, [rounding1_mmx + eax * 8]
176 : Isibaar 262
177 : edgomez 1382 mov edi, [esp + 8 + 4] ; dst
178 :     mov esi, [esp + 8 + 8] ; src
179 :     mov edx, [esp + 8 + 12] ; stride
180 : Isibaar 262
181 : edgomez 1382 pxor mm6, mm6 ; zero
182 : Isibaar 262
183 : edgomez 1382 COPY_H_MMX
184 :     COPY_H_MMX
185 :     COPY_H_MMX
186 :     COPY_H_MMX
187 :     COPY_H_MMX
188 :     COPY_H_MMX
189 :     COPY_H_MMX
190 :     COPY_H_MMX
191 : Isibaar 262
192 : edgomez 1382 pop edi
193 :     pop esi
194 : Isibaar 262
195 : edgomez 1382 ret
196 : Isibaar 1793 ENDFUNC
197 : Isibaar 262
198 :    
199 : edgomez 1382 ;-----------------------------------------------------------------------------
200 : Isibaar 262 ;
201 :     ; void interpolate8x8_halfpel_v_mmx(uint8_t * const dst,
202 : edgomez 1382 ; const uint8_t * const src,
203 :     ; const uint32_t stride,
204 :     ; const uint32_t rounding);
205 : Isibaar 262 ;
206 : edgomez 1382 ;-----------------------------------------------------------------------------
207 : Isibaar 262
208 :     %macro COPY_V_MMX 0
209 : edgomez 1382 movq mm0, [esi]
210 :     movq mm2, [esi + edx]
211 :     movq mm1, mm0
212 :     movq mm3, mm2
213 : Isibaar 262
214 : edgomez 1382 punpcklbw mm0, mm6 ; mm01 = [src]
215 :     punpckhbw mm1, mm6 ; mm23 = [src + 1]
216 : Isibaar 262
217 : edgomez 1382 CALC_AVG mm0, mm1, mm2, mm3, mm7, mm6
218 : Isibaar 262
219 : edgomez 1382 packuswb mm0, mm1
220 :     movq [edi], mm0 ; [dst] = mm01
221 : Isibaar 262
222 : edgomez 1382 add esi, edx ; src += stride
223 :     add edi, edx ; dst += stride
224 : Isibaar 262 %endmacro
225 :    
226 : edgomez 1382 ALIGN 16
227 :     interpolate8x8_halfpel_v_mmx:
228 : Isibaar 262
229 : edgomez 1382 push esi
230 :     push edi
231 : Isibaar 262
232 : edgomez 1382 mov eax, [esp + 8 + 16] ; rounding
233 : Isibaar 262
234 : edgomez 1382 movq mm7, [rounding1_mmx + eax * 8]
235 : Isibaar 262
236 : edgomez 1382 mov edi, [esp + 8 + 4] ; dst
237 :     mov esi, [esp + 8 + 8] ; src
238 :     mov edx, [esp + 8 + 12] ; stride
239 : Isibaar 262
240 : edgomez 1382 pxor mm6, mm6 ; zero
241 : Isibaar 262
242 :    
243 : edgomez 1382 COPY_V_MMX
244 :     COPY_V_MMX
245 :     COPY_V_MMX
246 :     COPY_V_MMX
247 :     COPY_V_MMX
248 :     COPY_V_MMX
249 :     COPY_V_MMX
250 :     COPY_V_MMX
251 : Isibaar 262
252 : edgomez 1382 pop edi
253 :     pop esi
254 : Isibaar 262
255 : edgomez 1382 ret
256 : Isibaar 1793 ENDFUNC
257 : Isibaar 262
258 : edgomez 1382
259 :     ;-----------------------------------------------------------------------------
260 : Isibaar 262 ;
261 :     ; void interpolate8x8_halfpel_hv_mmx(uint8_t * const dst,
262 : edgomez 1382 ; const uint8_t * const src,
263 :     ; const uint32_t stride,
264 :     ; const uint32_t rounding);
265 : Isibaar 262 ;
266 :     ;
267 : edgomez 1382 ;-----------------------------------------------------------------------------
268 : Isibaar 262
269 :     %macro COPY_HV_MMX 0
270 : edgomez 1382 ; current row
271 :     movq mm0, [esi]
272 :     movq mm2, [esi + 1]
273 : Isibaar 262
274 : edgomez 1382 movq mm1, mm0
275 :     movq mm3, mm2
276 : Isibaar 262
277 : edgomez 1382 punpcklbw mm0, mm6 ; mm01 = [src]
278 :     punpcklbw mm2, mm6 ; mm23 = [src + 1]
279 :     punpckhbw mm1, mm6
280 :     punpckhbw mm3, mm6
281 : Isibaar 262
282 : edgomez 1382 paddusw mm0, mm2 ; mm01 += mm23
283 :     paddusw mm1, mm3
284 : Isibaar 262
285 : edgomez 1382 ; next row
286 :     movq mm4, [esi + edx]
287 :     movq mm2, [esi + edx + 1]
288 : Isibaar 262
289 : edgomez 1382 movq mm5, mm4
290 :     movq mm3, mm2
291 : Isibaar 262
292 : edgomez 1382 punpcklbw mm4, mm6 ; mm45 = [src + stride]
293 :     punpcklbw mm2, mm6 ; mm23 = [src + stride + 1]
294 :     punpckhbw mm5, mm6
295 :     punpckhbw mm3, mm6
296 : Isibaar 262
297 : edgomez 1382 paddusw mm4, mm2 ; mm45 += mm23
298 :     paddusw mm5, mm3
299 : Isibaar 262
300 : edgomez 1382 ; add current + next row
301 :     paddusw mm0, mm4 ; mm01 += mm45
302 :     paddusw mm1, mm5
303 :     paddusw mm0, mm7 ; mm01 += rounding2
304 :     paddusw mm1, mm7
305 : Isibaar 262
306 : edgomez 1382 psrlw mm0, 2 ; mm01 >>= 2
307 :     psrlw mm1, 2
308 : Isibaar 262
309 : edgomez 1382 packuswb mm0, mm1
310 :     movq [edi], mm0 ; [dst] = mm01
311 : Isibaar 262
312 : edgomez 1382 add esi, edx ; src += stride
313 :     add edi, edx ; dst += stride
314 : Isibaar 262 %endmacro
315 :    
316 : edgomez 1382 ALIGN 16
317 :     interpolate8x8_halfpel_hv_mmx:
318 : Isibaar 262
319 : edgomez 1382 push esi
320 :     push edi
321 : Isibaar 262
322 : edgomez 1382 mov eax, [esp + 8 + 16] ; rounding
323 : Isibaar 262
324 : edgomez 1382 movq mm7, [rounding2_mmx + eax * 8]
325 : Isibaar 262
326 : edgomez 1382 mov edi, [esp + 8 + 4] ; dst
327 :     mov esi, [esp + 8 + 8] ; src
328 : Isibaar 262
329 : edgomez 1382 mov eax, 8
330 : Isibaar 262
331 : edgomez 1382 pxor mm6, mm6 ; zero
332 : Isibaar 262
333 : edgomez 1382 mov edx, [esp + 8 + 12] ; stride
334 : Isibaar 262
335 : edgomez 1382 COPY_HV_MMX
336 :     COPY_HV_MMX
337 :     COPY_HV_MMX
338 :     COPY_HV_MMX
339 :     COPY_HV_MMX
340 :     COPY_HV_MMX
341 :     COPY_HV_MMX
342 :     COPY_HV_MMX
343 : edgomez 851
344 : edgomez 1382 pop edi
345 :     pop esi
346 :    
347 :     ret
348 : Isibaar 1793 ENDFUNC
349 : edgomez 1382
350 :     ;-----------------------------------------------------------------------------
351 : edgomez 851 ;
352 : suxen_drol 1632 ; void interpolate8x4_halfpel_h_mmx(uint8_t * const dst,
353 :     ; const uint8_t * const src,
354 :     ; const uint32_t stride,
355 :     ; const uint32_t rounding);
356 :     ;
357 :     ;-----------------------------------------------------------------------------
358 :    
359 :     ALIGN 16
360 :     interpolate8x4_halfpel_h_mmx:
361 :    
362 :     push esi
363 :     push edi
364 :     mov eax, [esp + 8 + 16] ; rounding
365 :    
366 :     movq mm7, [rounding1_mmx + eax * 8]
367 :    
368 :     mov edi, [esp + 8 + 4] ; dst
369 :     mov esi, [esp + 8 + 8] ; src
370 :     mov edx, [esp + 8 + 12] ; stride
371 :    
372 :     pxor mm6, mm6 ; zero
373 :    
374 :     COPY_H_MMX
375 :     COPY_H_MMX
376 :     COPY_H_MMX
377 :     COPY_H_MMX
378 :    
379 :     pop edi
380 :     pop esi
381 :    
382 :     ret
383 : Isibaar 1793 ENDFUNC
384 : suxen_drol 1632
385 :    
386 :     ;-----------------------------------------------------------------------------
387 :     ;
388 :     ; void interpolate8x4_halfpel_v_mmx(uint8_t * const dst,
389 :     ; const uint8_t * const src,
390 :     ; const uint32_t stride,
391 :     ; const uint32_t rounding);
392 :     ;
393 :     ;-----------------------------------------------------------------------------
394 :    
395 :     ALIGN 16
396 :     interpolate8x4_halfpel_v_mmx:
397 :    
398 :     push esi
399 :     push edi
400 :    
401 :     mov eax, [esp + 8 + 16] ; rounding
402 :    
403 :     movq mm7, [rounding1_mmx + eax * 8]
404 :    
405 :     mov edi, [esp + 8 + 4] ; dst
406 :     mov esi, [esp + 8 + 8] ; src
407 :     mov edx, [esp + 8 + 12] ; stride
408 :    
409 :     pxor mm6, mm6 ; zero
410 :    
411 :    
412 :     COPY_V_MMX
413 :     COPY_V_MMX
414 :     COPY_V_MMX
415 :     COPY_V_MMX
416 :    
417 :     pop edi
418 :     pop esi
419 :    
420 :     ret
421 : Isibaar 1793 ENDFUNC
422 : suxen_drol 1632
423 :    
424 :     ;-----------------------------------------------------------------------------
425 :     ;
426 :     ; void interpolate8x4_halfpel_hv_mmx(uint8_t * const dst,
427 :     ; const uint8_t * const src,
428 :     ; const uint32_t stride,
429 :     ; const uint32_t rounding);
430 :     ;
431 :     ;
432 :     ;-----------------------------------------------------------------------------
433 :    
434 :     ALIGN 16
435 :     interpolate8x4_halfpel_hv_mmx:
436 :    
437 :     push esi
438 :     push edi
439 :    
440 :     mov eax, [esp + 8 + 16] ; rounding
441 :    
442 :     movq mm7, [rounding2_mmx + eax * 8]
443 :    
444 :     mov edi, [esp + 8 + 4] ; dst
445 :     mov esi, [esp + 8 + 8] ; src
446 :    
447 :     mov eax, 8
448 :    
449 :     pxor mm6, mm6 ; zero
450 :    
451 :     mov edx, [esp + 8 + 12] ; stride
452 :    
453 :     COPY_HV_MMX
454 :     COPY_HV_MMX
455 :     COPY_HV_MMX
456 :     COPY_HV_MMX
457 :    
458 :     pop edi
459 :     pop esi
460 :    
461 :     ret
462 : Isibaar 1793 ENDFUNC
463 : suxen_drol 1632
464 :     ;-----------------------------------------------------------------------------
465 :     ;
466 : edgomez 851 ; void interpolate8x8_avg2_mmx(uint8_t const *dst,
467 : edgomez 1382 ; const uint8_t * const src1,
468 :     ; const uint8_t * const src2,
469 :     ; const uint32_t stride,
470 :     ; const uint32_t rounding,
471 :     ; const uint32_t height);
472 : edgomez 851 ;
473 : edgomez 1382 ;-----------------------------------------------------------------------------
474 : edgomez 851
475 :     %macro AVG2_MMX_RND0 0
476 : edgomez 1382 movq mm0, [eax] ; src1 -> mm0
477 :     movq mm1, [ebx] ; src2 -> mm1
478 : edgomez 851
479 : edgomez 1382 movq mm4, [eax+edx]
480 :     movq mm5, [ebx+edx]
481 : edgomez 851
482 : edgomez 1382 movq mm2, mm0 ; src1 -> mm2
483 :     movq mm3, mm1 ; src2 -> mm3
484 : edgomez 851
485 : edgomez 1382 pand mm2, mm7 ; isolate the lsb
486 :     pand mm3, mm7 ; isolate the lsb
487 : edgomez 851
488 : edgomez 1382 por mm2, mm3 ; ODD(src1) OR ODD(src2) -> mm2
489 : edgomez 851
490 : edgomez 1382 movq mm3, mm4
491 :     movq mm6, mm5
492 : edgomez 851
493 : edgomez 1382 pand mm3, mm7
494 :     pand mm6, mm7
495 : edgomez 851
496 : edgomez 1382 por mm3, mm6
497 : edgomez 851
498 : edgomez 1382 pand mm0, [mmx_mask]
499 :     pand mm1, [mmx_mask]
500 :     pand mm4, [mmx_mask]
501 :     pand mm5, [mmx_mask]
502 : edgomez 851
503 : edgomez 1382 psrlq mm0, 1 ; src1 / 2
504 :     psrlq mm1, 1 ; src2 / 2
505 : edgomez 851
506 : edgomez 1382 psrlq mm4, 1
507 :     psrlq mm5, 1
508 : edgomez 851
509 : edgomez 1382 paddb mm0, mm1 ; src1/2 + src2/2 -> mm0
510 :     paddb mm0, mm2 ; correct rounding error
511 : edgomez 851
512 : edgomez 1382 paddb mm4, mm5
513 :     paddb mm4, mm3
514 : edgomez 851
515 : edgomez 1382 lea eax, [eax+2*edx]
516 :     lea ebx, [ebx+2*edx]
517 :    
518 :     movq [ecx], mm0 ; (src1 + src2 + 1) / 2 -> dst
519 :     movq [ecx+edx], mm4
520 : edgomez 851 %endmacro
521 :    
522 :     %macro AVG2_MMX_RND1 0
523 : edgomez 1382 movq mm0, [eax] ; src1 -> mm0
524 :     movq mm1, [ebx] ; src2 -> mm1
525 : edgomez 851
526 : edgomez 1382 movq mm4, [eax+edx]
527 :     movq mm5, [ebx+edx]
528 : edgomez 851
529 : edgomez 1382 movq mm2, mm0 ; src1 -> mm2
530 :     movq mm3, mm1 ; src2 -> mm3
531 : edgomez 851
532 : edgomez 1382 pand mm2, mm7 ; isolate the lsb
533 :     pand mm3, mm7 ; isolate the lsb
534 : edgomez 851
535 : edgomez 1382 pand mm2, mm3 ; ODD(src1) AND ODD(src2) -> mm2
536 : edgomez 851
537 : edgomez 1382 movq mm3, mm4
538 :     movq mm6, mm5
539 : edgomez 851
540 : edgomez 1382 pand mm3, mm7
541 :     pand mm6, mm7
542 : edgomez 851
543 : edgomez 1382 pand mm3, mm6
544 : edgomez 851
545 : edgomez 1382 pand mm0, [mmx_mask]
546 :     pand mm1, [mmx_mask]
547 :     pand mm4, [mmx_mask]
548 :     pand mm5, [mmx_mask]
549 : edgomez 851
550 : edgomez 1382 psrlq mm0, 1 ; src1 / 2
551 :     psrlq mm1, 1 ; src2 / 2
552 : edgomez 851
553 : edgomez 1382 psrlq mm4, 1
554 :     psrlq mm5, 1
555 : edgomez 851
556 : edgomez 1382 paddb mm0, mm1 ; src1/2 + src2/2 -> mm0
557 :     paddb mm0, mm2 ; correct rounding error
558 : edgomez 851
559 : edgomez 1382 paddb mm4, mm5
560 :     paddb mm4, mm3
561 :    
562 :     lea eax, [eax+2*edx]
563 :     lea ebx, [ebx+2*edx]
564 :    
565 :     movq [ecx], mm0 ; (src1 + src2 + 1) / 2 -> dst
566 :     movq [ecx+edx], mm4
567 : edgomez 851 %endmacro
568 :    
569 : edgomez 1382 ALIGN 16
570 :     interpolate8x8_avg2_mmx:
571 : edgomez 851
572 : edgomez 1382 push ebx
573 : edgomez 851
574 : edgomez 1382 mov eax, [esp + 4 + 20] ; rounding
575 :     test eax, eax
576 : edgomez 851
577 : edgomez 1382 jnz near .rounding1
578 : edgomez 851
579 : edgomez 1382 mov eax, [esp + 4 + 24] ; height -> eax
580 :     sub eax, 8
581 :     test eax, eax
582 : edgomez 851
583 : edgomez 1382 mov ecx, [esp + 4 + 4] ; dst -> edi
584 :     mov eax, [esp + 4 + 8] ; src1 -> esi
585 :     mov ebx, [esp + 4 + 12] ; src2 -> eax
586 :     mov edx, [esp + 4 + 16] ; stride -> edx
587 : edgomez 851
588 : edgomez 1382 movq mm7, [mmx_one]
589 : edgomez 851
590 : edgomez 1382 jz near .start0
591 : edgomez 851
592 : edgomez 1382 AVG2_MMX_RND0
593 :     lea ecx, [ecx+2*edx]
594 :    
595 : Isibaar 1793 .start0:
596 : edgomez 851
597 : edgomez 1382 AVG2_MMX_RND0
598 :     lea ecx, [ecx+2*edx]
599 :     AVG2_MMX_RND0
600 :     lea ecx, [ecx+2*edx]
601 :     AVG2_MMX_RND0
602 :     lea ecx, [ecx+2*edx]
603 :     AVG2_MMX_RND0
604 : edgomez 851
605 : edgomez 1382 pop ebx
606 :     ret
607 :    
608 : Isibaar 1793 .rounding1:
609 : edgomez 1382 mov eax, [esp + 4 + 24] ; height -> eax
610 :     sub eax, 8
611 :     test eax, eax
612 : edgomez 851
613 : edgomez 1382 mov ecx, [esp + 4 + 4] ; dst -> edi
614 :     mov eax, [esp + 4 + 8] ; src1 -> esi
615 :     mov ebx, [esp + 4 + 12] ; src2 -> eax
616 :     mov edx, [esp + 4 + 16] ; stride -> edx
617 : edgomez 851
618 : edgomez 1382 movq mm7, [mmx_one]
619 : edgomez 851
620 : edgomez 1382 jz near .start1
621 : edgomez 851
622 : edgomez 1382 AVG2_MMX_RND1
623 :     lea ecx, [ecx+2*edx]
624 : edgomez 851
625 : Isibaar 1793 .start1:
626 : edgomez 851
627 : edgomez 1382 AVG2_MMX_RND1
628 :     lea ecx, [ecx+2*edx]
629 :     AVG2_MMX_RND1
630 :     lea ecx, [ecx+2*edx]
631 :     AVG2_MMX_RND1
632 :     lea ecx, [ecx+2*edx]
633 :     AVG2_MMX_RND1
634 : edgomez 851
635 : edgomez 1382 pop ebx
636 :     ret
637 : Isibaar 1793 ENDFUNC
638 : edgomez 851
639 :    
640 : edgomez 1382 ;-----------------------------------------------------------------------------
641 : edgomez 851 ;
642 :     ; void interpolate8x8_avg4_mmx(uint8_t const *dst,
643 : edgomez 1382 ; const uint8_t * const src1,
644 :     ; const uint8_t * const src2,
645 :     ; const uint8_t * const src3,
646 :     ; const uint8_t * const src4,
647 :     ; const uint32_t stride,
648 :     ; const uint32_t rounding);
649 : edgomez 851 ;
650 : edgomez 1382 ;-----------------------------------------------------------------------------
651 : edgomez 851
652 :     %macro AVG4_MMX_RND0 0
653 : edgomez 1382 movq mm0, [eax] ; src1 -> mm0
654 :     movq mm1, [ebx] ; src2 -> mm1
655 : edgomez 851
656 : edgomez 1382 movq mm2, mm0
657 :     movq mm3, mm1
658 : edgomez 851
659 : edgomez 1382 pand mm2, [mmx_three]
660 :     pand mm3, [mmx_three]
661 : edgomez 851
662 : edgomez 1382 pand mm0, [mmx_mask2]
663 :     pand mm1, [mmx_mask2]
664 : edgomez 851
665 : edgomez 1382 psrlq mm0, 2
666 :     psrlq mm1, 2
667 : edgomez 851
668 : edgomez 1382 lea eax, [eax+edx]
669 :     lea ebx, [ebx+edx]
670 : edgomez 851
671 : edgomez 1382 paddb mm0, mm1
672 :     paddb mm2, mm3
673 : edgomez 851
674 : edgomez 1382 movq mm4, [esi] ; src3 -> mm0
675 :     movq mm5, [edi] ; src4 -> mm1
676 : edgomez 851
677 : edgomez 1382 movq mm1, mm4
678 :     movq mm3, mm5
679 : edgomez 851
680 : edgomez 1382 pand mm1, [mmx_three]
681 :     pand mm3, [mmx_three]
682 : edgomez 851
683 : edgomez 1382 pand mm4, [mmx_mask2]
684 :     pand mm5, [mmx_mask2]
685 : edgomez 851
686 : edgomez 1382 psrlq mm4, 2
687 :     psrlq mm5, 2
688 : edgomez 851
689 : edgomez 1382 paddb mm4, mm5
690 :     paddb mm0, mm4
691 : edgomez 851
692 : edgomez 1382 paddb mm1, mm3
693 :     paddb mm2, mm1
694 :    
695 :     paddb mm2, [mmx_two]
696 :     pand mm2, [mmx_mask2]
697 :    
698 :     psrlq mm2, 2
699 :     paddb mm0, mm2
700 :    
701 :     lea esi, [esi+edx]
702 :     lea edi, [edi+edx]
703 :    
704 :     movq [ecx], mm0 ; (src1 + src2 + src3 + src4 + 2) / 4 -> dst
705 : edgomez 851 %endmacro
706 :    
707 :     %macro AVG4_MMX_RND1 0
708 : edgomez 1382 movq mm0, [eax] ; src1 -> mm0
709 :     movq mm1, [ebx] ; src2 -> mm1
710 : edgomez 851
711 : edgomez 1382 movq mm2, mm0
712 :     movq mm3, mm1
713 : edgomez 851
714 : edgomez 1382 pand mm2, [mmx_three]
715 :     pand mm3, [mmx_three]
716 : edgomez 851
717 : edgomez 1382 pand mm0, [mmx_mask2]
718 :     pand mm1, [mmx_mask2]
719 : edgomez 851
720 : edgomez 1382 psrlq mm0, 2
721 :     psrlq mm1, 2
722 : edgomez 851
723 : edgomez 1382 lea eax,[eax+edx]
724 :     lea ebx,[ebx+edx]
725 : edgomez 851
726 : edgomez 1382 paddb mm0, mm1
727 :     paddb mm2, mm3
728 : edgomez 851
729 : edgomez 1382 movq mm4, [esi] ; src3 -> mm0
730 :     movq mm5, [edi] ; src4 -> mm1
731 : edgomez 851
732 : edgomez 1382 movq mm1, mm4
733 :     movq mm3, mm5
734 : edgomez 851
735 : edgomez 1382 pand mm1, [mmx_three]
736 :     pand mm3, [mmx_three]
737 : edgomez 851
738 : edgomez 1382 pand mm4, [mmx_mask2]
739 :     pand mm5, [mmx_mask2]
740 : edgomez 851
741 : edgomez 1382 psrlq mm4, 2
742 :     psrlq mm5, 2
743 : edgomez 851
744 : edgomez 1382 paddb mm4, mm5
745 :     paddb mm0, mm4
746 : edgomez 851
747 : edgomez 1382 paddb mm1, mm3
748 :     paddb mm2, mm1
749 :    
750 :     paddb mm2, [mmx_one]
751 :     pand mm2, [mmx_mask2]
752 :    
753 :     psrlq mm2, 2
754 :     paddb mm0, mm2
755 :    
756 :     lea esi,[esi+edx]
757 :     lea edi,[edi+edx]
758 :    
759 :     movq [ecx], mm0 ; (src1 + src2 + src3 + src4 + 2) / 4 -> dst
760 : edgomez 851 %endmacro
761 :    
762 : edgomez 1382 ALIGN 16
763 :     interpolate8x8_avg4_mmx:
764 : edgomez 851
765 : edgomez 1382 push ebx
766 :     push edi
767 :     push esi
768 : edgomez 851
769 : edgomez 1382 mov eax, [esp + 12 + 28] ; rounding
770 : edgomez 851
771 : edgomez 1382 test eax, eax
772 : edgomez 851
773 : edgomez 1382 mov ecx, [esp + 12 + 4] ; dst -> edi
774 :     mov eax, [esp + 12 + 8] ; src1 -> esi
775 :     mov ebx, [esp + 12 + 12] ; src2 -> eax
776 :     mov esi, [esp + 12 + 16] ; src3 -> esi
777 :     mov edi, [esp + 12 + 20] ; src4 -> edi
778 :     mov edx, [esp + 12 + 24] ; stride -> edx
779 : edgomez 851
780 : edgomez 1382 movq mm7, [mmx_one]
781 : edgomez 851
782 : edgomez 1382 jnz near .rounding1
783 : edgomez 851
784 : edgomez 1382 AVG4_MMX_RND0
785 :     lea ecx, [ecx+edx]
786 :     AVG4_MMX_RND0
787 :     lea ecx, [ecx+edx]
788 :     AVG4_MMX_RND0
789 :     lea ecx, [ecx+edx]
790 :     AVG4_MMX_RND0
791 :     lea ecx, [ecx+edx]
792 :     AVG4_MMX_RND0
793 :     lea ecx, [ecx+edx]
794 :     AVG4_MMX_RND0
795 :     lea ecx, [ecx+edx]
796 :     AVG4_MMX_RND0
797 :     lea ecx, [ecx+edx]
798 :     AVG4_MMX_RND0
799 :    
800 :     pop esi
801 :     pop edi
802 :     pop ebx
803 :     ret
804 :    
805 : Isibaar 1793 .rounding1:
806 : edgomez 1382 AVG4_MMX_RND1
807 :     lea ecx, [ecx+edx]
808 :     AVG4_MMX_RND1
809 :     lea ecx, [ecx+edx]
810 :     AVG4_MMX_RND1
811 :     lea ecx, [ecx+edx]
812 :     AVG4_MMX_RND1
813 :     lea ecx, [ecx+edx]
814 :     AVG4_MMX_RND1
815 :     lea ecx, [ecx+edx]
816 :     AVG4_MMX_RND1
817 :     lea ecx, [ecx+edx]
818 :     AVG4_MMX_RND1
819 :     lea ecx, [ecx+edx]
820 :     AVG4_MMX_RND1
821 : edgomez 851
822 : edgomez 1382 pop esi
823 :     pop edi
824 :     pop ebx
825 :     ret
826 : Isibaar 1793 ENDFUNC
827 : edgomez 851
828 :    
829 : edgomez 1382 ;-----------------------------------------------------------------------------
830 : edgomez 851 ;
831 :     ; void interpolate8x8_6tap_lowpass_h_mmx(uint8_t const *dst,
832 : edgomez 1382 ; const uint8_t * const src,
833 :     ; const uint32_t stride,
834 :     ; const uint32_t rounding);
835 : edgomez 851 ;
836 : edgomez 1382 ;-----------------------------------------------------------------------------
837 : edgomez 851
838 :     %macro LOWPASS_6TAP_H_MMX 0
839 : edgomez 1382 movq mm0, [eax]
840 :     movq mm2, [eax+1]
841 : edgomez 851
842 : edgomez 1382 movq mm1, mm0
843 :     movq mm3, mm2
844 : edgomez 851
845 : edgomez 1382 punpcklbw mm0, mm7
846 :     punpcklbw mm2, mm7
847 : edgomez 851
848 : edgomez 1382 punpckhbw mm1, mm7
849 :     punpckhbw mm3, mm7
850 : edgomez 851
851 : edgomez 1382 paddw mm0, mm2
852 :     paddw mm1, mm3
853 : edgomez 851
854 : edgomez 1382 psllw mm0, 2
855 :     psllw mm1, 2
856 : edgomez 851
857 : edgomez 1382 movq mm2, [eax-1]
858 :     movq mm4, [eax+2]
859 : edgomez 851
860 : edgomez 1382 movq mm3, mm2
861 :     movq mm5, mm4
862 : edgomez 851
863 : edgomez 1382 punpcklbw mm2, mm7
864 :     punpcklbw mm4, mm7
865 : edgomez 851
866 : edgomez 1382 punpckhbw mm3, mm7
867 :     punpckhbw mm5, mm7
868 : edgomez 851
869 : edgomez 1382 paddw mm2, mm4
870 :     paddw mm3, mm5
871 : edgomez 851
872 : edgomez 1382 psubsw mm0, mm2
873 :     psubsw mm1, mm3
874 : edgomez 851
875 : edgomez 1382 pmullw mm0, [mmx_five]
876 :     pmullw mm1, [mmx_five]
877 : edgomez 851
878 : edgomez 1382 movq mm2, [eax-2]
879 :     movq mm4, [eax+3]
880 : edgomez 851
881 : edgomez 1382 movq mm3, mm2
882 :     movq mm5, mm4
883 : edgomez 851
884 : edgomez 1382 punpcklbw mm2, mm7
885 :     punpcklbw mm4, mm7
886 : edgomez 851
887 : edgomez 1382 punpckhbw mm3, mm7
888 :     punpckhbw mm5, mm7
889 : edgomez 851
890 : edgomez 1382 paddw mm2, mm4
891 :     paddw mm3, mm5
892 : edgomez 851
893 : edgomez 1382 paddsw mm0, mm2
894 :     paddsw mm1, mm3
895 : edgomez 851
896 : edgomez 1382 paddsw mm0, mm6
897 :     paddsw mm1, mm6
898 : edgomez 851
899 : edgomez 1382 psraw mm0, 5
900 :     psraw mm1, 5
901 : edgomez 851
902 : edgomez 1382 lea eax, [eax+edx]
903 :     packuswb mm0, mm1
904 :     movq [ecx], mm0
905 : edgomez 851 %endmacro
906 :    
907 : edgomez 1382 ALIGN 16
908 :     interpolate8x8_6tap_lowpass_h_mmx:
909 : edgomez 851
910 : edgomez 1382 mov eax, [esp + 16] ; rounding
911 : edgomez 851
912 : edgomez 1382 movq mm6, [rounding_lowpass_mmx + eax * 8]
913 : edgomez 851
914 : edgomez 1382 mov ecx, [esp + 4] ; dst -> edi
915 :     mov eax, [esp + 8] ; src -> esi
916 :     mov edx, [esp + 12] ; stride -> edx
917 : edgomez 851
918 : edgomez 1382 pxor mm7, mm7
919 : edgomez 851
920 : edgomez 1382 LOWPASS_6TAP_H_MMX
921 :     lea ecx, [ecx+edx]
922 :     LOWPASS_6TAP_H_MMX
923 :     lea ecx, [ecx+edx]
924 :     LOWPASS_6TAP_H_MMX
925 :     lea ecx, [ecx+edx]
926 :     LOWPASS_6TAP_H_MMX
927 :     lea ecx, [ecx+edx]
928 :     LOWPASS_6TAP_H_MMX
929 :     lea ecx, [ecx+edx]
930 :     LOWPASS_6TAP_H_MMX
931 :     lea ecx, [ecx+edx]
932 :     LOWPASS_6TAP_H_MMX
933 :     lea ecx, [ecx+edx]
934 :     LOWPASS_6TAP_H_MMX
935 : edgomez 851
936 : edgomez 1382 ret
937 : Isibaar 1793 ENDFUNC
938 : edgomez 1382
939 :     ;-----------------------------------------------------------------------------
940 : edgomez 851 ;
941 :     ; void interpolate8x8_6tap_lowpass_v_mmx(uint8_t const *dst,
942 : edgomez 1382 ; const uint8_t * const src,
943 :     ; const uint32_t stride,
944 :     ; const uint32_t rounding);
945 : edgomez 851 ;
946 : edgomez 1382 ;-----------------------------------------------------------------------------
947 : edgomez 851
948 :     %macro LOWPASS_6TAP_V_MMX 0
949 : edgomez 1382 movq mm0, [eax]
950 :     movq mm2, [eax+edx]
951 : edgomez 851
952 : edgomez 1382 movq mm1, mm0
953 :     movq mm3, mm2
954 : edgomez 851
955 : edgomez 1382 punpcklbw mm0, mm7
956 :     punpcklbw mm2, mm7
957 : edgomez 851
958 : edgomez 1382 punpckhbw mm1, mm7
959 :     punpckhbw mm3, mm7
960 : edgomez 851
961 : edgomez 1382 paddw mm0, mm2
962 :     paddw mm1, mm3
963 : edgomez 851
964 : edgomez 1382 psllw mm0, 2
965 :     psllw mm1, 2
966 : edgomez 851
967 : edgomez 1382 movq mm4, [eax+2*edx]
968 :     sub eax, ebx
969 :     movq mm2, [eax+2*edx]
970 : edgomez 851
971 : edgomez 1382 movq mm3, mm2
972 :     movq mm5, mm4
973 : edgomez 851
974 : edgomez 1382 punpcklbw mm2, mm7
975 :     punpcklbw mm4, mm7
976 : edgomez 851
977 : edgomez 1382 punpckhbw mm3, mm7
978 :     punpckhbw mm5, mm7
979 : edgomez 851
980 : edgomez 1382 paddw mm2, mm4
981 :     paddw mm3, mm5
982 : edgomez 851
983 : edgomez 1382 psubsw mm0, mm2
984 :     psubsw mm1, mm3
985 : edgomez 851
986 : edgomez 1382 pmullw mm0, [mmx_five]
987 :     pmullw mm1, [mmx_five]
988 : edgomez 851
989 : edgomez 1382 movq mm2, [eax+edx]
990 :     movq mm4, [eax+2*ebx]
991 : edgomez 851
992 : edgomez 1382 movq mm3, mm2
993 :     movq mm5, mm4
994 : edgomez 851
995 : edgomez 1382 punpcklbw mm2, mm7
996 :     punpcklbw mm4, mm7
997 : edgomez 851
998 : edgomez 1382 punpckhbw mm3, mm7
999 :     punpckhbw mm5, mm7
1000 : edgomez 851
1001 : edgomez 1382 paddw mm2, mm4
1002 :     paddw mm3, mm5
1003 : edgomez 851
1004 : edgomez 1382 paddsw mm0, mm2
1005 :     paddsw mm1, mm3
1006 : edgomez 851
1007 : edgomez 1382 paddsw mm0, mm6
1008 :     paddsw mm1, mm6
1009 : edgomez 851
1010 : edgomez 1382 psraw mm0, 5
1011 :     psraw mm1, 5
1012 : edgomez 851
1013 : edgomez 1382 lea eax, [eax+4*edx]
1014 :     packuswb mm0, mm1
1015 :     movq [ecx], mm0
1016 : edgomez 851 %endmacro
1017 :    
1018 : edgomez 1382 ALIGN 16
1019 :     interpolate8x8_6tap_lowpass_v_mmx:
1020 : edgomez 851
1021 : edgomez 1382 push ebx
1022 : edgomez 851
1023 : edgomez 1382 mov eax, [esp + 4 + 16] ; rounding
1024 : edgomez 851
1025 : edgomez 1382 movq mm6, [rounding_lowpass_mmx + eax * 8]
1026 : edgomez 851
1027 : edgomez 1382 mov ecx, [esp + 4 + 4] ; dst -> edi
1028 :     mov eax, [esp + 4 + 8] ; src -> esi
1029 :     mov edx, [esp + 4 + 12] ; stride -> edx
1030 : edgomez 851
1031 : edgomez 1382 mov ebx, edx
1032 :     shl ebx, 1
1033 :     add ebx, edx
1034 : edgomez 851
1035 : edgomez 1382 pxor mm7, mm7
1036 : edgomez 851
1037 : edgomez 1382 LOWPASS_6TAP_V_MMX
1038 :     lea ecx, [ecx+edx]
1039 :     LOWPASS_6TAP_V_MMX
1040 :     lea ecx, [ecx+edx]
1041 :     LOWPASS_6TAP_V_MMX
1042 :     lea ecx, [ecx+edx]
1043 :     LOWPASS_6TAP_V_MMX
1044 :     lea ecx, [ecx+edx]
1045 :     LOWPASS_6TAP_V_MMX
1046 :     lea ecx, [ecx+edx]
1047 :     LOWPASS_6TAP_V_MMX
1048 :     lea ecx, [ecx+edx]
1049 :     LOWPASS_6TAP_V_MMX
1050 :     lea ecx, [ecx+edx]
1051 :     LOWPASS_6TAP_V_MMX
1052 : edgomez 851
1053 : edgomez 1382 pop ebx
1054 :     ret
1055 : Isibaar 1793 ENDFUNC
1056 : edgomez 1530
1057 :     ;===========================================================================
1058 :     ;
1059 :     ; The next functions combine both source halfpel interpolation step and the
1060 :     ; averaging (with rouding) step to avoid wasting memory bandwidth computing
1061 :     ; intermediate halfpel images and then averaging them.
1062 :     ;
1063 :     ;===========================================================================
1064 :    
1065 :     %macro PROLOG0 0
1066 :     mov ecx, [esp+ 4] ; Dst
1067 :     mov eax, [esp+ 8] ; Src
1068 :     mov edx, [esp+12] ; BpS
1069 :     %endmacro
1070 :    
1071 :     %macro PROLOG 2 ; %1: Rounder, %2 load Dst-Rounder
1072 :     pxor mm6, mm6
1073 :     movq mm7, [%1] ; TODO: dangerous! (eax isn't checked)
1074 :     %if %2
1075 :     movq mm5, [rounding1_mmx]
1076 :     %endif
1077 :    
1078 :     PROLOG0
1079 :     %endmacro
1080 :    
1081 :     ; performs: mm0 == (mm0+mm2) mm1 == (mm1+mm3)
1082 :     %macro MIX 0
1083 :     punpcklbw mm0, mm6
1084 :     punpcklbw mm2, mm6
1085 :     punpckhbw mm1, mm6
1086 :     punpckhbw mm3, mm6
1087 :     paddusw mm0, mm2
1088 :     paddusw mm1, mm3
1089 :     %endmacro
1090 :    
1091 :     %macro MIX_DST 0
1092 :     movq mm3, mm2
1093 :     paddusw mm0, mm7 ; rounder
1094 :     paddusw mm1, mm7 ; rounder
1095 :     punpcklbw mm2, mm6
1096 :     punpckhbw mm3, mm6
1097 :     psrlw mm0, 1
1098 :     psrlw mm1, 1
1099 :    
1100 :     paddusw mm0, mm2 ; mix Src(mm0/mm1) with Dst(mm2/mm3)
1101 :     paddusw mm1, mm3
1102 :     paddusw mm0, mm5
1103 :     paddusw mm1, mm5
1104 :     psrlw mm0, 1
1105 :     psrlw mm1, 1
1106 :    
1107 :     packuswb mm0, mm1
1108 :     %endmacro
1109 :    
1110 :     %macro MIX2 0
1111 :     punpcklbw mm0, mm6
1112 :     punpcklbw mm2, mm6
1113 :     paddusw mm0, mm2
1114 :     paddusw mm0, mm7
1115 :     punpckhbw mm1, mm6
1116 :     punpckhbw mm3, mm6
1117 :     paddusw mm1, mm7
1118 :     paddusw mm1, mm3
1119 :     psrlw mm0, 1
1120 :     psrlw mm1, 1
1121 :    
1122 :     packuswb mm0, mm1
1123 :     %endmacro
1124 :    
1125 :     ;===========================================================================
1126 :     ;
1127 :     ; void interpolate8x8_halfpel_add_mmx(uint8_t * const dst,
1128 :     ; const uint8_t * const src,
1129 :     ; const uint32_t stride,
1130 :     ; const uint32_t rounding);
1131 :     ;
1132 :     ;
1133 :     ;===========================================================================
1134 :    
1135 :     %macro ADD_FF_MMX 1
1136 :     movq mm0, [eax]
1137 :     movq mm2, [ecx]
1138 :     movq mm1, mm0
1139 :     movq mm3, mm2
1140 :     %if (%1!=0)
1141 :     lea eax,[eax+%1*edx]
1142 :     %endif
1143 :     MIX
1144 :     paddusw mm0, mm5 ; rounder
1145 :     paddusw mm1, mm5 ; rounder
1146 :     psrlw mm0, 1
1147 :     psrlw mm1, 1
1148 :    
1149 :     packuswb mm0, mm1
1150 :     movq [ecx], mm0
1151 :     %if (%1!=0)
1152 :     lea ecx,[ecx+%1*edx]
1153 :     %endif
1154 :     %endmacro
1155 :    
1156 :     ALIGN 16
1157 :     interpolate8x8_halfpel_add_mmx:
1158 :     PROLOG rounding1_mmx, 1
1159 :     ADD_FF_MMX 1
1160 :     ADD_FF_MMX 1
1161 :     ADD_FF_MMX 1
1162 :     ADD_FF_MMX 1
1163 :     ADD_FF_MMX 1
1164 :     ADD_FF_MMX 1
1165 :     ADD_FF_MMX 1
1166 :     ADD_FF_MMX 0
1167 :     ret
1168 : Isibaar 1793 ENDFUNC
1169 : edgomez 1530
1170 :     ;===========================================================================
1171 :     ;
1172 :     ; void interpolate8x8_halfpel_h_add_mmx(uint8_t * const dst,
1173 :     ; const uint8_t * const src,
1174 :     ; const uint32_t stride,
1175 :     ; const uint32_t rounding);
1176 :     ;
1177 :     ;
1178 :     ;===========================================================================
1179 :    
1180 :     %macro ADD_FH_MMX 0
1181 :     movq mm0, [eax]
1182 :     movq mm2, [eax+1]
1183 :     movq mm1, mm0
1184 :     movq mm3, mm2
1185 :    
1186 :     lea eax,[eax+edx]
1187 :    
1188 :     MIX
1189 :     movq mm2, [ecx] ; prepare mix with Dst[0]
1190 :     MIX_DST
1191 :     movq [ecx], mm0
1192 :     %endmacro
1193 :    
1194 :     ALIGN 16
1195 :     interpolate8x8_halfpel_h_add_mmx:
1196 :     PROLOG rounding1_mmx, 1
1197 :    
1198 :     ADD_FH_MMX
1199 :     lea ecx,[ecx+edx]
1200 :     ADD_FH_MMX
1201 :     lea ecx,[ecx+edx]
1202 :     ADD_FH_MMX
1203 :     lea ecx,[ecx+edx]
1204 :     ADD_FH_MMX
1205 :     lea ecx,[ecx+edx]
1206 :     ADD_FH_MMX
1207 :     lea ecx,[ecx+edx]
1208 :     ADD_FH_MMX
1209 :     lea ecx,[ecx+edx]
1210 :     ADD_FH_MMX
1211 :     lea ecx,[ecx+edx]
1212 :     ADD_FH_MMX
1213 :     ret
1214 : Isibaar 1793 ENDFUNC
1215 : edgomez 1530
1216 :     ;===========================================================================
1217 :     ;
1218 :     ; void interpolate8x8_halfpel_v_add_mmx(uint8_t * const dst,
1219 :     ; const uint8_t * const src,
1220 :     ; const uint32_t stride,
1221 :     ; const uint32_t rounding);
1222 :     ;
1223 :     ;
1224 :     ;===========================================================================
1225 :    
1226 :     %macro ADD_HF_MMX 0
1227 :     movq mm0, [eax]
1228 :     movq mm2, [eax+edx]
1229 :     movq mm1, mm0
1230 :     movq mm3, mm2
1231 :    
1232 :     lea eax,[eax+edx]
1233 :    
1234 :     MIX
1235 :     movq mm2, [ecx] ; prepare mix with Dst[0]
1236 :     MIX_DST
1237 :     movq [ecx], mm0
1238 :    
1239 :     %endmacro
1240 :    
1241 :     ALIGN 16
1242 :     interpolate8x8_halfpel_v_add_mmx:
1243 :     PROLOG rounding1_mmx, 1
1244 :    
1245 :     ADD_HF_MMX
1246 :     lea ecx,[ecx+edx]
1247 :     ADD_HF_MMX
1248 :     lea ecx,[ecx+edx]
1249 :     ADD_HF_MMX
1250 :     lea ecx,[ecx+edx]
1251 :     ADD_HF_MMX
1252 :     lea ecx,[ecx+edx]
1253 :     ADD_HF_MMX
1254 :     lea ecx,[ecx+edx]
1255 :     ADD_HF_MMX
1256 :     lea ecx,[ecx+edx]
1257 :     ADD_HF_MMX
1258 :     lea ecx,[ecx+edx]
1259 :     ADD_HF_MMX
1260 :     ret
1261 : Isibaar 1793 ENDFUNC
1262 : edgomez 1530
1263 :     ; The trick is to correct the result of 'pavgb' with some combination of the
1264 :     ; lsb's of the 4 input values i,j,k,l, and their intermediate 'pavgb' (s and t).
1265 :     ; The boolean relations are:
1266 :     ; (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
1267 :     ; (i+j+k+l+2)/4 = (s+t+1)/2 - (ij|kl)&st
1268 :     ; (i+j+k+l+1)/4 = (s+t+1)/2 - (ij&kl)|st
1269 :     ; (i+j+k+l+0)/4 = (s+t+1)/2 - (ij|kl)|st
1270 :     ; with s=(i+j+1)/2, t=(k+l+1)/2, ij = i^j, kl = k^l, st = s^t.
1271 :    
1272 :     ; Moreover, we process 2 lines at a times, for better overlapping (~15% faster).
1273 :    
1274 :     ;===========================================================================
1275 :     ;
1276 :     ; void interpolate8x8_halfpel_hv_add_mmx(uint8_t * const dst,
1277 :     ; const uint8_t * const src,
1278 :     ; const uint32_t stride,
1279 :     ; const uint32_t rounding);
1280 :     ;
1281 :     ;
1282 :     ;===========================================================================
1283 :    
1284 :     %macro ADD_HH_MMX 0
1285 :     lea eax,[eax+edx]
1286 :    
1287 :     ; transfert prev line to mm0/mm1
1288 :     movq mm0, mm2
1289 :     movq mm1, mm3
1290 :    
1291 :     ; load new line in mm2/mm3
1292 :     movq mm2, [eax]
1293 :     movq mm4, [eax+1]
1294 :     movq mm3, mm2
1295 :     movq mm5, mm4
1296 :    
1297 :     punpcklbw mm2, mm6
1298 :     punpcklbw mm4, mm6
1299 :     paddusw mm2, mm4
1300 :     punpckhbw mm3, mm6
1301 :     punpckhbw mm5, mm6
1302 :     paddusw mm3, mm5
1303 :    
1304 :     ; mix current line (mm2/mm3) with previous (mm0,mm1);
1305 :     ; we'll preserve mm2/mm3 for next line...
1306 :    
1307 :     paddusw mm0, mm2
1308 :     paddusw mm1, mm3
1309 :    
1310 :     movq mm4, [ecx] ; prepare mix with Dst[0]
1311 :     movq mm5, mm4
1312 :    
1313 :     paddusw mm0, mm7 ; finish mixing current line
1314 :     paddusw mm1, mm7
1315 :    
1316 :     punpcklbw mm4, mm6
1317 :     punpckhbw mm5, mm6
1318 :    
1319 :     psrlw mm0, 2
1320 :     psrlw mm1, 2
1321 :    
1322 :     paddusw mm0, mm4 ; mix Src(mm0/mm1) with Dst(mm2/mm3)
1323 :     paddusw mm1, mm5
1324 :    
1325 :     paddusw mm0, [rounding1_mmx]
1326 :     paddusw mm1, [rounding1_mmx]
1327 :    
1328 :     psrlw mm0, 1
1329 :     psrlw mm1, 1
1330 :    
1331 :     packuswb mm0, mm1
1332 :    
1333 :     movq [ecx], mm0
1334 :     %endmacro
1335 :    
1336 :     ALIGN 16
1337 :     interpolate8x8_halfpel_hv_add_mmx:
1338 :     PROLOG rounding2_mmx, 0 ; mm5 is busy. Don't load dst-rounder
1339 :    
1340 :     ; preprocess first line
1341 :     movq mm0, [eax]
1342 :     movq mm2, [eax+1]
1343 :     movq mm1, mm0
1344 :     movq mm3, mm2
1345 :    
1346 :     punpcklbw mm0, mm6
1347 :     punpcklbw mm2, mm6
1348 :     punpckhbw mm1, mm6
1349 :     punpckhbw mm3, mm6
1350 :     paddusw mm2, mm0
1351 :     paddusw mm3, mm1
1352 :    
1353 :     ; Input: mm2/mm3 contains the value (Src[0]+Src[1]) of previous line
1354 :    
1355 :     ADD_HH_MMX
1356 :     lea ecx,[ecx+edx]
1357 :     ADD_HH_MMX
1358 :     lea ecx,[ecx+edx]
1359 :     ADD_HH_MMX
1360 :     lea ecx,[ecx+edx]
1361 :     ADD_HH_MMX
1362 :     lea ecx,[ecx+edx]
1363 :     ADD_HH_MMX
1364 :     lea ecx,[ecx+edx]
1365 :     ADD_HH_MMX
1366 :     lea ecx,[ecx+edx]
1367 :     ADD_HH_MMX
1368 :     lea ecx,[ecx+edx]
1369 :     ADD_HH_MMX
1370 :    
1371 :     ret
1372 : Isibaar 1793 ENDFUNC
1373 : edgomez 1530
1374 : Isibaar 1790
1375 :     %ifidn __OUTPUT_FORMAT__,elf
1376 :     section ".note.GNU-stack" noalloc noexec nowrite progbits
1377 :     %endif
1378 :    

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