[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.4.2.1, Tue Oct 28 22:23:03 2003 UTC revision 1.8, Sun Aug 22 11:46:10 2004 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
31                            %define %1 _%1:function
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
39          %else          %else
40                  global %1                  global %1
41          %endif          %endif
42            %endif
43  %endmacro  %endmacro
44    
45  ;=============================================================================  ;=============================================================================
46  ; Read only data  ; Read only data
47  ;=============================================================================  ;=============================================================================
48    
49    %ifdef FORMAT_COFF
50  SECTION .rodata  SECTION .rodata
51    %else
52    SECTION .rodata align=16
53    %endif
54    
55  ALIGN 16  ALIGN 16
56  mmx_one:  mmx_one:
# Line 49  Line 62 
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 331  Line 349 
349    add ecx, edx    add ecx, edx
350    COPY_HV_SSE_RND1    COPY_HV_SSE_RND1
351    ret    ret
352    
353    ;===========================================================================
354    ;
355    ; The next functions combine both source halfpel interpolation step and the
356    ; averaging (with rouding) step to avoid wasting memory bandwidth computing
357    ; intermediate halfpel images and then averaging them.
358    ;
359    ;===========================================================================
360    
361    %macro PROLOG0 0
362      mov ecx, [esp+ 4] ; Dst
363      mov eax, [esp+ 8] ; Src
364      mov edx, [esp+12] ; BpS
365    %endmacro
366    %macro PROLOG1 0
367      PROLOG0
368      test dword [esp+16], 1; Rounding?
369    %endmacro
370    %macro EPILOG 0
371      ret
372    %endmacro
373    
374    ;===========================================================================
375    ;
376    ; void interpolate8x8_halfpel_add_xmm(uint8_t * const dst,
377    ;                       const uint8_t * const src,
378    ;                       const uint32_t stride,
379    ;                       const uint32_t rounding);
380    ;
381    ;
382    ;===========================================================================
383    
384    %macro ADD_FF 2
385        movq mm0,  [eax+%1]
386        movq mm1,  [eax+%2]
387    ;;---
388    ;;    movq mm2, mm0
389    ;;      movq mm3, mm1
390    ;;---
391        pavgb mm0, [ecx+%1]
392        pavgb mm1, [ecx+%2]
393    ;;--
394    ;;    por mm2, [ecx+%1]
395    ;;      por mm3, [ecx+%2]
396    ;;      pand mm2, [mmx_one]
397    ;;      pand mm3, [mmx_one]
398    ;;      psubsb mm0, mm2
399    ;;      psubsb mm1, mm3
400    ;;--
401        movq [ecx+%1], mm0
402        movq [ecx+%2], mm1
403    %endmacro
404    
405    ALIGN 16
406    interpolate8x8_halfpel_add_xmm:  ; 23c
407      PROLOG1
408      ADD_FF 0, edx
409      lea eax,[eax+2*edx]
410      lea ecx,[ecx+2*edx]
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      EPILOG
419    
420    ;===========================================================================
421    ;
422    ; void interpolate8x8_halfpel_h_add_xmm(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    
431    %macro ADD_FH_RND0 2
432        movq mm0,  [eax+%1]
433        movq mm1,  [eax+%2]
434        pavgb mm0, [eax+%1+1]
435        pavgb mm1, [eax+%2+1]
436        pavgb mm0, [ecx+%1]
437        pavgb mm1, [ecx+%2]
438        movq [ecx+%1],mm0
439        movq [ecx+%2],mm1
440    %endmacro
441    
442    %macro ADD_FH_RND1 2
443        movq mm0,  [eax+%1]
444        movq mm1,  [eax+%2]
445        movq mm4, mm0
446        movq mm5, mm1
447        movq mm2, [eax+%1+1]
448        movq mm3, [eax+%2+1]
449        pavgb mm0, mm2
450        ; lea ??
451        pxor mm2, mm4
452        pavgb mm1, mm3
453        pxor mm3, mm5
454        pand mm2, [mmx_one]
455        pand mm3, [mmx_one]
456        psubb mm0, mm2
457        psubb mm1, mm3
458        pavgb mm0, [ecx+%1]
459        pavgb mm1, [ecx+%2]
460        movq [ecx+%1],mm0
461        movq [ecx+%2],mm1
462    %endmacro
463    
464    ALIGN 16
465    interpolate8x8_halfpel_h_add_xmm:   ; 32c
466      PROLOG1
467      jnz near .Loop1
468      ADD_FH_RND0 0, edx
469      lea eax,[eax+2*edx]
470      lea ecx,[ecx+2*edx]
471      ADD_FH_RND0 0, edx
472      lea eax,[eax+2*edx]
473      lea ecx,[ecx+2*edx]
474      ADD_FH_RND0 0, edx
475      lea eax,[eax+2*edx]
476      lea ecx,[ecx+2*edx]
477      ADD_FH_RND0 0, edx
478      EPILOG
479    
480    .Loop1
481      ; we use: (i+j)/2 = ( i+j+1 )/2 - (i^j)&1
482      ; movq mm7, [mmx_one]
483      ADD_FH_RND1 0, edx
484      lea eax,[eax+2*edx]
485      lea ecx,[ecx+2*edx]
486      ADD_FH_RND1 0, edx
487      lea eax,[eax+2*edx]
488      lea ecx,[ecx+2*edx]
489      ADD_FH_RND1 0, edx
490      lea eax,[eax+2*edx]
491      lea ecx,[ecx+2*edx]
492      ADD_FH_RND1 0, edx
493      EPILOG
494    
495    
496    ;===========================================================================
497    ;
498    ; void interpolate8x8_halfpel_v_add_xmm(uint8_t * const dst,
499    ;                       const uint8_t * const src,
500    ;                       const uint32_t stride,
501    ;                       const uint32_t rounding);
502    ;
503    ;
504    ;===========================================================================
505    
506    %macro ADD_8_HF_RND0 0
507      movq mm0,  [eax]
508      movq mm1,  [eax+edx]
509      pavgb mm0, mm1
510      pavgb mm1, [eax+2*edx]
511      lea eax,[eax+2*edx]
512      pavgb mm0, [ecx]
513      pavgb mm1, [ecx+edx]
514      movq [ecx],mm0
515      movq [ecx+edx],mm1
516    %endmacro
517    
518    %macro ADD_8_HF_RND1 0
519      movq mm1, [eax+edx]
520      movq mm2, [eax+2*edx]
521      lea eax,[eax+2*edx]
522      movq mm4, mm0
523      movq mm5, mm1
524      pavgb mm0, mm1
525      pxor mm4, mm1
526      pavgb mm1, mm2
527      pxor mm5, mm2
528      pand mm4, mm7    ; lsb's of (i^j)...
529      pand mm5, mm7    ; lsb's of (i^j)...
530      psubb mm0, mm4 ; ...are substracted from result of pavgb
531      pavgb mm0, [ecx]
532      movq [ecx], mm0
533      psubb mm1, mm5 ; ...are substracted from result of pavgb
534      pavgb mm1, [ecx+edx]
535      movq [ecx+edx], mm1
536    %endmacro
537    
538    ALIGN 16
539    interpolate8x8_halfpel_v_add_xmm:
540      PROLOG1
541    
542      jnz near .Loop1
543      pxor mm7, mm7   ; this is a NOP
544    
545      ADD_8_HF_RND0
546      lea ecx,[ecx+2*edx]
547      ADD_8_HF_RND0
548      lea ecx,[ecx+2*edx]
549      ADD_8_HF_RND0
550      lea ecx,[ecx+2*edx]
551      ADD_8_HF_RND0
552      EPILOG
553    
554    .Loop1
555      movq mm0, [eax] ; loop invariant
556      movq mm7, [mmx_one]
557    
558      ADD_8_HF_RND1
559      movq mm0, mm2
560      lea ecx,[ecx+2*edx]
561      ADD_8_HF_RND1
562      movq mm0, mm2
563      lea ecx,[ecx+2*edx]
564      ADD_8_HF_RND1
565      movq mm0, mm2
566      lea ecx,[ecx+2*edx]
567      ADD_8_HF_RND1
568      EPILOG
569    
570    ; The trick is to correct the result of 'pavgb' with some combination of the
571    ; lsb's of the 4 input values i,j,k,l, and their intermediate 'pavgb' (s and t).
572    ; The boolean relations are:
573    ;   (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
574    ;   (i+j+k+l+2)/4 = (s+t+1)/2 - (ij|kl)&st
575    ;   (i+j+k+l+1)/4 = (s+t+1)/2 - (ij&kl)|st
576    ;   (i+j+k+l+0)/4 = (s+t+1)/2 - (ij|kl)|st
577    ; with  s=(i+j+1)/2, t=(k+l+1)/2, ij = i^j, kl = k^l, st = s^t.
578    
579    ; Moreover, we process 2 lines at a times, for better overlapping (~15% faster).
580    
581    ;===========================================================================
582    ;
583    ; void interpolate8x8_halfpel_hv_add_xmm(uint8_t * const dst,
584    ;                       const uint8_t * const src,
585    ;                       const uint32_t stride,
586    ;                       const uint32_t rounding);
587    ;
588    ;
589    ;===========================================================================
590    
591    %macro ADD_HH_RND0 0
592      lea eax,[eax+edx]
593    
594      movq mm0, [eax]
595      movq mm1, [eax+1]
596    
597      movq mm6, mm0
598      pavgb mm0, mm1  ; mm0=(j+k+1)/2. preserved for next step
599      lea eax,[eax+edx]
600      pxor mm1, mm6   ; mm1=(j^k).     preserved for next step
601    
602      por mm3, mm1    ; ij |= jk
603      movq mm6, mm2
604      pxor mm6, mm0   ; mm6 = s^t
605      pand mm3, mm6   ; (ij|jk) &= st
606      pavgb mm2, mm0  ; mm2 = (s+t+1)/2
607      pand mm3, mm7   ; mask lsb
608      psubb mm2, mm3  ; apply.
609    
610      pavgb mm2, [ecx]
611      movq [ecx], mm2
612    
613      movq mm2, [eax]
614      movq mm3, [eax+1]
615      movq mm6, mm2
616      pavgb mm2, mm3  ; preserved for next iteration
617      lea ecx,[ecx+edx]
618      pxor mm3, mm6   ; preserved for next iteration
619    
620      por mm1, mm3
621      movq mm6, mm0
622      pxor mm6, mm2
623      pand mm1, mm6
624      pavgb mm0, mm2
625    
626      pand mm1, mm7
627      psubb mm0, mm1
628    
629      pavgb mm0, [ecx]
630      movq [ecx], mm0
631    %endmacro
632    
633    %macro ADD_HH_RND1 0
634      lea eax,[eax+edx]
635    
636      movq mm0, [eax]
637      movq mm1, [eax+1]
638    
639      movq mm6, mm0
640      pavgb mm0, mm1  ; mm0=(j+k+1)/2. preserved for next step
641      lea eax,[eax+edx]
642      pxor mm1, mm6   ; mm1=(j^k).     preserved for next step
643    
644      pand mm3, mm1
645      movq mm6, mm2
646      pxor mm6, mm0
647      por mm3, mm6
648      pavgb mm2, mm0
649      pand mm3, mm7
650      psubb mm2, mm3
651    
652      pavgb mm2, [ecx]
653      movq [ecx], mm2
654    
655      movq mm2, [eax]
656      movq mm3, [eax+1]
657      movq mm6, mm2
658      pavgb mm2, mm3  ; preserved for next iteration
659      lea ecx,[ecx+edx]
660      pxor mm3, mm6   ; preserved for next iteration
661    
662      pand mm1, mm3
663      movq mm6, mm0
664      pxor mm6, mm2
665      por mm1, mm6
666      pavgb mm0, mm2
667      pand mm1, mm7
668      psubb mm0, mm1
669    
670      pavgb mm0, [ecx]
671      movq [ecx], mm0
672    %endmacro
673    
674    ALIGN 16
675    interpolate8x8_halfpel_hv_add_xmm:
676      PROLOG1
677    
678      movq mm7, [mmx_one]
679    
680        ; loop invariants: mm2=(i+j+1)/2  and  mm3= i^j
681      movq mm2, [eax]
682      movq mm3, [eax+1]
683      movq mm6, mm2
684      pavgb mm2, mm3
685      pxor mm3, mm6   ; mm2/mm3 ready
686    
687      jnz near .Loop1
688    
689      ADD_HH_RND0
690      add ecx, edx
691      ADD_HH_RND0
692      add ecx, edx
693      ADD_HH_RND0
694      add ecx, edx
695      ADD_HH_RND0
696      EPILOG
697    
698    .Loop1
699      ADD_HH_RND1
700      add ecx, edx
701      ADD_HH_RND1
702      add ecx, edx
703      ADD_HH_RND1
704      add ecx, edx
705      ADD_HH_RND1
706    
707      EPILOG

Legend:
Removed from v.1.4.2.1  
changed lines
  Added in v.1.8

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