[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.5, Mon Mar 22 22:36:24 2004 UTC revision 1.12, Tue Nov 11 20:46:24 2008 UTC
# Line 26  Line 26 
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                            %define ENDFUNC .endfunc
33                    %else
34                  global _%1                  global _%1
35                  %define %1 _%1                  %define %1 _%1
36                            %define ENDFUNC
37                    %endif
38            %else
39                    %ifdef MARK_FUNCS
40                            global %1:function %1.endfunc-%1
41                            %define ENDFUNC .endfunc
42          %else          %else
43                  global %1                  global %1
44                            %define ENDFUNC
45                    %endif
46          %endif          %endif
47  %endmacro  %endmacro
48    
# Line 38  Line 51 
51  ;=============================================================================  ;=============================================================================
52    
53  %ifdef FORMAT_COFF  %ifdef FORMAT_COFF
54  SECTION .rodata data  SECTION .rodata
55  %else  %else
56  SECTION .rodata data align=16  SECTION .rodata align=16
57  %endif  %endif
58    
59  ALIGN 16  ALIGN 16
# Line 53  Line 66 
66  cglobal interpolate8x8_halfpel_v_xmm  cglobal interpolate8x8_halfpel_v_xmm
67  cglobal interpolate8x8_halfpel_hv_xmm  cglobal interpolate8x8_halfpel_hv_xmm
68    
69    cglobal interpolate8x4_halfpel_h_xmm
70    cglobal interpolate8x4_halfpel_v_xmm
71    cglobal interpolate8x4_halfpel_hv_xmm
72    
73    cglobal interpolate8x8_halfpel_add_xmm
74    cglobal interpolate8x8_halfpel_h_add_xmm
75    cglobal interpolate8x8_halfpel_v_add_xmm
76    cglobal interpolate8x8_halfpel_hv_add_xmm
77    
78  ;===========================================================================  ;===========================================================================
79  ;  ;
80  ; void interpolate8x8_halfpel_h_xmm(uint8_t * const dst,  ; void interpolate8x8_halfpel_h_xmm(uint8_t * const dst,
# Line 112  Line 134 
134    COPY_H_SSE_RND0    COPY_H_SSE_RND0
135    ret    ret
136    
137  .rounding1  .rounding1:
138   ; we use: (i+j)/2 = ( i+j+1 )/2 - (i^j)&1   ; we use: (i+j)/2 = ( i+j+1 )/2 - (i^j)&1
139    movq mm7, [mmx_one]    movq mm7, [mmx_one]
140    COPY_H_SSE_RND1    COPY_H_SSE_RND1
# Line 123  Line 145 
145    lea ecx,[ecx+2*edx]    lea ecx,[ecx+2*edx]
146    COPY_H_SSE_RND1    COPY_H_SSE_RND1
147    ret    ret
148    ENDFUNC
149    
150  ;===========================================================================  ;===========================================================================
151  ;  ;
# Line 183  Line 206 
206    COPY_V_SSE_RND0    COPY_V_SSE_RND0
207    ret    ret
208    
209  .rounding1  .rounding1:
210   ; we use: (i+j)/2 = ( i+j+1 )/2 - (i^j)&1   ; we use: (i+j)/2 = ( i+j+1 )/2 - (i^j)&1
211    movq mm7, [mmx_one]    movq mm7, [mmx_one]
212    movq mm2, [eax]       ; loop invariant    movq mm2, [eax]       ; loop invariant
# Line 197  Line 220 
220    lea ecx,[ecx+2*edx]    lea ecx,[ecx+2*edx]
221    COPY_V_SSE_RND1    COPY_V_SSE_RND1
222    ret    ret
223    ENDFUNC
224    
225  ;===========================================================================  ;===========================================================================
226  ;  ;
# Line 326  Line 350 
350    COPY_HV_SSE_RND0    COPY_HV_SSE_RND0
351    ret    ret
352    
353  .rounding1  .rounding1:
354      COPY_HV_SSE_RND1
355      add ecx, edx
356      COPY_HV_SSE_RND1
357      add ecx, edx
358    COPY_HV_SSE_RND1    COPY_HV_SSE_RND1
359    add ecx, edx    add ecx, edx
360    COPY_HV_SSE_RND1    COPY_HV_SSE_RND1
361      ret
362    ENDFUNC
363    
364    ;===========================================================================
365    ;
366    ; void interpolate8x4_halfpel_h_xmm(uint8_t * const dst,
367    ;                                               const uint8_t * const src,
368    ;                                               const uint32_t stride,
369    ;                                               const uint32_t rounding);
370    ;
371    ;===========================================================================
372    
373    ALIGN 16
374    interpolate8x4_halfpel_h_xmm:
375    
376      mov eax, [esp+16]     ; rounding
377      mov ecx, [esp+ 4]     ; Dst
378      test eax,eax
379      mov eax, [esp+ 8]     ; Src
380      mov edx, [esp+12]     ; stride
381    
382      jnz near .rounding1
383    
384      COPY_H_SSE_RND0
385      lea ecx,[ecx+2*edx]
386      COPY_H_SSE_RND0
387      ret
388    
389    .rounding1:
390     ; we use: (i+j)/2 = ( i+j+1 )/2 - (i^j)&1
391      movq mm7, [mmx_one]
392      COPY_H_SSE_RND1
393      lea ecx, [ecx+2*edx]
394      COPY_H_SSE_RND1
395      ret
396    ENDFUNC
397    
398    ;===========================================================================
399    ;
400    ; void interpolate8x4_halfpel_v_xmm(uint8_t * const dst,
401    ;                       const uint8_t * const src,
402    ;                       const uint32_t stride,
403    ;                       const uint32_t rounding);
404    ;
405    ;===========================================================================
406    
407    ALIGN 16
408    interpolate8x4_halfpel_v_xmm:
409    
410      mov eax, [esp+16]; rounding
411      mov ecx, [esp+ 4]     ; Dst
412      test eax,eax
413      mov eax, [esp+ 8]     ; Src
414      mov edx, [esp+12]     ; stride
415    
416      ; we process 2 line at a time
417      jnz near .rounding1
418    
419      COPY_V_SSE_RND0
420      lea ecx, [ecx+2*edx]
421      COPY_V_SSE_RND0
422      ret
423    
424    .rounding1:
425     ; we use: (i+j)/2 = ( i+j+1 )/2 - (i^j)&1
426      movq mm7, [mmx_one]
427      movq mm2, [eax]       ; loop invariant
428      add eax, edx
429    
430      COPY_V_SSE_RND1
431      lea ecx,[ecx+2*edx]
432      COPY_V_SSE_RND1
433      ret
434    ENDFUNC
435    
436    ;===========================================================================
437    ;
438    ; void interpolate8x4_halfpel_hv_xmm(uint8_t * const dst,
439    ;                       const uint8_t * const src,
440    ;                       const uint32_t stride,
441    ;                       const uint32_t rounding);
442    ;
443    ;
444    ;===========================================================================
445    
446    ; The trick is to correct the result of 'pavgb' with some combination of the
447    ; lsb's of the 4 input values i,j,k,l, and their intermediate 'pavgb' (s and t).
448    ; The boolean relations are:
449    ;   (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
450    ;   (i+j+k+l+2)/4 = (s+t+1)/2 - (ij|kl)&st
451    ;   (i+j+k+l+1)/4 = (s+t+1)/2 - (ij&kl)|st
452    ;   (i+j+k+l+0)/4 = (s+t+1)/2 - (ij|kl)|st
453    ; with  s=(i+j+1)/2, t=(k+l+1)/2, ij = i^j, kl = k^l, st = s^t.
454    
455    ; Moreover, we process 2 lines at a times, for better overlapping (~15% faster).
456    
457    ALIGN 16
458    interpolate8x4_halfpel_hv_xmm:
459      mov eax, [esp+16]  ; rounding
460      mov ecx, [esp+ 4]  ; Dst
461      test eax, eax
462      mov eax, [esp+ 8]  ; Src
463      mov edx, [esp+12]  ; stride
464    
465      movq mm7, [mmx_one]
466    
467        ; loop invariants: mm2=(i+j+1)/2  and  mm3= i^j
468      movq mm2, [eax]
469      movq mm3, [eax+1]
470      movq mm6, mm2
471      pavgb mm2, mm3
472      pxor mm3, mm6       ; mm2/mm3 ready
473    
474      jnz near .rounding1
475    
476      COPY_HV_SSE_RND0
477    add ecx, edx    add ecx, edx
478      COPY_HV_SSE_RND0
479      ret
480    
481    .rounding1:
482    COPY_HV_SSE_RND1    COPY_HV_SSE_RND1
483    add ecx, edx    add ecx, edx
484    COPY_HV_SSE_RND1    COPY_HV_SSE_RND1
485    ret    ret
486    ENDFUNC
487    
488    ;===========================================================================
489    ;
490    ; The next functions combine both source halfpel interpolation step and the
491    ; averaging (with rouding) step to avoid wasting memory bandwidth computing
492    ; intermediate halfpel images and then averaging them.
493    ;
494    ;===========================================================================
495    
496    %macro PROLOG0 0
497      mov ecx, [esp+ 4] ; Dst
498      mov eax, [esp+ 8] ; Src
499      mov edx, [esp+12] ; BpS
500    %endmacro
501    %macro PROLOG1 0
502      PROLOG0
503      test dword [esp+16], 1; Rounding?
504    %endmacro
505    %macro EPILOG 0
506      ret
507    %endmacro
508    
509    ;===========================================================================
510    ;
511    ; void interpolate8x8_halfpel_add_xmm(uint8_t * const dst,
512    ;                       const uint8_t * const src,
513    ;                       const uint32_t stride,
514    ;                       const uint32_t rounding);
515    ;
516    ;
517    ;===========================================================================
518    
519    %macro ADD_FF 2
520        movq mm0,  [eax+%1]
521        movq mm1,  [eax+%2]
522    ;;---
523    ;;    movq mm2, mm0
524    ;;      movq mm3, mm1
525    ;;---
526        pavgb mm0, [ecx+%1]
527        pavgb mm1, [ecx+%2]
528    ;;--
529    ;;    por mm2, [ecx+%1]
530    ;;      por mm3, [ecx+%2]
531    ;;      pand mm2, [mmx_one]
532    ;;      pand mm3, [mmx_one]
533    ;;      psubsb mm0, mm2
534    ;;      psubsb mm1, mm3
535    ;;--
536        movq [ecx+%1], mm0
537        movq [ecx+%2], mm1
538    %endmacro
539    
540    ALIGN 16
541    interpolate8x8_halfpel_add_xmm:  ; 23c
542      PROLOG1
543      ADD_FF 0, edx
544      lea eax,[eax+2*edx]
545      lea ecx,[ecx+2*edx]
546      ADD_FF 0, edx
547      lea eax,[eax+2*edx]
548      lea ecx,[ecx+2*edx]
549      ADD_FF 0, edx
550      lea eax,[eax+2*edx]
551      lea ecx,[ecx+2*edx]
552      ADD_FF 0, edx
553      EPILOG
554    ENDFUNC
555    
556    ;===========================================================================
557    ;
558    ; void interpolate8x8_halfpel_h_add_xmm(uint8_t * const dst,
559    ;                       const uint8_t * const src,
560    ;                       const uint32_t stride,
561    ;                       const uint32_t rounding);
562    ;
563    ;
564    ;===========================================================================
565    
566    
567    %macro ADD_FH_RND0 2
568        movq mm0,  [eax+%1]
569        movq mm1,  [eax+%2]
570        pavgb mm0, [eax+%1+1]
571        pavgb mm1, [eax+%2+1]
572        pavgb mm0, [ecx+%1]
573        pavgb mm1, [ecx+%2]
574        movq [ecx+%1],mm0
575        movq [ecx+%2],mm1
576    %endmacro
577    
578    %macro ADD_FH_RND1 2
579        movq mm0,  [eax+%1]
580        movq mm1,  [eax+%2]
581        movq mm4, mm0
582        movq mm5, mm1
583        movq mm2, [eax+%1+1]
584        movq mm3, [eax+%2+1]
585        pavgb mm0, mm2
586        ; lea ??
587        pxor mm2, mm4
588        pavgb mm1, mm3
589        pxor mm3, mm5
590        pand mm2, [mmx_one]
591        pand mm3, [mmx_one]
592        psubb mm0, mm2
593        psubb mm1, mm3
594        pavgb mm0, [ecx+%1]
595        pavgb mm1, [ecx+%2]
596        movq [ecx+%1],mm0
597        movq [ecx+%2],mm1
598    %endmacro
599    
600    ALIGN 16
601    interpolate8x8_halfpel_h_add_xmm:   ; 32c
602      PROLOG1
603      jnz near .Loop1
604      ADD_FH_RND0 0, edx
605      lea eax,[eax+2*edx]
606      lea ecx,[ecx+2*edx]
607      ADD_FH_RND0 0, edx
608      lea eax,[eax+2*edx]
609      lea ecx,[ecx+2*edx]
610      ADD_FH_RND0 0, edx
611      lea eax,[eax+2*edx]
612      lea ecx,[ecx+2*edx]
613      ADD_FH_RND0 0, edx
614      EPILOG
615    
616    .Loop1:
617      ; we use: (i+j)/2 = ( i+j+1 )/2 - (i^j)&1
618      ; movq mm7, [mmx_one]
619      ADD_FH_RND1 0, edx
620      lea eax,[eax+2*edx]
621      lea ecx,[ecx+2*edx]
622      ADD_FH_RND1 0, edx
623      lea eax,[eax+2*edx]
624      lea ecx,[ecx+2*edx]
625      ADD_FH_RND1 0, edx
626      lea eax,[eax+2*edx]
627      lea ecx,[ecx+2*edx]
628      ADD_FH_RND1 0, edx
629      EPILOG
630    ENDFUNC
631    
632    
633    ;===========================================================================
634    ;
635    ; void interpolate8x8_halfpel_v_add_xmm(uint8_t * const dst,
636    ;                       const uint8_t * const src,
637    ;                       const uint32_t stride,
638    ;                       const uint32_t rounding);
639    ;
640    ;
641    ;===========================================================================
642    
643    %macro ADD_8_HF_RND0 0
644      movq mm0,  [eax]
645      movq mm1,  [eax+edx]
646      pavgb mm0, mm1
647      pavgb mm1, [eax+2*edx]
648      lea eax,[eax+2*edx]
649      pavgb mm0, [ecx]
650      pavgb mm1, [ecx+edx]
651      movq [ecx],mm0
652      movq [ecx+edx],mm1
653    %endmacro
654    
655    %macro ADD_8_HF_RND1 0
656      movq mm1, [eax+edx]
657      movq mm2, [eax+2*edx]
658      lea eax,[eax+2*edx]
659      movq mm4, mm0
660      movq mm5, mm1
661      pavgb mm0, mm1
662      pxor mm4, mm1
663      pavgb mm1, mm2
664      pxor mm5, mm2
665      pand mm4, mm7    ; lsb's of (i^j)...
666      pand mm5, mm7    ; lsb's of (i^j)...
667      psubb mm0, mm4 ; ...are substracted from result of pavgb
668      pavgb mm0, [ecx]
669      movq [ecx], mm0
670      psubb mm1, mm5 ; ...are substracted from result of pavgb
671      pavgb mm1, [ecx+edx]
672      movq [ecx+edx], mm1
673    %endmacro
674    
675    ALIGN 16
676    interpolate8x8_halfpel_v_add_xmm:
677      PROLOG1
678    
679      jnz near .Loop1
680      pxor mm7, mm7   ; this is a NOP
681    
682      ADD_8_HF_RND0
683      lea ecx,[ecx+2*edx]
684      ADD_8_HF_RND0
685      lea ecx,[ecx+2*edx]
686      ADD_8_HF_RND0
687      lea ecx,[ecx+2*edx]
688      ADD_8_HF_RND0
689      EPILOG
690    
691    .Loop1:
692      movq mm0, [eax] ; loop invariant
693      movq mm7, [mmx_one]
694    
695      ADD_8_HF_RND1
696      movq mm0, mm2
697      lea ecx,[ecx+2*edx]
698      ADD_8_HF_RND1
699      movq mm0, mm2
700      lea ecx,[ecx+2*edx]
701      ADD_8_HF_RND1
702      movq mm0, mm2
703      lea ecx,[ecx+2*edx]
704      ADD_8_HF_RND1
705      EPILOG
706    ENDFUNC
707    
708    ; The trick is to correct the result of 'pavgb' with some combination of the
709    ; lsb's of the 4 input values i,j,k,l, and their intermediate 'pavgb' (s and t).
710    ; The boolean relations are:
711    ;   (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
712    ;   (i+j+k+l+2)/4 = (s+t+1)/2 - (ij|kl)&st
713    ;   (i+j+k+l+1)/4 = (s+t+1)/2 - (ij&kl)|st
714    ;   (i+j+k+l+0)/4 = (s+t+1)/2 - (ij|kl)|st
715    ; with  s=(i+j+1)/2, t=(k+l+1)/2, ij = i^j, kl = k^l, st = s^t.
716    
717    ; Moreover, we process 2 lines at a times, for better overlapping (~15% faster).
718    
719    ;===========================================================================
720    ;
721    ; void interpolate8x8_halfpel_hv_add_xmm(uint8_t * const dst,
722    ;                       const uint8_t * const src,
723    ;                       const uint32_t stride,
724    ;                       const uint32_t rounding);
725    ;
726    ;
727    ;===========================================================================
728    
729    %macro ADD_HH_RND0 0
730      lea eax,[eax+edx]
731    
732      movq mm0, [eax]
733      movq mm1, [eax+1]
734    
735      movq mm6, mm0
736      pavgb mm0, mm1  ; mm0=(j+k+1)/2. preserved for next step
737      lea eax,[eax+edx]
738      pxor mm1, mm6   ; mm1=(j^k).     preserved for next step
739    
740      por mm3, mm1    ; ij |= jk
741      movq mm6, mm2
742      pxor mm6, mm0   ; mm6 = s^t
743      pand mm3, mm6   ; (ij|jk) &= st
744      pavgb mm2, mm0  ; mm2 = (s+t+1)/2
745      pand mm3, mm7   ; mask lsb
746      psubb mm2, mm3  ; apply.
747    
748      pavgb mm2, [ecx]
749      movq [ecx], mm2
750    
751      movq mm2, [eax]
752      movq mm3, [eax+1]
753      movq mm6, mm2
754      pavgb mm2, mm3  ; preserved for next iteration
755      lea ecx,[ecx+edx]
756      pxor mm3, mm6   ; preserved for next iteration
757    
758      por mm1, mm3
759      movq mm6, mm0
760      pxor mm6, mm2
761      pand mm1, mm6
762      pavgb mm0, mm2
763    
764      pand mm1, mm7
765      psubb mm0, mm1
766    
767      pavgb mm0, [ecx]
768      movq [ecx], mm0
769    %endmacro
770    
771    %macro ADD_HH_RND1 0
772      lea eax,[eax+edx]
773    
774      movq mm0, [eax]
775      movq mm1, [eax+1]
776    
777      movq mm6, mm0
778      pavgb mm0, mm1  ; mm0=(j+k+1)/2. preserved for next step
779      lea eax,[eax+edx]
780      pxor mm1, mm6   ; mm1=(j^k).     preserved for next step
781    
782      pand mm3, mm1
783      movq mm6, mm2
784      pxor mm6, mm0
785      por mm3, mm6
786      pavgb mm2, mm0
787      pand mm3, mm7
788      psubb mm2, mm3
789    
790      pavgb mm2, [ecx]
791      movq [ecx], mm2
792    
793      movq mm2, [eax]
794      movq mm3, [eax+1]
795      movq mm6, mm2
796      pavgb mm2, mm3  ; preserved for next iteration
797      lea ecx,[ecx+edx]
798      pxor mm3, mm6   ; preserved for next iteration
799    
800      pand mm1, mm3
801      movq mm6, mm0
802      pxor mm6, mm2
803      por mm1, mm6
804      pavgb mm0, mm2
805      pand mm1, mm7
806      psubb mm0, mm1
807    
808      pavgb mm0, [ecx]
809      movq [ecx], mm0
810    %endmacro
811    
812    ALIGN 16
813    interpolate8x8_halfpel_hv_add_xmm:
814      PROLOG1
815    
816      movq mm7, [mmx_one]
817    
818        ; loop invariants: mm2=(i+j+1)/2  and  mm3= i^j
819      movq mm2, [eax]
820      movq mm3, [eax+1]
821      movq mm6, mm2
822      pavgb mm2, mm3
823      pxor mm3, mm6   ; mm2/mm3 ready
824    
825      jnz near .Loop1
826    
827      ADD_HH_RND0
828      add ecx, edx
829      ADD_HH_RND0
830      add ecx, edx
831      ADD_HH_RND0
832      add ecx, edx
833      ADD_HH_RND0
834      EPILOG
835    
836    .Loop1:
837      ADD_HH_RND1
838      add ecx, edx
839      ADD_HH_RND1
840      add ecx, edx
841      ADD_HH_RND1
842      add ecx, edx
843      ADD_HH_RND1
844    
845      EPILOG
846    ENDFUNC
847    
848    
849    %ifidn __OUTPUT_FORMAT__,elf
850    section ".note.GNU-stack" noalloc noexec nowrite progbits
851    %endif
852    

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.12

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