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

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

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

revision 1.10, Sat Oct 19 12:20:33 2002 UTC revision 1.18, Tue Sep 13 12:12:15 2005 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>
 ; *  This program is an implementation of a part of one or more MPEG-4  
 ; *  Video tools as specified in ISO/IEC 14496-2 standard.  Those intending  
 ; *  to use this software module in hardware or software products are  
 ; *  advised that its use may infringe existing patents or copyrights, and  
 ; *  any such use would be at such party's own risk.  The original  
 ; *  developer of this software module and his/her company, and subsequent  
 ; *  editors and their companies, will have no liability for use of this  
 ; *  software or modifications or derivatives thereof.  
8  ; *  ; *
9  ; *  This program is free software; you can redistribute it and/or modify  ; *  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  ; *  it under the terms of the GNU General Public License as published by
# Line 30  Line 22 
22  ; *  ; *
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  align 16  %ifdef FORMAT_COFF
50    SECTION .rodata
51    %else
52    SECTION .rodata align=16
53    %endif
54    
55  ;===========================================================================  ;-----------------------------------------------------------------------------
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 interpolate8x4_halfpel_h_mmx
109    cglobal interpolate8x4_halfpel_v_mmx
110    cglobal interpolate8x4_halfpel_hv_mmx
111    
112    cglobal interpolate8x8_avg4_mmx
113    cglobal interpolate8x8_avg2_mmx
114    
115    cglobal interpolate8x8_6tap_lowpass_h_mmx
116    cglobal interpolate8x8_6tap_lowpass_v_mmx
117    
118    cglobal interpolate8x8_halfpel_add_mmx
119    cglobal interpolate8x8_halfpel_h_add_mmx
120    cglobal interpolate8x8_halfpel_v_add_mmx
121    cglobal interpolate8x8_halfpel_hv_add_mmx
122    
123  %macro  CALC_AVG 6  %macro  CALC_AVG 6
124          punpcklbw %3, %6          punpcklbw %3, %6
# Line 77  Line 131 
131    
132          psrlw %1, 1                     ; mm01 >>= 1          psrlw %1, 1                     ; mm01 >>= 1
133          psrlw %2, 1          psrlw %2, 1
   
134  %endmacro  %endmacro
135    
136    
137  ;===========================================================================  ;-----------------------------------------------------------------------------
138  ;  ;
139  ; void interpolate8x8_halfpel_h_mmx(uint8_t * const dst,  ; void interpolate8x8_halfpel_h_mmx(uint8_t * const dst,
140  ;                                               const uint8_t * const src,  ;                                               const uint8_t * const src,
141  ;                                               const uint32_t stride,  ;                                               const uint32_t stride,
142  ;                                               const uint32_t rounding);  ;                                               const uint32_t rounding);
143  ;  ;
144  ;===========================================================================  ;-----------------------------------------------------------------------------
145    
146  %macro COPY_H_MMX 0  %macro COPY_H_MMX 0
147                  movq mm0, [esi]                  movq mm0, [esi]
# Line 108  Line 161 
161                  add edi, edx            ; dst += stride                  add edi, edx            ; dst += stride
162  %endmacro  %endmacro
163    
164  align 16  ALIGN 16
165  cglobal interpolate8x8_halfpel_h_mmx  interpolate8x8_halfpel_h_mmx:
 interpolate8x8_halfpel_h_mmx  
166    
167                  push    esi                  push    esi
168                  push    edi                  push    edi
   
169                  mov     eax, [esp + 8 + 16]             ; rounding                  mov     eax, [esp + 8 + 16]             ; rounding
170    
 interpolate8x8_halfpel_h_mmx.start  
171                  movq mm7, [rounding1_mmx + eax * 8]                  movq mm7, [rounding1_mmx + eax * 8]
172    
173                  mov     edi, [esp + 8 + 4]              ; dst                  mov     edi, [esp + 8 + 4]              ; dst
# Line 139  Line 189 
189                  pop esi                  pop esi
190    
191                  ret                  ret
192    .endfunc
193    
194    
195  ;===========================================================================  ;-----------------------------------------------------------------------------
196  ;  ;
197  ; void interpolate8x8_halfpel_v_mmx(uint8_t * const dst,  ; void interpolate8x8_halfpel_v_mmx(uint8_t * const dst,
198  ;                                               const uint8_t * const src,  ;                                               const uint8_t * const src,
199  ;                                               const uint32_t stride,  ;                                               const uint32_t stride,
200  ;                                               const uint32_t rounding);  ;                                               const uint32_t rounding);
201  ;  ;
202  ;===========================================================================  ;-----------------------------------------------------------------------------
203    
204  %macro COPY_V_MMX 0  %macro COPY_V_MMX 0
205                  movq mm0, [esi]                  movq mm0, [esi]
# Line 168  Line 219 
219                  add edi, edx            ; dst += stride                  add edi, edx            ; dst += stride
220  %endmacro  %endmacro
221    
222  align 16  ALIGN 16
223  cglobal interpolate8x8_halfpel_v_mmx  interpolate8x8_halfpel_v_mmx:
 interpolate8x8_halfpel_v_mmx  
224    
225                  push    esi                  push    esi
226                  push    edi                  push    edi
227    
228                  mov     eax, [esp + 8 + 16]             ; rounding                  mov     eax, [esp + 8 + 16]             ; rounding
229    
 interpolate8x8_halfpel_v_mmx.start  
230                  movq mm7, [rounding1_mmx + eax * 8]                  movq mm7, [rounding1_mmx + eax * 8]
231    
232                  mov     edi, [esp + 8 + 4]              ; dst                  mov     edi, [esp + 8 + 4]              ; dst
# Line 200  Line 249 
249                  pop esi                  pop esi
250    
251                  ret                  ret
252    .endfunc
253    
254    
255  ;===========================================================================  ;-----------------------------------------------------------------------------
256  ;  ;
257  ; void interpolate8x8_halfpel_hv_mmx(uint8_t * const dst,  ; void interpolate8x8_halfpel_hv_mmx(uint8_t * const dst,
258  ;                                               const uint8_t * const src,  ;                                               const uint8_t * const src,
# Line 210  Line 260 
260  ;                                               const uint32_t rounding);  ;                                               const uint32_t rounding);
261  ;  ;
262  ;  ;
263  ;===========================================================================  ;-----------------------------------------------------------------------------
264    
265  %macro COPY_HV_MMX 0  %macro COPY_HV_MMX 0
266                  ; current row                  ; current row
   
267                  movq mm0, [esi]                  movq mm0, [esi]
268                  movq mm2, [esi + 1]                  movq mm2, [esi + 1]
269    
# Line 230  Line 279 
279                  paddusw mm1, mm3                  paddusw mm1, mm3
280    
281                  ; next row                  ; next row
   
282                  movq mm4, [esi + edx]                  movq mm4, [esi + edx]
283                  movq mm2, [esi + edx + 1]                  movq mm2, [esi + edx + 1]
284    
# Line 246  Line 294 
294                  paddusw mm5, mm3                  paddusw mm5, mm3
295    
296                  ; add current + next row                  ; add current + next row
   
297                  paddusw mm0, mm4                ; mm01 += mm45                  paddusw mm0, mm4                ; mm01 += mm45
298                  paddusw mm1, mm5                  paddusw mm1, mm5
299                  paddusw mm0, mm7                ; mm01 += rounding2                  paddusw mm0, mm7                ; mm01 += rounding2
# Line 262  Line 309 
309                  add edi, edx            ; dst += stride                  add edi, edx            ; dst += stride
310  %endmacro  %endmacro
311    
312  align 16  ALIGN 16
313  cglobal interpolate8x8_halfpel_hv_mmx  interpolate8x8_halfpel_hv_mmx:
 interpolate8x8_halfpel_hv_mmx  
314    
315                  push    esi                  push    esi
316                  push    edi                  push    edi
317    
318                  mov     eax, [esp + 8 + 16]             ; rounding                  mov     eax, [esp + 8 + 16]             ; rounding
 interpolate8x8_halfpel_hv_mmx.start  
319    
320                  movq mm7, [rounding2_mmx + eax * 8]                  movq mm7, [rounding2_mmx + eax * 8]
321    
# Line 296  Line 341 
341                  pop esi                  pop esi
342    
343                  ret                  ret
344    .endfunc
345    
346    ;-----------------------------------------------------------------------------
347    ;
348    ; void interpolate8x4_halfpel_h_mmx(uint8_t * const dst,
349    ;                       const uint8_t * const src,
350    ;                       const uint32_t stride,
351    ;                       const uint32_t rounding);
352    ;
353    ;-----------------------------------------------------------------------------
354    
355    ALIGN 16
356    interpolate8x4_halfpel_h_mmx:
357    
358      push esi
359      push edi
360      mov eax, [esp + 8 + 16]       ; rounding
361    
362      movq mm7, [rounding1_mmx + eax * 8]
363    
364      mov edi, [esp + 8 + 4]        ; dst
365      mov esi, [esp + 8 + 8]        ; src
366      mov edx, [esp + 8 + 12]       ; stride
367    
368      pxor mm6, mm6                 ; zero
369    
370      COPY_H_MMX
371      COPY_H_MMX
372      COPY_H_MMX
373      COPY_H_MMX
374    
375      pop edi
376      pop esi
377    
378      ret
379    .endfunc
380    
381    
382    ;-----------------------------------------------------------------------------
383    ;
384    ; void interpolate8x4_halfpel_v_mmx(uint8_t * const dst,
385    ;                       const uint8_t * const src,
386    ;                       const uint32_t stride,
387    ;                       const uint32_t rounding);
388    ;
389    ;-----------------------------------------------------------------------------
390    
391    ALIGN 16
392    interpolate8x4_halfpel_v_mmx:
393    
394      push esi
395      push edi
396    
397      mov eax, [esp + 8 + 16]       ; rounding
398    
399      movq mm7, [rounding1_mmx + eax * 8]
400    
401      mov edi, [esp + 8 + 4]        ; dst
402      mov esi, [esp + 8 + 8]        ; src
403      mov edx, [esp + 8 + 12]       ; stride
404    
405      pxor mm6, mm6                 ; zero
406    
407    
408      COPY_V_MMX
409      COPY_V_MMX
410      COPY_V_MMX
411      COPY_V_MMX
412    
413      pop edi
414      pop esi
415    
416      ret
417    .endfunc
418    
419    
420    ;-----------------------------------------------------------------------------
421    ;
422    ; void interpolate8x4_halfpel_hv_mmx(uint8_t * const dst,
423    ;                       const uint8_t * const src,
424    ;                       const uint32_t stride,
425    ;                       const uint32_t rounding);
426    ;
427    ;
428    ;-----------------------------------------------------------------------------
429    
430    ALIGN 16
431    interpolate8x4_halfpel_hv_mmx:
432    
433      push esi
434      push edi
435    
436      mov eax, [esp + 8 + 16]   ; rounding
437    
438      movq mm7, [rounding2_mmx + eax * 8]
439    
440      mov edi, [esp + 8 + 4]    ; dst
441      mov esi, [esp + 8 + 8]    ; src
442    
443      mov eax, 8
444    
445      pxor mm6, mm6             ; zero
446    
447      mov edx, [esp + 8 + 12]   ; stride
448    
449      COPY_HV_MMX
450      COPY_HV_MMX
451      COPY_HV_MMX
452      COPY_HV_MMX
453    
454      pop edi
455      pop esi
456    
457      ret
458    .endfunc
459    
460    ;-----------------------------------------------------------------------------
461    ;
462    ; void interpolate8x8_avg2_mmx(uint8_t const *dst,
463    ;                              const uint8_t * const src1,
464    ;                              const uint8_t * const src2,
465    ;                              const uint32_t stride,
466    ;                              const uint32_t rounding,
467    ;                              const uint32_t height);
468    ;
469    ;-----------------------------------------------------------------------------
470    
471    %macro AVG2_MMX_RND0 0
472      movq mm0, [eax]           ; src1 -> mm0
473      movq mm1, [ebx]           ; src2 -> mm1
474    
475      movq mm4, [eax+edx]
476      movq mm5, [ebx+edx]
477    
478      movq mm2, mm0             ; src1 -> mm2
479      movq mm3, mm1             ; src2 -> mm3
480    
481      pand mm2, mm7             ; isolate the lsb
482      pand mm3, mm7             ; isolate the lsb
483    
484      por mm2, mm3              ; ODD(src1) OR ODD(src2) -> mm2
485    
486      movq mm3, mm4
487      movq mm6, mm5
488    
489      pand mm3, mm7
490      pand mm6, mm7
491    
492      por mm3, mm6
493    
494      pand mm0, [mmx_mask]
495      pand mm1, [mmx_mask]
496      pand mm4, [mmx_mask]
497      pand mm5, [mmx_mask]
498    
499      psrlq mm0, 1              ; src1 / 2
500      psrlq mm1, 1              ; src2 / 2
501    
502      psrlq mm4, 1
503      psrlq mm5, 1
504    
505      paddb mm0, mm1            ; src1/2 + src2/2 -> mm0
506      paddb mm0, mm2            ; correct rounding error
507    
508      paddb mm4, mm5
509      paddb mm4, mm3
510    
511      lea eax, [eax+2*edx]
512      lea ebx, [ebx+2*edx]
513    
514      movq [ecx], mm0           ; (src1 + src2 + 1) / 2 -> dst
515      movq [ecx+edx], mm4
516    %endmacro
517    
518    %macro AVG2_MMX_RND1 0
519      movq mm0, [eax]           ; src1 -> mm0
520      movq mm1, [ebx]           ; src2 -> mm1
521    
522      movq mm4, [eax+edx]
523      movq mm5, [ebx+edx]
524    
525      movq mm2, mm0             ; src1 -> mm2
526      movq mm3, mm1             ; src2 -> mm3
527    
528      pand mm2, mm7             ; isolate the lsb
529      pand mm3, mm7             ; isolate the lsb
530    
531      pand mm2, mm3             ; ODD(src1) AND ODD(src2) -> mm2
532    
533      movq mm3, mm4
534      movq mm6, mm5
535    
536      pand mm3, mm7
537      pand mm6, mm7
538    
539      pand mm3, mm6
540    
541      pand mm0, [mmx_mask]
542      pand mm1, [mmx_mask]
543      pand mm4, [mmx_mask]
544      pand mm5, [mmx_mask]
545    
546      psrlq mm0, 1              ; src1 / 2
547      psrlq mm1, 1              ; src2 / 2
548    
549      psrlq mm4, 1
550      psrlq mm5, 1
551    
552      paddb mm0, mm1            ; src1/2 + src2/2 -> mm0
553      paddb mm0, mm2            ; correct rounding error
554    
555      paddb mm4, mm5
556      paddb mm4, mm3
557    
558      lea eax, [eax+2*edx]
559      lea ebx, [ebx+2*edx]
560    
561      movq [ecx], mm0           ; (src1 + src2 + 1) / 2 -> dst
562      movq [ecx+edx], mm4
563    %endmacro
564    
565    ALIGN 16
566    interpolate8x8_avg2_mmx:
567    
568      push ebx
569    
570      mov eax, [esp + 4 + 20]   ; rounding
571      test eax, eax
572    
573      jnz near .rounding1
574    
575      mov eax, [esp + 4 + 24]   ; height -> eax
576      sub eax, 8
577      test eax, eax
578    
579      mov ecx, [esp + 4 + 4]    ; dst -> edi
580      mov eax, [esp + 4 + 8]    ; src1 -> esi
581      mov ebx, [esp + 4 + 12]   ; src2 -> eax
582      mov edx, [esp + 4 + 16]   ; stride -> edx
583    
584      movq mm7, [mmx_one]
585    
586      jz near .start0
587    
588      AVG2_MMX_RND0
589      lea ecx, [ecx+2*edx]
590    
591    .start0
592    
593      AVG2_MMX_RND0
594      lea ecx, [ecx+2*edx]
595      AVG2_MMX_RND0
596      lea ecx, [ecx+2*edx]
597      AVG2_MMX_RND0
598      lea ecx, [ecx+2*edx]
599      AVG2_MMX_RND0
600    
601      pop ebx
602      ret
603    
604    .rounding1
605      mov eax, [esp + 4 + 24]       ; height -> eax
606      sub eax, 8
607      test eax, eax
608    
609      mov ecx, [esp + 4 + 4]        ; dst -> edi
610      mov eax, [esp + 4 + 8]        ; src1 -> esi
611      mov ebx, [esp + 4 + 12]       ; src2 -> eax
612      mov edx, [esp + 4 + 16]       ; stride -> edx
613    
614      movq mm7, [mmx_one]
615    
616      jz near .start1
617    
618      AVG2_MMX_RND1
619      lea ecx, [ecx+2*edx]
620    
621    .start1
622    
623      AVG2_MMX_RND1
624      lea ecx, [ecx+2*edx]
625      AVG2_MMX_RND1
626      lea ecx, [ecx+2*edx]
627      AVG2_MMX_RND1
628      lea ecx, [ecx+2*edx]
629      AVG2_MMX_RND1
630    
631      pop ebx
632      ret
633    .endfunc
634    
635    
636    ;-----------------------------------------------------------------------------
637    ;
638    ; void interpolate8x8_avg4_mmx(uint8_t const *dst,
639    ;                              const uint8_t * const src1,
640    ;                              const uint8_t * const src2,
641    ;                              const uint8_t * const src3,
642    ;                              const uint8_t * const src4,
643    ;                              const uint32_t stride,
644    ;                              const uint32_t rounding);
645    ;
646    ;-----------------------------------------------------------------------------
647    
648    %macro AVG4_MMX_RND0 0
649      movq mm0, [eax]           ; src1 -> mm0
650      movq mm1, [ebx]           ; src2 -> mm1
651    
652      movq mm2, mm0
653      movq mm3, mm1
654    
655      pand mm2, [mmx_three]
656      pand mm3, [mmx_three]
657    
658      pand mm0, [mmx_mask2]
659      pand mm1, [mmx_mask2]
660    
661      psrlq mm0, 2
662      psrlq mm1, 2
663    
664      lea eax, [eax+edx]
665      lea ebx, [ebx+edx]
666    
667      paddb mm0, mm1
668      paddb mm2, mm3
669    
670      movq mm4, [esi]           ; src3 -> mm0
671      movq mm5, [edi]           ; src4 -> mm1
672    
673      movq mm1, mm4
674      movq mm3, mm5
675    
676      pand mm1, [mmx_three]
677      pand mm3, [mmx_three]
678    
679      pand mm4, [mmx_mask2]
680      pand mm5, [mmx_mask2]
681    
682      psrlq mm4, 2
683      psrlq mm5, 2
684    
685      paddb mm4, mm5
686      paddb mm0, mm4
687    
688      paddb mm1, mm3
689      paddb mm2, mm1
690    
691      paddb mm2, [mmx_two]
692      pand mm2, [mmx_mask2]
693    
694      psrlq mm2, 2
695      paddb mm0, mm2
696    
697      lea esi, [esi+edx]
698      lea edi, [edi+edx]
699    
700      movq [ecx], mm0           ; (src1 + src2 + src3 + src4 + 2) / 4 -> dst
701    %endmacro
702    
703    %macro AVG4_MMX_RND1 0
704      movq mm0, [eax]           ; src1 -> mm0
705      movq mm1, [ebx]           ; src2 -> mm1
706    
707      movq mm2, mm0
708      movq mm3, mm1
709    
710      pand mm2, [mmx_three]
711      pand mm3, [mmx_three]
712    
713      pand mm0, [mmx_mask2]
714      pand mm1, [mmx_mask2]
715    
716      psrlq mm0, 2
717      psrlq mm1, 2
718    
719      lea eax,[eax+edx]
720      lea ebx,[ebx+edx]
721    
722      paddb mm0, mm1
723      paddb mm2, mm3
724    
725      movq mm4, [esi]           ; src3 -> mm0
726      movq mm5, [edi]           ; src4 -> mm1
727    
728      movq mm1, mm4
729      movq mm3, mm5
730    
731      pand mm1, [mmx_three]
732      pand mm3, [mmx_three]
733    
734      pand mm4, [mmx_mask2]
735      pand mm5, [mmx_mask2]
736    
737      psrlq mm4, 2
738      psrlq mm5, 2
739    
740      paddb mm4, mm5
741      paddb mm0, mm4
742    
743      paddb mm1, mm3
744      paddb mm2, mm1
745    
746      paddb mm2, [mmx_one]
747      pand mm2, [mmx_mask2]
748    
749      psrlq mm2, 2
750      paddb mm0, mm2
751    
752      lea esi,[esi+edx]
753      lea edi,[edi+edx]
754    
755      movq [ecx], mm0           ; (src1 + src2 + src3 + src4 + 2) / 4 -> dst
756    %endmacro
757    
758    ALIGN 16
759    interpolate8x8_avg4_mmx:
760    
761      push ebx
762      push edi
763      push esi
764    
765      mov eax, [esp + 12 + 28]      ; rounding
766    
767      test eax, eax
768    
769      mov ecx, [esp + 12 + 4]       ; dst -> edi
770      mov eax, [esp + 12 + 8]       ; src1 -> esi
771      mov ebx, [esp + 12 + 12]      ; src2 -> eax
772      mov esi, [esp + 12 + 16]      ; src3 -> esi
773      mov edi, [esp + 12 + 20]      ; src4 -> edi
774      mov edx, [esp + 12 + 24]      ; stride -> edx
775    
776      movq mm7, [mmx_one]
777    
778      jnz near .rounding1
779    
780      AVG4_MMX_RND0
781      lea ecx, [ecx+edx]
782      AVG4_MMX_RND0
783      lea ecx, [ecx+edx]
784      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    
796      pop esi
797      pop edi
798      pop ebx
799      ret
800    
801    .rounding1
802      AVG4_MMX_RND1
803      lea ecx, [ecx+edx]
804      AVG4_MMX_RND1
805      lea ecx, [ecx+edx]
806      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    
818      pop esi
819      pop edi
820      pop ebx
821      ret
822    .endfunc
823    
824    
825    ;-----------------------------------------------------------------------------
826    ;
827    ; void interpolate8x8_6tap_lowpass_h_mmx(uint8_t const *dst,
828    ;                                        const uint8_t * const src,
829    ;                                        const uint32_t stride,
830    ;                                        const uint32_t rounding);
831    ;
832    ;-----------------------------------------------------------------------------
833    
834    %macro LOWPASS_6TAP_H_MMX 0
835      movq mm0, [eax]
836      movq mm2, [eax+1]
837    
838      movq mm1, mm0
839      movq mm3, mm2
840    
841      punpcklbw mm0, mm7
842      punpcklbw mm2, mm7
843    
844      punpckhbw mm1, mm7
845      punpckhbw mm3, mm7
846    
847      paddw mm0, mm2
848      paddw mm1, mm3
849    
850      psllw mm0, 2
851      psllw mm1, 2
852    
853      movq mm2, [eax-1]
854      movq mm4, [eax+2]
855    
856      movq mm3, mm2
857      movq mm5, mm4
858    
859      punpcklbw mm2, mm7
860      punpcklbw mm4, mm7
861    
862      punpckhbw mm3, mm7
863      punpckhbw mm5, mm7
864    
865      paddw mm2, mm4
866      paddw mm3, mm5
867    
868      psubsw mm0, mm2
869      psubsw mm1, mm3
870    
871      pmullw mm0, [mmx_five]
872      pmullw mm1, [mmx_five]
873    
874      movq mm2, [eax-2]
875      movq mm4, [eax+3]
876    
877      movq mm3, mm2
878      movq mm5, mm4
879    
880      punpcklbw mm2, mm7
881      punpcklbw mm4, mm7
882    
883      punpckhbw mm3, mm7
884      punpckhbw mm5, mm7
885    
886      paddw mm2, mm4
887      paddw mm3, mm5
888    
889      paddsw mm0, mm2
890      paddsw mm1, mm3
891    
892      paddsw mm0, mm6
893      paddsw mm1, mm6
894    
895      psraw mm0, 5
896      psraw mm1, 5
897    
898      lea eax, [eax+edx]
899      packuswb mm0, mm1
900      movq [ecx], mm0
901    %endmacro
902    
903    ALIGN 16
904    interpolate8x8_6tap_lowpass_h_mmx:
905    
906      mov eax, [esp + 16]           ; rounding
907    
908      movq mm6, [rounding_lowpass_mmx + eax * 8]
909    
910      mov ecx, [esp + 4]            ; dst -> edi
911      mov eax, [esp + 8]            ; src -> esi
912      mov edx, [esp + 12]           ; stride -> edx
913    
914      pxor mm7, mm7
915    
916      LOWPASS_6TAP_H_MMX
917      lea ecx, [ecx+edx]
918      LOWPASS_6TAP_H_MMX
919      lea ecx, [ecx+edx]
920      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    
932      ret
933    .endfunc
934    
935    ;-----------------------------------------------------------------------------
936    ;
937    ; void interpolate8x8_6tap_lowpass_v_mmx(uint8_t const *dst,
938    ;                                        const uint8_t * const src,
939    ;                                        const uint32_t stride,
940    ;                                        const uint32_t rounding);
941    ;
942    ;-----------------------------------------------------------------------------
943    
944    %macro LOWPASS_6TAP_V_MMX 0
945      movq mm0, [eax]
946      movq mm2, [eax+edx]
947    
948      movq mm1, mm0
949      movq mm3, mm2
950    
951      punpcklbw mm0, mm7
952      punpcklbw mm2, mm7
953    
954      punpckhbw mm1, mm7
955      punpckhbw mm3, mm7
956    
957      paddw mm0, mm2
958      paddw mm1, mm3
959    
960      psllw mm0, 2
961      psllw mm1, 2
962    
963      movq mm4, [eax+2*edx]
964      sub eax, ebx
965      movq mm2, [eax+2*edx]
966    
967      movq mm3, mm2
968      movq mm5, mm4
969    
970      punpcklbw mm2, mm7
971      punpcklbw mm4, mm7
972    
973      punpckhbw mm3, mm7
974      punpckhbw mm5, mm7
975    
976      paddw mm2, mm4
977      paddw mm3, mm5
978    
979      psubsw mm0, mm2
980      psubsw mm1, mm3
981    
982      pmullw mm0, [mmx_five]
983      pmullw mm1, [mmx_five]
984    
985      movq mm2, [eax+edx]
986      movq mm4, [eax+2*ebx]
987    
988      movq mm3, mm2
989      movq mm5, mm4
990    
991      punpcklbw mm2, mm7
992      punpcklbw mm4, mm7
993    
994      punpckhbw mm3, mm7
995      punpckhbw mm5, mm7
996    
997      paddw mm2, mm4
998      paddw mm3, mm5
999    
1000      paddsw mm0, mm2
1001      paddsw mm1, mm3
1002    
1003      paddsw mm0, mm6
1004      paddsw mm1, mm6
1005    
1006      psraw mm0, 5
1007      psraw mm1, 5
1008    
1009      lea eax, [eax+4*edx]
1010      packuswb mm0, mm1
1011      movq [ecx], mm0
1012    %endmacro
1013    
1014    ALIGN 16
1015    interpolate8x8_6tap_lowpass_v_mmx:
1016    
1017      push ebx
1018    
1019      mov eax, [esp + 4 + 16]           ; rounding
1020    
1021      movq mm6, [rounding_lowpass_mmx + eax * 8]
1022    
1023      mov ecx, [esp + 4 + 4]            ; dst -> edi
1024      mov eax, [esp + 4 + 8]            ; src -> esi
1025      mov edx, [esp + 4 + 12]           ; stride -> edx
1026    
1027      mov ebx, edx
1028      shl ebx, 1
1029      add ebx, edx
1030    
1031      pxor mm7, mm7
1032    
1033      LOWPASS_6TAP_V_MMX
1034      lea ecx, [ecx+edx]
1035      LOWPASS_6TAP_V_MMX
1036      lea ecx, [ecx+edx]
1037      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    
1049      pop ebx
1050      ret
1051    .endfunc
1052    
1053    ;===========================================================================
1054    ;
1055    ; The next functions combine both source halfpel interpolation step and the
1056    ; averaging (with rouding) step to avoid wasting memory bandwidth computing
1057    ; intermediate halfpel images and then averaging them.
1058    ;
1059    ;===========================================================================
1060    
1061    %macro PROLOG0 0
1062      mov ecx, [esp+ 4] ; Dst
1063      mov eax, [esp+ 8] ; Src
1064      mov edx, [esp+12] ; BpS
1065    %endmacro
1066    
1067    %macro PROLOG 2   ; %1: Rounder, %2 load Dst-Rounder
1068      pxor mm6, mm6
1069      movq mm7, [%1]    ; TODO: dangerous! (eax isn't checked)
1070    %if %2
1071      movq mm5, [rounding1_mmx]
1072    %endif
1073    
1074      PROLOG0
1075    %endmacro
1076    
1077      ; performs: mm0 == (mm0+mm2)  mm1 == (mm1+mm3)
1078    %macro MIX 0
1079      punpcklbw mm0, mm6
1080      punpcklbw mm2, mm6
1081      punpckhbw mm1, mm6
1082      punpckhbw mm3, mm6
1083      paddusw mm0, mm2
1084      paddusw mm1, mm3
1085    %endmacro
1086    
1087    %macro MIX_DST 0
1088      movq mm3, mm2
1089      paddusw mm0, mm7  ; rounder
1090      paddusw mm1, mm7  ; rounder
1091      punpcklbw mm2, mm6
1092      punpckhbw mm3, mm6
1093      psrlw mm0, 1
1094      psrlw mm1, 1
1095    
1096      paddusw mm0, mm2  ; mix Src(mm0/mm1) with Dst(mm2/mm3)
1097      paddusw mm1, mm3
1098      paddusw mm0, mm5
1099      paddusw mm1, mm5
1100      psrlw mm0, 1
1101      psrlw mm1, 1
1102    
1103      packuswb mm0, mm1
1104    %endmacro
1105    
1106    %macro MIX2 0
1107      punpcklbw mm0, mm6
1108      punpcklbw mm2, mm6
1109      paddusw mm0, mm2
1110      paddusw mm0, mm7
1111      punpckhbw mm1, mm6
1112      punpckhbw mm3, mm6
1113      paddusw mm1, mm7
1114      paddusw mm1, mm3
1115      psrlw mm0, 1
1116      psrlw mm1, 1
1117    
1118      packuswb mm0, mm1
1119    %endmacro
1120    
1121    ;===========================================================================
1122    ;
1123    ; void interpolate8x8_halfpel_add_mmx(uint8_t * const dst,
1124    ;                       const uint8_t * const src,
1125    ;                       const uint32_t stride,
1126    ;                       const uint32_t rounding);
1127    ;
1128    ;
1129    ;===========================================================================
1130    
1131    %macro ADD_FF_MMX 1
1132      movq mm0, [eax]
1133      movq mm2, [ecx]
1134      movq mm1, mm0
1135      movq mm3, mm2
1136    %if (%1!=0)
1137      lea eax,[eax+%1*edx]
1138    %endif
1139      MIX
1140      paddusw mm0, mm5  ; rounder
1141      paddusw mm1, mm5  ; rounder
1142      psrlw mm0, 1
1143      psrlw mm1, 1
1144    
1145      packuswb mm0, mm1
1146      movq [ecx], mm0
1147    %if (%1!=0)
1148      lea ecx,[ecx+%1*edx]
1149    %endif
1150    %endmacro
1151    
1152    ALIGN 16
1153    interpolate8x8_halfpel_add_mmx:
1154      PROLOG rounding1_mmx, 1
1155      ADD_FF_MMX 1
1156      ADD_FF_MMX 1
1157      ADD_FF_MMX 1
1158      ADD_FF_MMX 1
1159      ADD_FF_MMX 1
1160      ADD_FF_MMX 1
1161      ADD_FF_MMX 1
1162      ADD_FF_MMX 0
1163      ret
1164    .endfunc
1165    
1166    ;===========================================================================
1167    ;
1168    ; void interpolate8x8_halfpel_h_add_mmx(uint8_t * const dst,
1169    ;                       const uint8_t * const src,
1170    ;                       const uint32_t stride,
1171    ;                       const uint32_t rounding);
1172    ;
1173    ;
1174    ;===========================================================================
1175    
1176    %macro ADD_FH_MMX 0
1177      movq mm0, [eax]
1178      movq mm2, [eax+1]
1179      movq mm1, mm0
1180      movq mm3, mm2
1181    
1182      lea eax,[eax+edx]
1183    
1184      MIX
1185      movq mm2, [ecx]   ; prepare mix with Dst[0]
1186      MIX_DST
1187      movq [ecx], mm0
1188    %endmacro
1189    
1190    ALIGN 16
1191    interpolate8x8_halfpel_h_add_mmx:
1192      PROLOG rounding1_mmx, 1
1193    
1194      ADD_FH_MMX
1195      lea ecx,[ecx+edx]
1196      ADD_FH_MMX
1197      lea ecx,[ecx+edx]
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      ret
1210    .endfunc
1211    
1212    ;===========================================================================
1213    ;
1214    ; void interpolate8x8_halfpel_v_add_mmx(uint8_t * const dst,
1215    ;                       const uint8_t * const src,
1216    ;                       const uint32_t stride,
1217    ;                       const uint32_t rounding);
1218    ;
1219    ;
1220    ;===========================================================================
1221    
1222    %macro ADD_HF_MMX 0
1223      movq mm0, [eax]
1224      movq mm2, [eax+edx]
1225      movq mm1, mm0
1226      movq mm3, mm2
1227    
1228      lea eax,[eax+edx]
1229    
1230      MIX
1231      movq mm2, [ecx]   ; prepare mix with Dst[0]
1232      MIX_DST
1233      movq [ecx], mm0
1234    
1235    %endmacro
1236    
1237    ALIGN 16
1238    interpolate8x8_halfpel_v_add_mmx:
1239      PROLOG rounding1_mmx, 1
1240    
1241      ADD_HF_MMX
1242      lea ecx,[ecx+edx]
1243      ADD_HF_MMX
1244      lea ecx,[ecx+edx]
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      ret
1257    .endfunc
1258    
1259    ; The trick is to correct the result of 'pavgb' with some combination of the
1260    ; lsb's of the 4 input values i,j,k,l, and their intermediate 'pavgb' (s and t).
1261    ; The boolean relations are:
1262    ;   (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
1263    ;   (i+j+k+l+2)/4 = (s+t+1)/2 - (ij|kl)&st
1264    ;   (i+j+k+l+1)/4 = (s+t+1)/2 - (ij&kl)|st
1265    ;   (i+j+k+l+0)/4 = (s+t+1)/2 - (ij|kl)|st
1266    ; with  s=(i+j+1)/2, t=(k+l+1)/2, ij = i^j, kl = k^l, st = s^t.
1267    
1268    ; Moreover, we process 2 lines at a times, for better overlapping (~15% faster).
1269    
1270    ;===========================================================================
1271    ;
1272    ; void interpolate8x8_halfpel_hv_add_mmx(uint8_t * const dst,
1273    ;                       const uint8_t * const src,
1274    ;                       const uint32_t stride,
1275    ;                       const uint32_t rounding);
1276    ;
1277    ;
1278    ;===========================================================================
1279    
1280    %macro ADD_HH_MMX 0
1281      lea eax,[eax+edx]
1282    
1283        ; transfert prev line to mm0/mm1
1284      movq mm0, mm2
1285      movq mm1, mm3
1286    
1287        ; load new line in mm2/mm3
1288      movq mm2, [eax]
1289      movq mm4, [eax+1]
1290      movq mm3, mm2
1291      movq mm5, mm4
1292    
1293      punpcklbw mm2, mm6
1294      punpcklbw mm4, mm6
1295      paddusw mm2, mm4
1296      punpckhbw mm3, mm6
1297      punpckhbw mm5, mm6
1298      paddusw mm3, mm5
1299    
1300        ; mix current line (mm2/mm3) with previous (mm0,mm1);
1301        ; we'll preserve mm2/mm3 for next line...
1302    
1303      paddusw mm0, mm2
1304      paddusw mm1, mm3
1305    
1306      movq mm4, [ecx]   ; prepare mix with Dst[0]
1307      movq mm5, mm4
1308    
1309      paddusw mm0, mm7  ; finish mixing current line
1310      paddusw mm1, mm7
1311    
1312      punpcklbw mm4, mm6
1313      punpckhbw mm5, mm6
1314    
1315      psrlw mm0, 2
1316      psrlw mm1, 2
1317    
1318      paddusw mm0, mm4  ; mix Src(mm0/mm1) with Dst(mm2/mm3)
1319      paddusw mm1, mm5
1320    
1321      paddusw mm0, [rounding1_mmx]
1322      paddusw mm1, [rounding1_mmx]
1323    
1324      psrlw mm0, 1
1325      psrlw mm1, 1
1326    
1327      packuswb mm0, mm1
1328    
1329      movq [ecx], mm0
1330    %endmacro
1331    
1332    ALIGN 16
1333    interpolate8x8_halfpel_hv_add_mmx:
1334      PROLOG rounding2_mmx, 0    ; mm5 is busy. Don't load dst-rounder
1335    
1336        ; preprocess first line
1337      movq mm0, [eax]
1338      movq mm2, [eax+1]
1339      movq mm1, mm0
1340      movq mm3, mm2
1341    
1342      punpcklbw mm0, mm6
1343      punpcklbw mm2, mm6
1344      punpckhbw mm1, mm6
1345      punpckhbw mm3, mm6
1346      paddusw mm2, mm0
1347      paddusw mm3, mm1
1348    
1349       ; Input: mm2/mm3 contains the value (Src[0]+Src[1]) of previous line
1350    
1351      ADD_HH_MMX
1352      lea ecx,[ecx+edx]
1353      ADD_HH_MMX
1354      lea ecx,[ecx+edx]
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    
1367      ret
1368    .endfunc
1369    

Legend:
Removed from v.1.10  
changed lines
  Added in v.1.18

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