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

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

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

revision 1.1, Sun Jul 7 09:41:42 2002 UTC revision 1.9, 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  ; *     xmm 8x8 block-based halfpel interpolation  ; *  - mmx 8x8 block-based halfpel interpolation -
5    ; *
6    ; *  Copyright(C) 2002 Michael Militzer <isibaar@xvid.org>
7    ; *               2002 Pascal Massimino <skal@planet-d.net>
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 15  Line 18 
18  ; *  ; *
19  ; *     You should have received a copy of the GNU General Public License  ; *     You should have received a copy of the GNU General Public License
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., 675 Mass Ave, Cambridge, MA 02139, USA.  ; *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 ; *  
 ; *************************************************************************/  
   
 ;/**************************************************************************  
 ; *  
 ; *     History:  
22  ; *  ; *
23  ; * 04.06.2002  rewrote some funcs, mostly XMM.       -Skal-  ; ****************************************************************************/
 ; *             Heavily tuned for overlap and AGI-stalls avoidance  
 ; * 04.02.2002  initial version (Isibaar)  
 ; *  
 ; *************************************************************************/  
   
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  ALIGN 16
56    mmx_one:
 mmx_one  
57  times 8 db 1  times 8 db 1
58    
59  section .text  SECTION .text
60    
61  cglobal interpolate8x8_halfpel_h_xmm  cglobal interpolate8x8_halfpel_h_xmm
62  cglobal interpolate8x8_halfpel_v_xmm  cglobal interpolate8x8_halfpel_v_xmm
63  cglobal interpolate8x8_halfpel_hv_xmm  cglobal interpolate8x8_halfpel_hv_xmm
64    
65    cglobal interpolate8x8_halfpel_add_xmm
66    cglobal interpolate8x8_halfpel_h_add_xmm
67    cglobal interpolate8x8_halfpel_v_add_xmm
68    cglobal interpolate8x8_halfpel_hv_add_xmm
69    
70  ;===========================================================================  ;===========================================================================
71  ;  ;
72  ; void interpolate8x8_halfpel_h_xmm(uint8_t * const dst,  ; void interpolate8x8_halfpel_h_xmm(uint8_t * const dst,
# Line 94  Line 106 
106          movq [ecx+edx], mm1          movq [ecx+edx], mm1
107  %endmacro  %endmacro
108    
109  align 16  ALIGN 16
110  interpolate8x8_halfpel_h_xmm:  interpolate8x8_halfpel_h_xmm:
111    
112    mov eax, [esp+16]; rounding    mov eax, [esp+16]; rounding
# Line 125  Line 137 
137    lea ecx,[ecx+2*edx]    lea ecx,[ecx+2*edx]
138    COPY_H_SSE_RND1    COPY_H_SSE_RND1
139    ret    ret
140    .endfunc
141    
142  ;===========================================================================  ;===========================================================================
143  ;  ;
# Line 164  Line 177 
177    movq [ecx+edx], mm1    movq [ecx+edx], mm1
178  %endmacro  %endmacro
179    
180  align 16  ALIGN 16
181  interpolate8x8_halfpel_v_xmm:  interpolate8x8_halfpel_v_xmm:
182    
183    mov eax, [esp+16]; rounding    mov eax, [esp+16]; rounding
# Line 174  Line 187 
187    mov edx, [esp+12] ; stride    mov edx, [esp+12] ; stride
188    
189      ; we process 2 line at a time      ; we process 2 line at a time
   
190    jnz near .rounding1    jnz near .rounding1
191    
192    COPY_V_SSE_RND0    COPY_V_SSE_RND0
# Line 200  Line 212 
212    lea ecx,[ecx+2*edx]    lea ecx,[ecx+2*edx]
213    COPY_V_SSE_RND1    COPY_V_SSE_RND1
214    ret    ret
215    .endfunc
216    
217  ;===========================================================================  ;===========================================================================
218  ;  ;
# Line 301  Line 314 
314      movq [ecx], mm0      movq [ecx], mm0
315  %endmacro  %endmacro
316    
317  align 16  ALIGN 16
318  interpolate8x8_halfpel_hv_xmm:  interpolate8x8_halfpel_hv_xmm:
319    mov eax, [esp+16] ; rounding    mov eax, [esp+16] ; rounding
320    mov ecx, [esp+ 4] ; Dst    mov ecx, [esp+ 4] ; Dst
# Line 338  Line 351 
351    add ecx, edx    add ecx, edx
352    COPY_HV_SSE_RND1    COPY_HV_SSE_RND1
353    ret    ret
354    .endfunc
355    
356    ;===========================================================================
357    ;
358    ; The next functions combine both source halfpel interpolation step and the
359    ; averaging (with rouding) step to avoid wasting memory bandwidth computing
360    ; intermediate halfpel images and then averaging them.
361    ;
362    ;===========================================================================
363    
364    %macro PROLOG0 0
365      mov ecx, [esp+ 4] ; Dst
366      mov eax, [esp+ 8] ; Src
367      mov edx, [esp+12] ; BpS
368    %endmacro
369    %macro PROLOG1 0
370      PROLOG0
371      test dword [esp+16], 1; Rounding?
372    %endmacro
373    %macro EPILOG 0
374      ret
375    %endmacro
376    
377    ;===========================================================================
378    ;
379    ; void interpolate8x8_halfpel_add_xmm(uint8_t * const dst,
380    ;                       const uint8_t * const src,
381    ;                       const uint32_t stride,
382    ;                       const uint32_t rounding);
383    ;
384    ;
385    ;===========================================================================
386    
387    %macro ADD_FF 2
388        movq mm0,  [eax+%1]
389        movq mm1,  [eax+%2]
390    ;;---
391    ;;    movq mm2, mm0
392    ;;      movq mm3, mm1
393    ;;---
394        pavgb mm0, [ecx+%1]
395        pavgb mm1, [ecx+%2]
396    ;;--
397    ;;    por mm2, [ecx+%1]
398    ;;      por mm3, [ecx+%2]
399    ;;      pand mm2, [mmx_one]
400    ;;      pand mm3, [mmx_one]
401    ;;      psubsb mm0, mm2
402    ;;      psubsb mm1, mm3
403    ;;--
404        movq [ecx+%1], mm0
405        movq [ecx+%2], mm1
406    %endmacro
407    
408    ALIGN 16
409    interpolate8x8_halfpel_add_xmm:  ; 23c
410      PROLOG1
411      ADD_FF 0, edx
412      lea eax,[eax+2*edx]
413      lea ecx,[ecx+2*edx]
414      ADD_FF 0, edx
415      lea eax,[eax+2*edx]
416      lea ecx,[ecx+2*edx]
417      ADD_FF 0, edx
418      lea eax,[eax+2*edx]
419      lea ecx,[ecx+2*edx]
420      ADD_FF 0, edx
421      EPILOG
422    .endfunc
423    
424    ;===========================================================================
425    ;
426    ; void interpolate8x8_halfpel_h_add_xmm(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    
435    %macro ADD_FH_RND0 2
436        movq mm0,  [eax+%1]
437        movq mm1,  [eax+%2]
438        pavgb mm0, [eax+%1+1]
439        pavgb mm1, [eax+%2+1]
440        pavgb mm0, [ecx+%1]
441        pavgb mm1, [ecx+%2]
442        movq [ecx+%1],mm0
443        movq [ecx+%2],mm1
444    %endmacro
445    
446    %macro ADD_FH_RND1 2
447        movq mm0,  [eax+%1]
448        movq mm1,  [eax+%2]
449        movq mm4, mm0
450        movq mm5, mm1
451        movq mm2, [eax+%1+1]
452        movq mm3, [eax+%2+1]
453        pavgb mm0, mm2
454        ; lea ??
455        pxor mm2, mm4
456        pavgb mm1, mm3
457        pxor mm3, mm5
458        pand mm2, [mmx_one]
459        pand mm3, [mmx_one]
460        psubb mm0, mm2
461        psubb mm1, mm3
462        pavgb mm0, [ecx+%1]
463        pavgb mm1, [ecx+%2]
464        movq [ecx+%1],mm0
465        movq [ecx+%2],mm1
466    %endmacro
467    
468    ALIGN 16
469    interpolate8x8_halfpel_h_add_xmm:   ; 32c
470      PROLOG1
471      jnz near .Loop1
472      ADD_FH_RND0 0, edx
473      lea eax,[eax+2*edx]
474      lea ecx,[ecx+2*edx]
475      ADD_FH_RND0 0, edx
476      lea eax,[eax+2*edx]
477      lea ecx,[ecx+2*edx]
478      ADD_FH_RND0 0, edx
479      lea eax,[eax+2*edx]
480      lea ecx,[ecx+2*edx]
481      ADD_FH_RND0 0, edx
482      EPILOG
483    
484    .Loop1
485      ; we use: (i+j)/2 = ( i+j+1 )/2 - (i^j)&1
486      ; movq mm7, [mmx_one]
487      ADD_FH_RND1 0, edx
488      lea eax,[eax+2*edx]
489      lea ecx,[ecx+2*edx]
490      ADD_FH_RND1 0, edx
491      lea eax,[eax+2*edx]
492      lea ecx,[ecx+2*edx]
493      ADD_FH_RND1 0, edx
494      lea eax,[eax+2*edx]
495      lea ecx,[ecx+2*edx]
496      ADD_FH_RND1 0, edx
497      EPILOG
498    .endfunc
499    
500    
501    ;===========================================================================
502    ;
503    ; void interpolate8x8_halfpel_v_add_xmm(uint8_t * const dst,
504    ;                       const uint8_t * const src,
505    ;                       const uint32_t stride,
506    ;                       const uint32_t rounding);
507    ;
508    ;
509    ;===========================================================================
510    
511    %macro ADD_8_HF_RND0 0
512      movq mm0,  [eax]
513      movq mm1,  [eax+edx]
514      pavgb mm0, mm1
515      pavgb mm1, [eax+2*edx]
516      lea eax,[eax+2*edx]
517      pavgb mm0, [ecx]
518      pavgb mm1, [ecx+edx]
519      movq [ecx],mm0
520      movq [ecx+edx],mm1
521    %endmacro
522    
523    %macro ADD_8_HF_RND1 0
524      movq mm1, [eax+edx]
525      movq mm2, [eax+2*edx]
526      lea eax,[eax+2*edx]
527      movq mm4, mm0
528      movq mm5, mm1
529      pavgb mm0, mm1
530      pxor mm4, mm1
531      pavgb mm1, mm2
532      pxor mm5, mm2
533      pand mm4, mm7    ; lsb's of (i^j)...
534      pand mm5, mm7    ; lsb's of (i^j)...
535      psubb mm0, mm4 ; ...are substracted from result of pavgb
536      pavgb mm0, [ecx]
537      movq [ecx], mm0
538      psubb mm1, mm5 ; ...are substracted from result of pavgb
539      pavgb mm1, [ecx+edx]
540      movq [ecx+edx], mm1
541    %endmacro
542    
543    ALIGN 16
544    interpolate8x8_halfpel_v_add_xmm:
545      PROLOG1
546    
547      jnz near .Loop1
548      pxor mm7, mm7   ; this is a NOP
549    
550      ADD_8_HF_RND0
551      lea ecx,[ecx+2*edx]
552      ADD_8_HF_RND0
553      lea ecx,[ecx+2*edx]
554      ADD_8_HF_RND0
555      lea ecx,[ecx+2*edx]
556      ADD_8_HF_RND0
557      EPILOG
558    
559    .Loop1
560      movq mm0, [eax] ; loop invariant
561      movq mm7, [mmx_one]
562    
563      ADD_8_HF_RND1
564      movq mm0, mm2
565      lea ecx,[ecx+2*edx]
566      ADD_8_HF_RND1
567      movq mm0, mm2
568      lea ecx,[ecx+2*edx]
569      ADD_8_HF_RND1
570      movq mm0, mm2
571      lea ecx,[ecx+2*edx]
572      ADD_8_HF_RND1
573      EPILOG
574    .endfunc
575    
576    ; The trick is to correct the result of 'pavgb' with some combination of the
577    ; lsb's of the 4 input values i,j,k,l, and their intermediate 'pavgb' (s and t).
578    ; The boolean relations are:
579    ;   (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
580    ;   (i+j+k+l+2)/4 = (s+t+1)/2 - (ij|kl)&st
581    ;   (i+j+k+l+1)/4 = (s+t+1)/2 - (ij&kl)|st
582    ;   (i+j+k+l+0)/4 = (s+t+1)/2 - (ij|kl)|st
583    ; with  s=(i+j+1)/2, t=(k+l+1)/2, ij = i^j, kl = k^l, st = s^t.
584    
585    ; Moreover, we process 2 lines at a times, for better overlapping (~15% faster).
586    
587    ;===========================================================================
588    ;
589    ; void interpolate8x8_halfpel_hv_add_xmm(uint8_t * const dst,
590    ;                       const uint8_t * const src,
591    ;                       const uint32_t stride,
592    ;                       const uint32_t rounding);
593    ;
594    ;
595    ;===========================================================================
596    
597    %macro ADD_HH_RND0 0
598      lea eax,[eax+edx]
599    
600      movq mm0, [eax]
601      movq mm1, [eax+1]
602    
603      movq mm6, mm0
604      pavgb mm0, mm1  ; mm0=(j+k+1)/2. preserved for next step
605      lea eax,[eax+edx]
606      pxor mm1, mm6   ; mm1=(j^k).     preserved for next step
607    
608      por mm3, mm1    ; ij |= jk
609      movq mm6, mm2
610      pxor mm6, mm0   ; mm6 = s^t
611      pand mm3, mm6   ; (ij|jk) &= st
612      pavgb mm2, mm0  ; mm2 = (s+t+1)/2
613      pand mm3, mm7   ; mask lsb
614      psubb mm2, mm3  ; apply.
615    
616      pavgb mm2, [ecx]
617      movq [ecx], mm2
618    
619      movq mm2, [eax]
620      movq mm3, [eax+1]
621      movq mm6, mm2
622      pavgb mm2, mm3  ; preserved for next iteration
623      lea ecx,[ecx+edx]
624      pxor mm3, mm6   ; preserved for next iteration
625    
626      por mm1, mm3
627      movq mm6, mm0
628      pxor mm6, mm2
629      pand mm1, mm6
630      pavgb mm0, mm2
631    
632      pand mm1, mm7
633      psubb mm0, mm1
634    
635      pavgb mm0, [ecx]
636      movq [ecx], mm0
637    %endmacro
638    
639    %macro ADD_HH_RND1 0
640      lea eax,[eax+edx]
641    
642      movq mm0, [eax]
643      movq mm1, [eax+1]
644    
645      movq mm6, mm0
646      pavgb mm0, mm1  ; mm0=(j+k+1)/2. preserved for next step
647      lea eax,[eax+edx]
648      pxor mm1, mm6   ; mm1=(j^k).     preserved for next step
649    
650      pand mm3, mm1
651      movq mm6, mm2
652      pxor mm6, mm0
653      por mm3, mm6
654      pavgb mm2, mm0
655      pand mm3, mm7
656      psubb mm2, mm3
657    
658      pavgb mm2, [ecx]
659      movq [ecx], mm2
660    
661      movq mm2, [eax]
662      movq mm3, [eax+1]
663      movq mm6, mm2
664      pavgb mm2, mm3  ; preserved for next iteration
665      lea ecx,[ecx+edx]
666      pxor mm3, mm6   ; preserved for next iteration
667    
668      pand mm1, mm3
669      movq mm6, mm0
670      pxor mm6, mm2
671      por mm1, mm6
672      pavgb mm0, mm2
673      pand mm1, mm7
674      psubb mm0, mm1
675    
676      pavgb mm0, [ecx]
677      movq [ecx], mm0
678    %endmacro
679    
680    ALIGN 16
681    interpolate8x8_halfpel_hv_add_xmm:
682      PROLOG1
683    
684      movq mm7, [mmx_one]
685    
686        ; loop invariants: mm2=(i+j+1)/2  and  mm3= i^j
687      movq mm2, [eax]
688      movq mm3, [eax+1]
689      movq mm6, mm2
690      pavgb mm2, mm3
691      pxor mm3, mm6   ; mm2/mm3 ready
692    
693      jnz near .Loop1
694    
695      ADD_HH_RND0
696      add ecx, edx
697      ADD_HH_RND0
698      add ecx, edx
699      ADD_HH_RND0
700      add ecx, edx
701      ADD_HH_RND0
702      EPILOG
703    
704    .Loop1
705      ADD_HH_RND1
706      add ecx, edx
707      ADD_HH_RND1
708      add ecx, edx
709      ADD_HH_RND1
710      add ecx, edx
711      ADD_HH_RND1
712    
713      EPILOG
714    .endfunc
715    

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.9

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