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

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

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

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

Legend:
Removed from v.1529  
changed lines
  Added in v.1530

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