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

Diff of /trunk/xvidcore/src/image/x86_asm/interpolate8x8_mmx.asm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 651, Sun Nov 17 00:20:30 2002 UTC revision 1540, Sun Aug 29 10:02:38 2004 UTC
# Line 1  Line 1 
1  ;/*****************************************************************************  ;/*****************************************************************************
2  ; *  ; *
3  ; *  XVID MPEG-4 VIDEO CODEC  ; *  XVID MPEG-4 VIDEO CODEC
4  ; *      mmx 8x8 block-based halfpel interpolation  ; *  - mmx 8x8 block-based halfpel interpolation -
5  ; *  ; *
6  ; *  Copyright(C) 2002 Peter Ross <pross@xvid.org>  ; *  Copyright(C) 2001 Peter Ross <pross@xvid.org>
7    ; *               2002 Michael Militzer <isibaar@xvid.org>
8  ; *  ; *
9  ; *  This file is part of XviD, a free MPEG-4 video encoder/decoder  ; *  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
 ; *  XviD is free software; you can redistribute it and/or modify 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  ; *  the Free Software Foundation; either version 2 of the License, or
12  ; *  (at your option) any later version.  ; *  (at your option) any later version.
13  ; *  ; *
# Line 21  Line 20 
20  ; *  along with this program; if not, write to the Free Software  ; *  along with this program; if not, write to the Free Software
21  ; *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA  ; *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
22  ; *  ; *
 ; *  Under section 8 of the GNU General Public License, the copyright  
 ; *  holders of XVID explicitly forbid distribution in the following  
 ; *  countries:  
 ; *  
 ; *    - Japan  
 ; *    - United States of America  
 ; *  
 ; *  Linking XviD statically or dynamically with other modules is making a  
 ; *  combined work based on XviD.  Thus, the terms and conditions of the  
 ; *  GNU General Public License cover the whole combination.  
 ; *  
 ; *  As a special exception, the copyright holders of XviD give you  
 ; *  permission to link XviD with independent modules that communicate with  
 ; *  XviD solely through the VFW1.1 and DShow interfaces, regardless of the  
 ; *  license terms of these independent modules, and to copy and distribute  
 ; *  the resulting combined work under terms of your choice, provided that  
 ; *  every copy of the combined work is accompanied by a complete copy of  
 ; *  the source code of XviD (the version of XviD used to produce the  
 ; *  combined work), being distributed under the terms of the GNU General  
 ; *  Public License plus this exception.  An independent module is a module  
 ; *  which is not derived from or based on XviD.  
 ; *  
 ; *  Note that people who make modified versions of XviD are not obligated  
 ; *  to grant this special exception for their modified versions; it is  
 ; *  their choice whether to do so.  The GNU General Public License gives  
 ; *  permission to release a modified version without this exception; this  
 ; *  exception also makes it possible to release a modified version which  
 ; *  carries forward this exception.  
 ; *  
 ; * $Id: interpolate8x8_mmx.asm,v 1.11 2002-11-17 00:20:30 edgomez Exp $  
 ; *  
23  ; ****************************************************************************/  ; ****************************************************************************/
24    
25  bits 32  BITS 32
26    
27  %macro cglobal 1  %macro cglobal 1
28          %ifdef PREFIX          %ifdef PREFIX
29                    %ifdef MARK_FUNCS
30                            global _%1:function %1.endfunc-%1
31                            %define %1 _%1:function %1.endfunc-%1
32                    %else
33                  global _%1                  global _%1
34                  %define %1 _%1                  %define %1 _%1
35                    %endif
36            %else
37                    %ifdef MARK_FUNCS
38                            global %1:function %1.endfunc-%1
39          %else          %else
40                  global %1                  global %1
41          %endif          %endif
42            %endif
43  %endmacro  %endmacro
44    
45  section .data  ;=============================================================================
46    ; Read only data
47    ;=============================================================================
48    
49    %ifdef FORMAT_COFF
50    SECTION .rodata
51    %else
52    SECTION .rodata align=16
53    %endif
54    
55  align 16  ;-----------------------------------------------------------------------------
56    ; (16 - r) rounding table
57    ;-----------------------------------------------------------------------------
58    
59    ALIGN 16
60    rounding_lowpass_mmx:
61            times 4 dw 16
62            times 4 dw 15
63    
64  ;===========================================================================  ;-----------------------------------------------------------------------------
65  ; (1 - r) rounding table  ; (1 - r) rounding table
66  ;===========================================================================  ;-----------------------------------------------------------------------------
67    
68  rounding1_mmx  rounding1_mmx:
69  times 4 dw 1  times 4 dw 1
70  times 4 dw 0  times 4 dw 0
71    
72  ;===========================================================================  ;-----------------------------------------------------------------------------
73  ; (2 - r) rounding table  ; (2 - r) rounding table
74  ;===========================================================================  ;-----------------------------------------------------------------------------
75    
76  rounding2_mmx  rounding2_mmx:
77  times 4 dw 2  times 4 dw 2
78  times 4 dw 1  times 4 dw 1
79    
80  mmx_one  mmx_one:
81  times 8 db 1  times 8 db 1
82    
83  section .text  mmx_two:
84            times 8 db 2
85    
86    mmx_three:
87            times 8 db 3
88    
89    mmx_five:
90            times 4 dw 5
91    
92    mmx_mask:
93            times 8 db 254
94    
95    mmx_mask2:
96            times 8 db 252
97    
98    ;=============================================================================
99    ; Code
100    ;=============================================================================
101    
102    SECTION .text
103    
104    cglobal interpolate8x8_halfpel_h_mmx
105    cglobal interpolate8x8_halfpel_v_mmx
106    cglobal interpolate8x8_halfpel_hv_mmx
107    
108    cglobal interpolate8x8_avg4_mmx
109    cglobal interpolate8x8_avg2_mmx
110    
111    cglobal interpolate8x8_6tap_lowpass_h_mmx
112    cglobal interpolate8x8_6tap_lowpass_v_mmx
113    
114    cglobal interpolate8x8_halfpel_add_mmx
115    cglobal interpolate8x8_halfpel_h_add_mmx
116    cglobal interpolate8x8_halfpel_v_add_mmx
117    cglobal interpolate8x8_halfpel_hv_add_mmx
118    
119  %macro  CALC_AVG 6  %macro  CALC_AVG 6
120          punpcklbw %3, %6          punpcklbw %3, %6
# Line 101  Line 127 
127    
128          psrlw %1, 1                     ; mm01 >>= 1          psrlw %1, 1                     ; mm01 >>= 1
129          psrlw %2, 1          psrlw %2, 1
   
130  %endmacro  %endmacro
131    
132    
133  ;===========================================================================  ;-----------------------------------------------------------------------------
134  ;  ;
135  ; void interpolate8x8_halfpel_h_mmx(uint8_t * const dst,  ; void interpolate8x8_halfpel_h_mmx(uint8_t * const dst,
136  ;                                               const uint8_t * const src,  ;                                               const uint8_t * const src,
137  ;                                               const uint32_t stride,  ;                                               const uint32_t stride,
138  ;                                               const uint32_t rounding);  ;                                               const uint32_t rounding);
139  ;  ;
140  ;===========================================================================  ;-----------------------------------------------------------------------------
141    
142  %macro COPY_H_MMX 0  %macro COPY_H_MMX 0
143                  movq mm0, [esi]                  movq mm0, [esi]
# Line 132  Line 157 
157                  add edi, edx            ; dst += stride                  add edi, edx            ; dst += stride
158  %endmacro  %endmacro
159    
160  align 16  ALIGN 16
161  cglobal interpolate8x8_halfpel_h_mmx  interpolate8x8_halfpel_h_mmx:
 interpolate8x8_halfpel_h_mmx  
162    
163                  push    esi                  push    esi
164                  push    edi                  push    edi
   
165                  mov     eax, [esp + 8 + 16]             ; rounding                  mov     eax, [esp + 8 + 16]             ; rounding
166    
 interpolate8x8_halfpel_h_mmx.start  
167                  movq mm7, [rounding1_mmx + eax * 8]                  movq mm7, [rounding1_mmx + eax * 8]
168    
169                  mov     edi, [esp + 8 + 4]              ; dst                  mov     edi, [esp + 8 + 4]              ; dst
# Line 163  Line 185 
185                  pop esi                  pop esi
186    
187                  ret                  ret
188    .endfunc
189    
190    
191  ;===========================================================================  ;-----------------------------------------------------------------------------
192  ;  ;
193  ; void interpolate8x8_halfpel_v_mmx(uint8_t * const dst,  ; void interpolate8x8_halfpel_v_mmx(uint8_t * const dst,
194  ;                                               const uint8_t * const src,  ;                                               const uint8_t * const src,
195  ;                                               const uint32_t stride,  ;                                               const uint32_t stride,
196  ;                                               const uint32_t rounding);  ;                                               const uint32_t rounding);
197  ;  ;
198  ;===========================================================================  ;-----------------------------------------------------------------------------
199    
200  %macro COPY_V_MMX 0  %macro COPY_V_MMX 0
201                  movq mm0, [esi]                  movq mm0, [esi]
# Line 192  Line 215 
215                  add edi, edx            ; dst += stride                  add edi, edx            ; dst += stride
216  %endmacro  %endmacro
217    
218  align 16  ALIGN 16
219  cglobal interpolate8x8_halfpel_v_mmx  interpolate8x8_halfpel_v_mmx:
 interpolate8x8_halfpel_v_mmx  
220    
221                  push    esi                  push    esi
222                  push    edi                  push    edi
223    
224                  mov     eax, [esp + 8 + 16]             ; rounding                  mov     eax, [esp + 8 + 16]             ; rounding
225    
 interpolate8x8_halfpel_v_mmx.start  
226                  movq mm7, [rounding1_mmx + eax * 8]                  movq mm7, [rounding1_mmx + eax * 8]
227    
228                  mov     edi, [esp + 8 + 4]              ; dst                  mov     edi, [esp + 8 + 4]              ; dst
# Line 224  Line 245 
245                  pop esi                  pop esi
246    
247                  ret                  ret
248    .endfunc
249    
250    
251  ;===========================================================================  ;-----------------------------------------------------------------------------
252  ;  ;
253  ; void interpolate8x8_halfpel_hv_mmx(uint8_t * const dst,  ; void interpolate8x8_halfpel_hv_mmx(uint8_t * const dst,
254  ;                                               const uint8_t * const src,  ;                                               const uint8_t * const src,
# Line 234  Line 256 
256  ;                                               const uint32_t rounding);  ;                                               const uint32_t rounding);
257  ;  ;
258  ;  ;
259  ;===========================================================================  ;-----------------------------------------------------------------------------
260    
261  %macro COPY_HV_MMX 0  %macro COPY_HV_MMX 0
262                  ; current row                  ; current row
   
263                  movq mm0, [esi]                  movq mm0, [esi]
264                  movq mm2, [esi + 1]                  movq mm2, [esi + 1]
265    
# Line 254  Line 275 
275                  paddusw mm1, mm3                  paddusw mm1, mm3
276    
277                  ; next row                  ; next row
   
278                  movq mm4, [esi + edx]                  movq mm4, [esi + edx]
279                  movq mm2, [esi + edx + 1]                  movq mm2, [esi + edx + 1]
280    
# Line 270  Line 290 
290                  paddusw mm5, mm3                  paddusw mm5, mm3
291    
292                  ; add current + next row                  ; add current + next row
   
293                  paddusw mm0, mm4                ; mm01 += mm45                  paddusw mm0, mm4                ; mm01 += mm45
294                  paddusw mm1, mm5                  paddusw mm1, mm5
295                  paddusw mm0, mm7                ; mm01 += rounding2                  paddusw mm0, mm7                ; mm01 += rounding2
# Line 286  Line 305 
305                  add edi, edx            ; dst += stride                  add edi, edx            ; dst += stride
306  %endmacro  %endmacro
307    
308  align 16  ALIGN 16
309  cglobal interpolate8x8_halfpel_hv_mmx  interpolate8x8_halfpel_hv_mmx:
 interpolate8x8_halfpel_hv_mmx  
310    
311                  push    esi                  push    esi
312                  push    edi                  push    edi
313    
314                  mov     eax, [esp + 8 + 16]             ; rounding                  mov     eax, [esp + 8 + 16]             ; rounding
 interpolate8x8_halfpel_hv_mmx.start  
315    
316                  movq mm7, [rounding2_mmx + eax * 8]                  movq mm7, [rounding2_mmx + eax * 8]
317    
# Line 320  Line 337 
337                  pop esi                  pop esi
338    
339                  ret                  ret
340    .endfunc
341    
342    ;-----------------------------------------------------------------------------
343    ;
344    ; void interpolate8x8_avg2_mmx(uint8_t const *dst,
345    ;                              const uint8_t * const src1,
346    ;                              const uint8_t * const src2,
347    ;                              const uint32_t stride,
348    ;                              const uint32_t rounding,
349    ;                              const uint32_t height);
350    ;
351    ;-----------------------------------------------------------------------------
352    
353    %macro AVG2_MMX_RND0 0
354      movq mm0, [eax]           ; src1 -> mm0
355      movq mm1, [ebx]           ; src2 -> mm1
356    
357      movq mm4, [eax+edx]
358      movq mm5, [ebx+edx]
359    
360      movq mm2, mm0             ; src1 -> mm2
361      movq mm3, mm1             ; src2 -> mm3
362    
363      pand mm2, mm7             ; isolate the lsb
364      pand mm3, mm7             ; isolate the lsb
365    
366      por mm2, mm3              ; ODD(src1) OR ODD(src2) -> mm2
367    
368      movq mm3, mm4
369      movq mm6, mm5
370    
371      pand mm3, mm7
372      pand mm6, mm7
373    
374      por mm3, mm6
375    
376      pand mm0, [mmx_mask]
377      pand mm1, [mmx_mask]
378      pand mm4, [mmx_mask]
379      pand mm5, [mmx_mask]
380    
381      psrlq mm0, 1              ; src1 / 2
382      psrlq mm1, 1              ; src2 / 2
383    
384      psrlq mm4, 1
385      psrlq mm5, 1
386    
387      paddb mm0, mm1            ; src1/2 + src2/2 -> mm0
388      paddb mm0, mm2            ; correct rounding error
389    
390      paddb mm4, mm5
391      paddb mm4, mm3
392    
393      lea eax, [eax+2*edx]
394      lea ebx, [ebx+2*edx]
395    
396      movq [ecx], mm0           ; (src1 + src2 + 1) / 2 -> dst
397      movq [ecx+edx], mm4
398    %endmacro
399    
400    %macro AVG2_MMX_RND1 0
401      movq mm0, [eax]           ; src1 -> mm0
402      movq mm1, [ebx]           ; src2 -> mm1
403    
404      movq mm4, [eax+edx]
405      movq mm5, [ebx+edx]
406    
407      movq mm2, mm0             ; src1 -> mm2
408      movq mm3, mm1             ; src2 -> mm3
409    
410      pand mm2, mm7             ; isolate the lsb
411      pand mm3, mm7             ; isolate the lsb
412    
413      pand mm2, mm3             ; ODD(src1) AND ODD(src2) -> mm2
414    
415      movq mm3, mm4
416      movq mm6, mm5
417    
418      pand mm3, mm7
419      pand mm6, mm7
420    
421      pand mm3, mm6
422    
423      pand mm0, [mmx_mask]
424      pand mm1, [mmx_mask]
425      pand mm4, [mmx_mask]
426      pand mm5, [mmx_mask]
427    
428      psrlq mm0, 1              ; src1 / 2
429      psrlq mm1, 1              ; src2 / 2
430    
431      psrlq mm4, 1
432      psrlq mm5, 1
433    
434      paddb mm0, mm1            ; src1/2 + src2/2 -> mm0
435      paddb mm0, mm2            ; correct rounding error
436    
437      paddb mm4, mm5
438      paddb mm4, mm3
439    
440      lea eax, [eax+2*edx]
441      lea ebx, [ebx+2*edx]
442    
443      movq [ecx], mm0           ; (src1 + src2 + 1) / 2 -> dst
444      movq [ecx+edx], mm4
445    %endmacro
446    
447    ALIGN 16
448    interpolate8x8_avg2_mmx:
449    
450      push ebx
451    
452      mov eax, [esp + 4 + 20]   ; rounding
453      test eax, eax
454    
455      jnz near .rounding1
456    
457      mov eax, [esp + 4 + 24]   ; height -> eax
458      sub eax, 8
459      test eax, eax
460    
461      mov ecx, [esp + 4 + 4]    ; dst -> edi
462      mov eax, [esp + 4 + 8]    ; src1 -> esi
463      mov ebx, [esp + 4 + 12]   ; src2 -> eax
464      mov edx, [esp + 4 + 16]   ; stride -> edx
465    
466      movq mm7, [mmx_one]
467    
468      jz near .start0
469    
470      AVG2_MMX_RND0
471      lea ecx, [ecx+2*edx]
472    
473    .start0
474    
475      AVG2_MMX_RND0
476      lea ecx, [ecx+2*edx]
477      AVG2_MMX_RND0
478      lea ecx, [ecx+2*edx]
479      AVG2_MMX_RND0
480      lea ecx, [ecx+2*edx]
481      AVG2_MMX_RND0
482    
483      pop ebx
484      ret
485    
486    .rounding1
487      mov eax, [esp + 4 + 24]       ; height -> eax
488      sub eax, 8
489      test eax, eax
490    
491      mov ecx, [esp + 4 + 4]        ; dst -> edi
492      mov eax, [esp + 4 + 8]        ; src1 -> esi
493      mov ebx, [esp + 4 + 12]       ; src2 -> eax
494      mov edx, [esp + 4 + 16]       ; stride -> edx
495    
496      movq mm7, [mmx_one]
497    
498      jz near .start1
499    
500      AVG2_MMX_RND1
501      lea ecx, [ecx+2*edx]
502    
503    .start1
504    
505      AVG2_MMX_RND1
506      lea ecx, [ecx+2*edx]
507      AVG2_MMX_RND1
508      lea ecx, [ecx+2*edx]
509      AVG2_MMX_RND1
510      lea ecx, [ecx+2*edx]
511      AVG2_MMX_RND1
512    
513      pop ebx
514      ret
515    .endfunc
516    
517    
518    ;-----------------------------------------------------------------------------
519    ;
520    ; void interpolate8x8_avg4_mmx(uint8_t const *dst,
521    ;                              const uint8_t * const src1,
522    ;                              const uint8_t * const src2,
523    ;                              const uint8_t * const src3,
524    ;                              const uint8_t * const src4,
525    ;                              const uint32_t stride,
526    ;                              const uint32_t rounding);
527    ;
528    ;-----------------------------------------------------------------------------
529    
530    %macro AVG4_MMX_RND0 0
531      movq mm0, [eax]           ; src1 -> mm0
532      movq mm1, [ebx]           ; src2 -> mm1
533    
534      movq mm2, mm0
535      movq mm3, mm1
536    
537      pand mm2, [mmx_three]
538      pand mm3, [mmx_three]
539    
540      pand mm0, [mmx_mask2]
541      pand mm1, [mmx_mask2]
542    
543      psrlq mm0, 2
544      psrlq mm1, 2
545    
546      lea eax, [eax+edx]
547      lea ebx, [ebx+edx]
548    
549      paddb mm0, mm1
550      paddb mm2, mm3
551    
552      movq mm4, [esi]           ; src3 -> mm0
553      movq mm5, [edi]           ; src4 -> mm1
554    
555      movq mm1, mm4
556      movq mm3, mm5
557    
558      pand mm1, [mmx_three]
559      pand mm3, [mmx_three]
560    
561      pand mm4, [mmx_mask2]
562      pand mm5, [mmx_mask2]
563    
564      psrlq mm4, 2
565      psrlq mm5, 2
566    
567      paddb mm4, mm5
568      paddb mm0, mm4
569    
570      paddb mm1, mm3
571      paddb mm2, mm1
572    
573      paddb mm2, [mmx_two]
574      pand mm2, [mmx_mask2]
575    
576      psrlq mm2, 2
577      paddb mm0, mm2
578    
579      lea esi, [esi+edx]
580      lea edi, [edi+edx]
581    
582      movq [ecx], mm0           ; (src1 + src2 + src3 + src4 + 2) / 4 -> dst
583    %endmacro
584    
585    %macro AVG4_MMX_RND1 0
586      movq mm0, [eax]           ; src1 -> mm0
587      movq mm1, [ebx]           ; src2 -> mm1
588    
589      movq mm2, mm0
590      movq mm3, mm1
591    
592      pand mm2, [mmx_three]
593      pand mm3, [mmx_three]
594    
595      pand mm0, [mmx_mask2]
596      pand mm1, [mmx_mask2]
597    
598      psrlq mm0, 2
599      psrlq mm1, 2
600    
601      lea eax,[eax+edx]
602      lea ebx,[ebx+edx]
603    
604      paddb mm0, mm1
605      paddb mm2, mm3
606    
607      movq mm4, [esi]           ; src3 -> mm0
608      movq mm5, [edi]           ; src4 -> mm1
609    
610      movq mm1, mm4
611      movq mm3, mm5
612    
613      pand mm1, [mmx_three]
614      pand mm3, [mmx_three]
615    
616      pand mm4, [mmx_mask2]
617      pand mm5, [mmx_mask2]
618    
619      psrlq mm4, 2
620      psrlq mm5, 2
621    
622      paddb mm4, mm5
623      paddb mm0, mm4
624    
625      paddb mm1, mm3
626      paddb mm2, mm1
627    
628      paddb mm2, [mmx_one]
629      pand mm2, [mmx_mask2]
630    
631      psrlq mm2, 2
632      paddb mm0, mm2
633    
634      lea esi,[esi+edx]
635      lea edi,[edi+edx]
636    
637      movq [ecx], mm0           ; (src1 + src2 + src3 + src4 + 2) / 4 -> dst
638    %endmacro
639    
640    ALIGN 16
641    interpolate8x8_avg4_mmx:
642    
643      push ebx
644      push edi
645      push esi
646    
647      mov eax, [esp + 12 + 28]      ; rounding
648    
649      test eax, eax
650    
651      mov ecx, [esp + 12 + 4]       ; dst -> edi
652      mov eax, [esp + 12 + 8]       ; src1 -> esi
653      mov ebx, [esp + 12 + 12]      ; src2 -> eax
654      mov esi, [esp + 12 + 16]      ; src3 -> esi
655      mov edi, [esp + 12 + 20]      ; src4 -> edi
656      mov edx, [esp + 12 + 24]      ; stride -> edx
657    
658      movq mm7, [mmx_one]
659    
660      jnz near .rounding1
661    
662      AVG4_MMX_RND0
663      lea ecx, [ecx+edx]
664      AVG4_MMX_RND0
665      lea ecx, [ecx+edx]
666      AVG4_MMX_RND0
667      lea ecx, [ecx+edx]
668      AVG4_MMX_RND0
669      lea ecx, [ecx+edx]
670      AVG4_MMX_RND0
671      lea ecx, [ecx+edx]
672      AVG4_MMX_RND0
673      lea ecx, [ecx+edx]
674      AVG4_MMX_RND0
675      lea ecx, [ecx+edx]
676      AVG4_MMX_RND0
677    
678      pop esi
679      pop edi
680      pop ebx
681      ret
682    
683    .rounding1
684      AVG4_MMX_RND1
685      lea ecx, [ecx+edx]
686      AVG4_MMX_RND1
687      lea ecx, [ecx+edx]
688      AVG4_MMX_RND1
689      lea ecx, [ecx+edx]
690      AVG4_MMX_RND1
691      lea ecx, [ecx+edx]
692      AVG4_MMX_RND1
693      lea ecx, [ecx+edx]
694      AVG4_MMX_RND1
695      lea ecx, [ecx+edx]
696      AVG4_MMX_RND1
697      lea ecx, [ecx+edx]
698      AVG4_MMX_RND1
699    
700      pop esi
701      pop edi
702      pop ebx
703      ret
704    .endfunc
705    
706    
707    ;-----------------------------------------------------------------------------
708    ;
709    ; void interpolate8x8_6tap_lowpass_h_mmx(uint8_t const *dst,
710    ;                                        const uint8_t * const src,
711    ;                                        const uint32_t stride,
712    ;                                        const uint32_t rounding);
713    ;
714    ;-----------------------------------------------------------------------------
715    
716    %macro LOWPASS_6TAP_H_MMX 0
717      movq mm0, [eax]
718      movq mm2, [eax+1]
719    
720      movq mm1, mm0
721      movq mm3, mm2
722    
723      punpcklbw mm0, mm7
724      punpcklbw mm2, mm7
725    
726      punpckhbw mm1, mm7
727      punpckhbw mm3, mm7
728    
729      paddw mm0, mm2
730      paddw mm1, mm3
731    
732      psllw mm0, 2
733      psllw mm1, 2
734    
735      movq mm2, [eax-1]
736      movq mm4, [eax+2]
737    
738      movq mm3, mm2
739      movq mm5, mm4
740    
741      punpcklbw mm2, mm7
742      punpcklbw mm4, mm7
743    
744      punpckhbw mm3, mm7
745      punpckhbw mm5, mm7
746    
747      paddw mm2, mm4
748      paddw mm3, mm5
749    
750      psubsw mm0, mm2
751      psubsw mm1, mm3
752    
753      pmullw mm0, [mmx_five]
754      pmullw mm1, [mmx_five]
755    
756      movq mm2, [eax-2]
757      movq mm4, [eax+3]
758    
759      movq mm3, mm2
760      movq mm5, mm4
761    
762      punpcklbw mm2, mm7
763      punpcklbw mm4, mm7
764    
765      punpckhbw mm3, mm7
766      punpckhbw mm5, mm7
767    
768      paddw mm2, mm4
769      paddw mm3, mm5
770    
771      paddsw mm0, mm2
772      paddsw mm1, mm3
773    
774      paddsw mm0, mm6
775      paddsw mm1, mm6
776    
777      psraw mm0, 5
778      psraw mm1, 5
779    
780      lea eax, [eax+edx]
781      packuswb mm0, mm1
782      movq [ecx], mm0
783    %endmacro
784    
785    ALIGN 16
786    interpolate8x8_6tap_lowpass_h_mmx:
787    
788      mov eax, [esp + 16]           ; rounding
789    
790      movq mm6, [rounding_lowpass_mmx + eax * 8]
791    
792      mov ecx, [esp + 4]            ; dst -> edi
793      mov eax, [esp + 8]            ; src -> esi
794      mov edx, [esp + 12]           ; stride -> edx
795    
796      pxor mm7, mm7
797    
798      LOWPASS_6TAP_H_MMX
799      lea ecx, [ecx+edx]
800      LOWPASS_6TAP_H_MMX
801      lea ecx, [ecx+edx]
802      LOWPASS_6TAP_H_MMX
803      lea ecx, [ecx+edx]
804      LOWPASS_6TAP_H_MMX
805      lea ecx, [ecx+edx]
806      LOWPASS_6TAP_H_MMX
807      lea ecx, [ecx+edx]
808      LOWPASS_6TAP_H_MMX
809      lea ecx, [ecx+edx]
810      LOWPASS_6TAP_H_MMX
811      lea ecx, [ecx+edx]
812      LOWPASS_6TAP_H_MMX
813    
814      ret
815    .endfunc
816    
817    ;-----------------------------------------------------------------------------
818    ;
819    ; void interpolate8x8_6tap_lowpass_v_mmx(uint8_t const *dst,
820    ;                                        const uint8_t * const src,
821    ;                                        const uint32_t stride,
822    ;                                        const uint32_t rounding);
823    ;
824    ;-----------------------------------------------------------------------------
825    
826    %macro LOWPASS_6TAP_V_MMX 0
827      movq mm0, [eax]
828      movq mm2, [eax+edx]
829    
830      movq mm1, mm0
831      movq mm3, mm2
832    
833      punpcklbw mm0, mm7
834      punpcklbw mm2, mm7
835    
836      punpckhbw mm1, mm7
837      punpckhbw mm3, mm7
838    
839      paddw mm0, mm2
840      paddw mm1, mm3
841    
842      psllw mm0, 2
843      psllw mm1, 2
844    
845      movq mm4, [eax+2*edx]
846      sub eax, ebx
847      movq mm2, [eax+2*edx]
848    
849      movq mm3, mm2
850      movq mm5, mm4
851    
852      punpcklbw mm2, mm7
853      punpcklbw mm4, mm7
854    
855      punpckhbw mm3, mm7
856      punpckhbw mm5, mm7
857    
858      paddw mm2, mm4
859      paddw mm3, mm5
860    
861      psubsw mm0, mm2
862      psubsw mm1, mm3
863    
864      pmullw mm0, [mmx_five]
865      pmullw mm1, [mmx_five]
866    
867      movq mm2, [eax+edx]
868      movq mm4, [eax+2*ebx]
869    
870      movq mm3, mm2
871      movq mm5, mm4
872    
873      punpcklbw mm2, mm7
874      punpcklbw mm4, mm7
875    
876      punpckhbw mm3, mm7
877      punpckhbw mm5, mm7
878    
879      paddw mm2, mm4
880      paddw mm3, mm5
881    
882      paddsw mm0, mm2
883      paddsw mm1, mm3
884    
885      paddsw mm0, mm6
886      paddsw mm1, mm6
887    
888      psraw mm0, 5
889      psraw mm1, 5
890    
891      lea eax, [eax+4*edx]
892      packuswb mm0, mm1
893      movq [ecx], mm0
894    %endmacro
895    
896    ALIGN 16
897    interpolate8x8_6tap_lowpass_v_mmx:
898    
899      push ebx
900    
901      mov eax, [esp + 4 + 16]           ; rounding
902    
903      movq mm6, [rounding_lowpass_mmx + eax * 8]
904    
905      mov ecx, [esp + 4 + 4]            ; dst -> edi
906      mov eax, [esp + 4 + 8]            ; src -> esi
907      mov edx, [esp + 4 + 12]           ; stride -> edx
908    
909      mov ebx, edx
910      shl ebx, 1
911      add ebx, edx
912    
913      pxor mm7, mm7
914    
915      LOWPASS_6TAP_V_MMX
916      lea ecx, [ecx+edx]
917      LOWPASS_6TAP_V_MMX
918      lea ecx, [ecx+edx]
919      LOWPASS_6TAP_V_MMX
920      lea ecx, [ecx+edx]
921      LOWPASS_6TAP_V_MMX
922      lea ecx, [ecx+edx]
923      LOWPASS_6TAP_V_MMX
924      lea ecx, [ecx+edx]
925      LOWPASS_6TAP_V_MMX
926      lea ecx, [ecx+edx]
927      LOWPASS_6TAP_V_MMX
928      lea ecx, [ecx+edx]
929      LOWPASS_6TAP_V_MMX
930    
931      pop ebx
932      ret
933    .endfunc
934    
935    ;===========================================================================
936    ;
937    ; The next functions combine both source halfpel interpolation step and the
938    ; averaging (with rouding) step to avoid wasting memory bandwidth computing
939    ; intermediate halfpel images and then averaging them.
940    ;
941    ;===========================================================================
942    
943    %macro PROLOG0 0
944      mov ecx, [esp+ 4] ; Dst
945      mov eax, [esp+ 8] ; Src
946      mov edx, [esp+12] ; BpS
947    %endmacro
948    
949    %macro PROLOG 2   ; %1: Rounder, %2 load Dst-Rounder
950      pxor mm6, mm6
951      movq mm7, [%1]    ; TODO: dangerous! (eax isn't checked)
952    %if %2
953      movq mm5, [rounding1_mmx]
954    %endif
955    
956      PROLOG0
957    %endmacro
958    
959      ; performs: mm0 == (mm0+mm2)  mm1 == (mm1+mm3)
960    %macro MIX 0
961      punpcklbw mm0, mm6
962      punpcklbw mm2, mm6
963      punpckhbw mm1, mm6
964      punpckhbw mm3, mm6
965      paddusw mm0, mm2
966      paddusw mm1, mm3
967    %endmacro
968    
969    %macro MIX_DST 0
970      movq mm3, mm2
971      paddusw mm0, mm7  ; rounder
972      paddusw mm1, mm7  ; rounder
973      punpcklbw mm2, mm6
974      punpckhbw mm3, mm6
975      psrlw mm0, 1
976      psrlw mm1, 1
977    
978      paddusw mm0, mm2  ; mix Src(mm0/mm1) with Dst(mm2/mm3)
979      paddusw mm1, mm3
980      paddusw mm0, mm5
981      paddusw mm1, mm5
982      psrlw mm0, 1
983      psrlw mm1, 1
984    
985      packuswb mm0, mm1
986    %endmacro
987    
988    %macro MIX2 0
989      punpcklbw mm0, mm6
990      punpcklbw mm2, mm6
991      paddusw mm0, mm2
992      paddusw mm0, mm7
993      punpckhbw mm1, mm6
994      punpckhbw mm3, mm6
995      paddusw mm1, mm7
996      paddusw mm1, mm3
997      psrlw mm0, 1
998      psrlw mm1, 1
999    
1000      packuswb mm0, mm1
1001    %endmacro
1002    
1003    ;===========================================================================
1004    ;
1005    ; void interpolate8x8_halfpel_add_mmx(uint8_t * const dst,
1006    ;                       const uint8_t * const src,
1007    ;                       const uint32_t stride,
1008    ;                       const uint32_t rounding);
1009    ;
1010    ;
1011    ;===========================================================================
1012    
1013    %macro ADD_FF_MMX 1
1014      movq mm0, [eax]
1015      movq mm2, [ecx]
1016      movq mm1, mm0
1017      movq mm3, mm2
1018    %if (%1!=0)
1019      lea eax,[eax+%1*edx]
1020    %endif
1021      MIX
1022      paddusw mm0, mm5  ; rounder
1023      paddusw mm1, mm5  ; rounder
1024      psrlw mm0, 1
1025      psrlw mm1, 1
1026    
1027      packuswb mm0, mm1
1028      movq [ecx], mm0
1029    %if (%1!=0)
1030      lea ecx,[ecx+%1*edx]
1031    %endif
1032    %endmacro
1033    
1034    ALIGN 16
1035    interpolate8x8_halfpel_add_mmx:
1036      PROLOG rounding1_mmx, 1
1037      ADD_FF_MMX 1
1038      ADD_FF_MMX 1
1039      ADD_FF_MMX 1
1040      ADD_FF_MMX 1
1041      ADD_FF_MMX 1
1042      ADD_FF_MMX 1
1043      ADD_FF_MMX 1
1044      ADD_FF_MMX 0
1045      ret
1046    .endfunc
1047    
1048    ;===========================================================================
1049    ;
1050    ; void interpolate8x8_halfpel_h_add_mmx(uint8_t * const dst,
1051    ;                       const uint8_t * const src,
1052    ;                       const uint32_t stride,
1053    ;                       const uint32_t rounding);
1054    ;
1055    ;
1056    ;===========================================================================
1057    
1058    %macro ADD_FH_MMX 0
1059      movq mm0, [eax]
1060      movq mm2, [eax+1]
1061      movq mm1, mm0
1062      movq mm3, mm2
1063    
1064      lea eax,[eax+edx]
1065    
1066      MIX
1067      movq mm2, [ecx]   ; prepare mix with Dst[0]
1068      MIX_DST
1069      movq [ecx], mm0
1070    %endmacro
1071    
1072    ALIGN 16
1073    interpolate8x8_halfpel_h_add_mmx:
1074      PROLOG rounding1_mmx, 1
1075    
1076      ADD_FH_MMX
1077      lea ecx,[ecx+edx]
1078      ADD_FH_MMX
1079      lea ecx,[ecx+edx]
1080      ADD_FH_MMX
1081      lea ecx,[ecx+edx]
1082      ADD_FH_MMX
1083      lea ecx,[ecx+edx]
1084      ADD_FH_MMX
1085      lea ecx,[ecx+edx]
1086      ADD_FH_MMX
1087      lea ecx,[ecx+edx]
1088      ADD_FH_MMX
1089      lea ecx,[ecx+edx]
1090      ADD_FH_MMX
1091      ret
1092    .endfunc
1093    
1094    ;===========================================================================
1095    ;
1096    ; void interpolate8x8_halfpel_v_add_mmx(uint8_t * const dst,
1097    ;                       const uint8_t * const src,
1098    ;                       const uint32_t stride,
1099    ;                       const uint32_t rounding);
1100    ;
1101    ;
1102    ;===========================================================================
1103    
1104    %macro ADD_HF_MMX 0
1105      movq mm0, [eax]
1106      movq mm2, [eax+edx]
1107      movq mm1, mm0
1108      movq mm3, mm2
1109    
1110      lea eax,[eax+edx]
1111    
1112      MIX
1113      movq mm2, [ecx]   ; prepare mix with Dst[0]
1114      MIX_DST
1115      movq [ecx], mm0
1116    
1117    %endmacro
1118    
1119    ALIGN 16
1120    interpolate8x8_halfpel_v_add_mmx:
1121      PROLOG rounding1_mmx, 1
1122    
1123      ADD_HF_MMX
1124      lea ecx,[ecx+edx]
1125      ADD_HF_MMX
1126      lea ecx,[ecx+edx]
1127      ADD_HF_MMX
1128      lea ecx,[ecx+edx]
1129      ADD_HF_MMX
1130      lea ecx,[ecx+edx]
1131      ADD_HF_MMX
1132      lea ecx,[ecx+edx]
1133      ADD_HF_MMX
1134      lea ecx,[ecx+edx]
1135      ADD_HF_MMX
1136      lea ecx,[ecx+edx]
1137      ADD_HF_MMX
1138      ret
1139    .endfunc
1140    
1141    ; The trick is to correct the result of 'pavgb' with some combination of the
1142    ; lsb's of the 4 input values i,j,k,l, and their intermediate 'pavgb' (s and t).
1143    ; The boolean relations are:
1144    ;   (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
1145    ;   (i+j+k+l+2)/4 = (s+t+1)/2 - (ij|kl)&st
1146    ;   (i+j+k+l+1)/4 = (s+t+1)/2 - (ij&kl)|st
1147    ;   (i+j+k+l+0)/4 = (s+t+1)/2 - (ij|kl)|st
1148    ; with  s=(i+j+1)/2, t=(k+l+1)/2, ij = i^j, kl = k^l, st = s^t.
1149    
1150    ; Moreover, we process 2 lines at a times, for better overlapping (~15% faster).
1151    
1152    ;===========================================================================
1153    ;
1154    ; void interpolate8x8_halfpel_hv_add_mmx(uint8_t * const dst,
1155    ;                       const uint8_t * const src,
1156    ;                       const uint32_t stride,
1157    ;                       const uint32_t rounding);
1158    ;
1159    ;
1160    ;===========================================================================
1161    
1162    %macro ADD_HH_MMX 0
1163      lea eax,[eax+edx]
1164    
1165        ; transfert prev line to mm0/mm1
1166      movq mm0, mm2
1167      movq mm1, mm3
1168    
1169        ; load new line in mm2/mm3
1170      movq mm2, [eax]
1171      movq mm4, [eax+1]
1172      movq mm3, mm2
1173      movq mm5, mm4
1174    
1175      punpcklbw mm2, mm6
1176      punpcklbw mm4, mm6
1177      paddusw mm2, mm4
1178      punpckhbw mm3, mm6
1179      punpckhbw mm5, mm6
1180      paddusw mm3, mm5
1181    
1182        ; mix current line (mm2/mm3) with previous (mm0,mm1);
1183        ; we'll preserve mm2/mm3 for next line...
1184    
1185      paddusw mm0, mm2
1186      paddusw mm1, mm3
1187    
1188      movq mm4, [ecx]   ; prepare mix with Dst[0]
1189      movq mm5, mm4
1190    
1191      paddusw mm0, mm7  ; finish mixing current line
1192      paddusw mm1, mm7
1193    
1194      punpcklbw mm4, mm6
1195      punpckhbw mm5, mm6
1196    
1197      psrlw mm0, 2
1198      psrlw mm1, 2
1199    
1200      paddusw mm0, mm4  ; mix Src(mm0/mm1) with Dst(mm2/mm3)
1201      paddusw mm1, mm5
1202    
1203      paddusw mm0, [rounding1_mmx]
1204      paddusw mm1, [rounding1_mmx]
1205    
1206      psrlw mm0, 1
1207      psrlw mm1, 1
1208    
1209      packuswb mm0, mm1
1210    
1211      movq [ecx], mm0
1212    %endmacro
1213    
1214    ALIGN 16
1215    interpolate8x8_halfpel_hv_add_mmx:
1216      PROLOG rounding2_mmx, 0    ; mm5 is busy. Don't load dst-rounder
1217    
1218        ; preprocess first line
1219      movq mm0, [eax]
1220      movq mm2, [eax+1]
1221      movq mm1, mm0
1222      movq mm3, mm2
1223    
1224      punpcklbw mm0, mm6
1225      punpcklbw mm2, mm6
1226      punpckhbw mm1, mm6
1227      punpckhbw mm3, mm6
1228      paddusw mm2, mm0
1229      paddusw mm3, mm1
1230    
1231       ; Input: mm2/mm3 contains the value (Src[0]+Src[1]) of previous line
1232    
1233      ADD_HH_MMX
1234      lea ecx,[ecx+edx]
1235      ADD_HH_MMX
1236      lea ecx,[ecx+edx]
1237      ADD_HH_MMX
1238      lea ecx,[ecx+edx]
1239      ADD_HH_MMX
1240      lea ecx,[ecx+edx]
1241      ADD_HH_MMX
1242      lea ecx,[ecx+edx]
1243      ADD_HH_MMX
1244      lea ecx,[ecx+edx]
1245      ADD_HH_MMX
1246      lea ecx,[ecx+edx]
1247      ADD_HH_MMX
1248    
1249      ret
1250    .endfunc
1251    

Legend:
Removed from v.651  
changed lines
  Added in v.1540

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