[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.8, Sun Jul 7 09:41:46 2002 UTC revision 1.15, Tue Aug 10 21:58:55 2004 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) 2001 Peter Ross <pross@xvid.org>
7    ; *               2002 Michael Militzer <isibaar@xvid.org>
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
 ; *  
 ; *************************************************************************/  
   
 ;/**************************************************************************  
22  ; *  ; *
23  ; *     History:  ; ****************************************************************************/
 ; *  
 ; * 06.07.2002  mmx cleanup - Isibaar  
 ; *     22.12.2001      inital version; (c)2001 peter ross <pross@cs.rmit.edu.au>  
 ; *  
 ; *************************************************************************/  
   
24    
25  bits 32  BITS 32
26    
27  %macro cglobal 1  %macro cglobal 1
28          %ifdef PREFIX          %ifdef PREFIX
# Line 40  Line 33 
33          %endif          %endif
34  %endmacro  %endmacro
35    
36  section .data  ;=============================================================================
37    ; Read only data
38    ;=============================================================================
39    
40  align 16  %ifdef FORMAT_COFF
41    SECTION .rodata
42    %else
43    SECTION .rodata align=16
44    %endif
45    
46  ;===========================================================================  ;-----------------------------------------------------------------------------
47    ; (16 - r) rounding table
48    ;-----------------------------------------------------------------------------
49    
50    ALIGN 16
51    rounding_lowpass_mmx:
52            times 4 dw 16
53            times 4 dw 15
54    
55    ;-----------------------------------------------------------------------------
56  ; (1 - r) rounding table  ; (1 - r) rounding table
57  ;===========================================================================  ;-----------------------------------------------------------------------------
58    
59  rounding1_mmx  rounding1_mmx:
60  times 4 dw 1  times 4 dw 1
61  times 4 dw 0  times 4 dw 0
62    
63  ;===========================================================================  ;-----------------------------------------------------------------------------
64  ; (2 - r) rounding table  ; (2 - r) rounding table
65  ;===========================================================================  ;-----------------------------------------------------------------------------
66    
67  rounding2_mmx  rounding2_mmx:
68  times 4 dw 2  times 4 dw 2
69  times 4 dw 1  times 4 dw 1
70    
71  mmx_one  mmx_one:
72  times 8 db 1  times 8 db 1
73    
74  section .text  mmx_two:
75            times 8 db 2
76    
77    mmx_three:
78            times 8 db 3
79    
80    mmx_five:
81            times 4 dw 5
82    
83    mmx_mask:
84            times 8 db 254
85    
86    mmx_mask2:
87            times 8 db 252
88    
89    ;=============================================================================
90    ; Code
91    ;=============================================================================
92    
93    SECTION .text
94    
95    cglobal interpolate8x8_halfpel_h_mmx
96    cglobal interpolate8x8_halfpel_v_mmx
97    cglobal interpolate8x8_halfpel_hv_mmx
98    
99    cglobal interpolate8x8_avg4_mmx
100    cglobal interpolate8x8_avg2_mmx
101    
102    cglobal interpolate8x8_6tap_lowpass_h_mmx
103    cglobal interpolate8x8_6tap_lowpass_v_mmx
104    
105    cglobal interpolate8x8_halfpel_add_mmx
106    cglobal interpolate8x8_halfpel_h_add_mmx
107    cglobal interpolate8x8_halfpel_v_add_mmx
108    cglobal interpolate8x8_halfpel_hv_add_mmx
109    
110  %macro  CALC_AVG 6  %macro  CALC_AVG 6
111          punpcklbw %3, %6          punpcklbw %3, %6
# Line 76  Line 118 
118    
119          psrlw %1, 1                     ; mm01 >>= 1          psrlw %1, 1                     ; mm01 >>= 1
120          psrlw %2, 1          psrlw %2, 1
   
121  %endmacro  %endmacro
122    
123    
124  ;===========================================================================  ;-----------------------------------------------------------------------------
125  ;  ;
126  ; void interpolate8x8_halfpel_h_mmx(uint8_t * const dst,  ; void interpolate8x8_halfpel_h_mmx(uint8_t * const dst,
127  ;                                               const uint8_t * const src,  ;                                               const uint8_t * const src,
128  ;                                               const uint32_t stride,  ;                                               const uint32_t stride,
129  ;                                               const uint32_t rounding);  ;                                               const uint32_t rounding);
130  ;  ;
131  ;===========================================================================  ;-----------------------------------------------------------------------------
132    
133  %macro COPY_H_MMX 0  %macro COPY_H_MMX 0
134                  movq mm0, [esi]                  movq mm0, [esi]
# Line 107  Line 148 
148                  add edi, edx            ; dst += stride                  add edi, edx            ; dst += stride
149  %endmacro  %endmacro
150    
151  align 16  ALIGN 16
152  cglobal interpolate8x8_halfpel_h_mmx  interpolate8x8_halfpel_h_mmx:
 interpolate8x8_halfpel_h_mmx  
153    
154                  push    esi                  push    esi
155                  push    edi                  push    edi
   
156                  mov     eax, [esp + 8 + 16]             ; rounding                  mov     eax, [esp + 8 + 16]             ; rounding
157    
 interpolate8x8_halfpel_h_mmx.start  
158                  movq mm7, [rounding1_mmx + eax * 8]                  movq mm7, [rounding1_mmx + eax * 8]
159    
160                  mov     edi, [esp + 8 + 4]              ; dst                  mov     edi, [esp + 8 + 4]              ; dst
# Line 140  Line 178 
178                  ret                  ret
179    
180    
181  ;===========================================================================  ;-----------------------------------------------------------------------------
182  ;  ;
183  ; void interpolate8x8_halfpel_v_mmx(uint8_t * const dst,  ; void interpolate8x8_halfpel_v_mmx(uint8_t * const dst,
184  ;                                               const uint8_t * const src,  ;                                               const uint8_t * const src,
185  ;                                               const uint32_t stride,  ;                                               const uint32_t stride,
186  ;                                               const uint32_t rounding);  ;                                               const uint32_t rounding);
187  ;  ;
188  ;===========================================================================  ;-----------------------------------------------------------------------------
189    
190  %macro COPY_V_MMX 0  %macro COPY_V_MMX 0
191                  movq mm0, [esi]                  movq mm0, [esi]
# Line 167  Line 205 
205                  add edi, edx            ; dst += stride                  add edi, edx            ; dst += stride
206  %endmacro  %endmacro
207    
208  align 16  ALIGN 16
209  cglobal interpolate8x8_halfpel_v_mmx  interpolate8x8_halfpel_v_mmx:
 interpolate8x8_halfpel_v_mmx  
210    
211                  push    esi                  push    esi
212                  push    edi                  push    edi
213    
214                  mov     eax, [esp + 8 + 16]             ; rounding                  mov     eax, [esp + 8 + 16]             ; rounding
215    
 interpolate8x8_halfpel_v_mmx.start  
216                  movq mm7, [rounding1_mmx + eax * 8]                  movq mm7, [rounding1_mmx + eax * 8]
217    
218                  mov     edi, [esp + 8 + 4]              ; dst                  mov     edi, [esp + 8 + 4]              ; dst
# Line 201  Line 237 
237                  ret                  ret
238    
239    
240  ;===========================================================================  ;-----------------------------------------------------------------------------
241  ;  ;
242  ; void interpolate8x8_halfpel_hv_mmx(uint8_t * const dst,  ; void interpolate8x8_halfpel_hv_mmx(uint8_t * const dst,
243  ;                                               const uint8_t * const src,  ;                                               const uint8_t * const src,
# Line 209  Line 245 
245  ;                                               const uint32_t rounding);  ;                                               const uint32_t rounding);
246  ;  ;
247  ;  ;
248  ;===========================================================================  ;-----------------------------------------------------------------------------
249    
250  %macro COPY_HV_MMX 0  %macro COPY_HV_MMX 0
251                  ; current row                  ; current row
   
252                  movq mm0, [esi]                  movq mm0, [esi]
253                  movq mm2, [esi + 1]                  movq mm2, [esi + 1]
254    
# Line 229  Line 264 
264                  paddusw mm1, mm3                  paddusw mm1, mm3
265    
266                  ; next row                  ; next row
   
267                  movq mm4, [esi + edx]                  movq mm4, [esi + edx]
268                  movq mm2, [esi + edx + 1]                  movq mm2, [esi + edx + 1]
269    
# Line 245  Line 279 
279                  paddusw mm5, mm3                  paddusw mm5, mm3
280    
281                  ; add current + next row                  ; add current + next row
   
282                  paddusw mm0, mm4                ; mm01 += mm45                  paddusw mm0, mm4                ; mm01 += mm45
283                  paddusw mm1, mm5                  paddusw mm1, mm5
284                  paddusw mm0, mm7                ; mm01 += rounding2                  paddusw mm0, mm7                ; mm01 += rounding2
# Line 261  Line 294 
294                  add edi, edx            ; dst += stride                  add edi, edx            ; dst += stride
295  %endmacro  %endmacro
296    
297  align 16  ALIGN 16
298  cglobal interpolate8x8_halfpel_hv_mmx  interpolate8x8_halfpel_hv_mmx:
 interpolate8x8_halfpel_hv_mmx  
299    
300                  push    esi                  push    esi
301                  push    edi                  push    edi
302    
303                  mov     eax, [esp + 8 + 16]             ; rounding                  mov     eax, [esp + 8 + 16]             ; rounding
 interpolate8x8_halfpel_hv_mmx.start  
304    
305                  movq mm7, [rounding2_mmx + eax * 8]                  movq mm7, [rounding2_mmx + eax * 8]
306    
# Line 295  Line 326 
326                  pop esi                  pop esi
327    
328                  ret                  ret
329    
330    ;-----------------------------------------------------------------------------
331    ;
332    ; void interpolate8x8_avg2_mmx(uint8_t const *dst,
333    ;                              const uint8_t * const src1,
334    ;                              const uint8_t * const src2,
335    ;                              const uint32_t stride,
336    ;                              const uint32_t rounding,
337    ;                              const uint32_t height);
338    ;
339    ;-----------------------------------------------------------------------------
340    
341    %macro AVG2_MMX_RND0 0
342      movq mm0, [eax]           ; src1 -> mm0
343      movq mm1, [ebx]           ; src2 -> mm1
344    
345      movq mm4, [eax+edx]
346      movq mm5, [ebx+edx]
347    
348      movq mm2, mm0             ; src1 -> mm2
349      movq mm3, mm1             ; src2 -> mm3
350    
351      pand mm2, mm7             ; isolate the lsb
352      pand mm3, mm7             ; isolate the lsb
353    
354      por mm2, mm3              ; ODD(src1) OR ODD(src2) -> mm2
355    
356      movq mm3, mm4
357      movq mm6, mm5
358    
359      pand mm3, mm7
360      pand mm6, mm7
361    
362      por mm3, mm6
363    
364      pand mm0, [mmx_mask]
365      pand mm1, [mmx_mask]
366      pand mm4, [mmx_mask]
367      pand mm5, [mmx_mask]
368    
369      psrlq mm0, 1              ; src1 / 2
370      psrlq mm1, 1              ; src2 / 2
371    
372      psrlq mm4, 1
373      psrlq mm5, 1
374    
375      paddb mm0, mm1            ; src1/2 + src2/2 -> mm0
376      paddb mm0, mm2            ; correct rounding error
377    
378      paddb mm4, mm5
379      paddb mm4, mm3
380    
381      lea eax, [eax+2*edx]
382      lea ebx, [ebx+2*edx]
383    
384      movq [ecx], mm0           ; (src1 + src2 + 1) / 2 -> dst
385      movq [ecx+edx], mm4
386    %endmacro
387    
388    %macro AVG2_MMX_RND1 0
389      movq mm0, [eax]           ; src1 -> mm0
390      movq mm1, [ebx]           ; src2 -> mm1
391    
392      movq mm4, [eax+edx]
393      movq mm5, [ebx+edx]
394    
395      movq mm2, mm0             ; src1 -> mm2
396      movq mm3, mm1             ; src2 -> mm3
397    
398      pand mm2, mm7             ; isolate the lsb
399      pand mm3, mm7             ; isolate the lsb
400    
401      pand mm2, mm3             ; ODD(src1) AND ODD(src2) -> mm2
402    
403      movq mm3, mm4
404      movq mm6, mm5
405    
406      pand mm3, mm7
407      pand mm6, mm7
408    
409      pand mm3, mm6
410    
411      pand mm0, [mmx_mask]
412      pand mm1, [mmx_mask]
413      pand mm4, [mmx_mask]
414      pand mm5, [mmx_mask]
415    
416      psrlq mm0, 1              ; src1 / 2
417      psrlq mm1, 1              ; src2 / 2
418    
419      psrlq mm4, 1
420      psrlq mm5, 1
421    
422      paddb mm0, mm1            ; src1/2 + src2/2 -> mm0
423      paddb mm0, mm2            ; correct rounding error
424    
425      paddb mm4, mm5
426      paddb mm4, mm3
427    
428      lea eax, [eax+2*edx]
429      lea ebx, [ebx+2*edx]
430    
431      movq [ecx], mm0           ; (src1 + src2 + 1) / 2 -> dst
432      movq [ecx+edx], mm4
433    %endmacro
434    
435    ALIGN 16
436    interpolate8x8_avg2_mmx:
437    
438      push ebx
439    
440      mov eax, [esp + 4 + 20]   ; rounding
441      test eax, eax
442    
443      jnz near .rounding1
444    
445      mov eax, [esp + 4 + 24]   ; height -> eax
446      sub eax, 8
447      test eax, eax
448    
449      mov ecx, [esp + 4 + 4]    ; dst -> edi
450      mov eax, [esp + 4 + 8]    ; src1 -> esi
451      mov ebx, [esp + 4 + 12]   ; src2 -> eax
452      mov edx, [esp + 4 + 16]   ; stride -> edx
453    
454      movq mm7, [mmx_one]
455    
456      jz near .start0
457    
458      AVG2_MMX_RND0
459      lea ecx, [ecx+2*edx]
460    
461    .start0
462    
463      AVG2_MMX_RND0
464      lea ecx, [ecx+2*edx]
465      AVG2_MMX_RND0
466      lea ecx, [ecx+2*edx]
467      AVG2_MMX_RND0
468      lea ecx, [ecx+2*edx]
469      AVG2_MMX_RND0
470    
471      pop ebx
472      ret
473    
474    .rounding1
475      mov eax, [esp + 4 + 24]       ; height -> eax
476      sub eax, 8
477      test eax, eax
478    
479      mov ecx, [esp + 4 + 4]        ; dst -> edi
480      mov eax, [esp + 4 + 8]        ; src1 -> esi
481      mov ebx, [esp + 4 + 12]       ; src2 -> eax
482      mov edx, [esp + 4 + 16]       ; stride -> edx
483    
484      movq mm7, [mmx_one]
485    
486      jz near .start1
487    
488      AVG2_MMX_RND1
489      lea ecx, [ecx+2*edx]
490    
491    .start1
492    
493      AVG2_MMX_RND1
494      lea ecx, [ecx+2*edx]
495      AVG2_MMX_RND1
496      lea ecx, [ecx+2*edx]
497      AVG2_MMX_RND1
498      lea ecx, [ecx+2*edx]
499      AVG2_MMX_RND1
500    
501      pop ebx
502      ret
503    
504    
505    ;-----------------------------------------------------------------------------
506    ;
507    ; void interpolate8x8_avg4_mmx(uint8_t const *dst,
508    ;                              const uint8_t * const src1,
509    ;                              const uint8_t * const src2,
510    ;                              const uint8_t * const src3,
511    ;                              const uint8_t * const src4,
512    ;                              const uint32_t stride,
513    ;                              const uint32_t rounding);
514    ;
515    ;-----------------------------------------------------------------------------
516    
517    %macro AVG4_MMX_RND0 0
518      movq mm0, [eax]           ; src1 -> mm0
519      movq mm1, [ebx]           ; src2 -> mm1
520    
521      movq mm2, mm0
522      movq mm3, mm1
523    
524      pand mm2, [mmx_three]
525      pand mm3, [mmx_three]
526    
527      pand mm0, [mmx_mask2]
528      pand mm1, [mmx_mask2]
529    
530      psrlq mm0, 2
531      psrlq mm1, 2
532    
533      lea eax, [eax+edx]
534      lea ebx, [ebx+edx]
535    
536      paddb mm0, mm1
537      paddb mm2, mm3
538    
539      movq mm4, [esi]           ; src3 -> mm0
540      movq mm5, [edi]           ; src4 -> mm1
541    
542      movq mm1, mm4
543      movq mm3, mm5
544    
545      pand mm1, [mmx_three]
546      pand mm3, [mmx_three]
547    
548      pand mm4, [mmx_mask2]
549      pand mm5, [mmx_mask2]
550    
551      psrlq mm4, 2
552      psrlq mm5, 2
553    
554      paddb mm4, mm5
555      paddb mm0, mm4
556    
557      paddb mm1, mm3
558      paddb mm2, mm1
559    
560      paddb mm2, [mmx_two]
561      pand mm2, [mmx_mask2]
562    
563      psrlq mm2, 2
564      paddb mm0, mm2
565    
566      lea esi, [esi+edx]
567      lea edi, [edi+edx]
568    
569      movq [ecx], mm0           ; (src1 + src2 + src3 + src4 + 2) / 4 -> dst
570    %endmacro
571    
572    %macro AVG4_MMX_RND1 0
573      movq mm0, [eax]           ; src1 -> mm0
574      movq mm1, [ebx]           ; src2 -> mm1
575    
576      movq mm2, mm0
577      movq mm3, mm1
578    
579      pand mm2, [mmx_three]
580      pand mm3, [mmx_three]
581    
582      pand mm0, [mmx_mask2]
583      pand mm1, [mmx_mask2]
584    
585      psrlq mm0, 2
586      psrlq mm1, 2
587    
588      lea eax,[eax+edx]
589      lea ebx,[ebx+edx]
590    
591      paddb mm0, mm1
592      paddb mm2, mm3
593    
594      movq mm4, [esi]           ; src3 -> mm0
595      movq mm5, [edi]           ; src4 -> mm1
596    
597      movq mm1, mm4
598      movq mm3, mm5
599    
600      pand mm1, [mmx_three]
601      pand mm3, [mmx_three]
602    
603      pand mm4, [mmx_mask2]
604      pand mm5, [mmx_mask2]
605    
606      psrlq mm4, 2
607      psrlq mm5, 2
608    
609      paddb mm4, mm5
610      paddb mm0, mm4
611    
612      paddb mm1, mm3
613      paddb mm2, mm1
614    
615      paddb mm2, [mmx_one]
616      pand mm2, [mmx_mask2]
617    
618      psrlq mm2, 2
619      paddb mm0, mm2
620    
621      lea esi,[esi+edx]
622      lea edi,[edi+edx]
623    
624      movq [ecx], mm0           ; (src1 + src2 + src3 + src4 + 2) / 4 -> dst
625    %endmacro
626    
627    ALIGN 16
628    interpolate8x8_avg4_mmx:
629    
630      push ebx
631      push edi
632      push esi
633    
634      mov eax, [esp + 12 + 28]      ; rounding
635    
636      test eax, eax
637    
638      mov ecx, [esp + 12 + 4]       ; dst -> edi
639      mov eax, [esp + 12 + 8]       ; src1 -> esi
640      mov ebx, [esp + 12 + 12]      ; src2 -> eax
641      mov esi, [esp + 12 + 16]      ; src3 -> esi
642      mov edi, [esp + 12 + 20]      ; src4 -> edi
643      mov edx, [esp + 12 + 24]      ; stride -> edx
644    
645      movq mm7, [mmx_one]
646    
647      jnz near .rounding1
648    
649      AVG4_MMX_RND0
650      lea ecx, [ecx+edx]
651      AVG4_MMX_RND0
652      lea ecx, [ecx+edx]
653      AVG4_MMX_RND0
654      lea ecx, [ecx+edx]
655      AVG4_MMX_RND0
656      lea ecx, [ecx+edx]
657      AVG4_MMX_RND0
658      lea ecx, [ecx+edx]
659      AVG4_MMX_RND0
660      lea ecx, [ecx+edx]
661      AVG4_MMX_RND0
662      lea ecx, [ecx+edx]
663      AVG4_MMX_RND0
664    
665      pop esi
666      pop edi
667      pop ebx
668      ret
669    
670    .rounding1
671      AVG4_MMX_RND1
672      lea ecx, [ecx+edx]
673      AVG4_MMX_RND1
674      lea ecx, [ecx+edx]
675      AVG4_MMX_RND1
676      lea ecx, [ecx+edx]
677      AVG4_MMX_RND1
678      lea ecx, [ecx+edx]
679      AVG4_MMX_RND1
680      lea ecx, [ecx+edx]
681      AVG4_MMX_RND1
682      lea ecx, [ecx+edx]
683      AVG4_MMX_RND1
684      lea ecx, [ecx+edx]
685      AVG4_MMX_RND1
686    
687      pop esi
688      pop edi
689      pop ebx
690      ret
691    
692    
693    ;-----------------------------------------------------------------------------
694    ;
695    ; void interpolate8x8_6tap_lowpass_h_mmx(uint8_t const *dst,
696    ;                                        const uint8_t * const src,
697    ;                                        const uint32_t stride,
698    ;                                        const uint32_t rounding);
699    ;
700    ;-----------------------------------------------------------------------------
701    
702    %macro LOWPASS_6TAP_H_MMX 0
703      movq mm0, [eax]
704      movq mm2, [eax+1]
705    
706      movq mm1, mm0
707      movq mm3, mm2
708    
709      punpcklbw mm0, mm7
710      punpcklbw mm2, mm7
711    
712      punpckhbw mm1, mm7
713      punpckhbw mm3, mm7
714    
715      paddw mm0, mm2
716      paddw mm1, mm3
717    
718      psllw mm0, 2
719      psllw mm1, 2
720    
721      movq mm2, [eax-1]
722      movq mm4, [eax+2]
723    
724      movq mm3, mm2
725      movq mm5, mm4
726    
727      punpcklbw mm2, mm7
728      punpcklbw mm4, mm7
729    
730      punpckhbw mm3, mm7
731      punpckhbw mm5, mm7
732    
733      paddw mm2, mm4
734      paddw mm3, mm5
735    
736      psubsw mm0, mm2
737      psubsw mm1, mm3
738    
739      pmullw mm0, [mmx_five]
740      pmullw mm1, [mmx_five]
741    
742      movq mm2, [eax-2]
743      movq mm4, [eax+3]
744    
745      movq mm3, mm2
746      movq mm5, mm4
747    
748      punpcklbw mm2, mm7
749      punpcklbw mm4, mm7
750    
751      punpckhbw mm3, mm7
752      punpckhbw mm5, mm7
753    
754      paddw mm2, mm4
755      paddw mm3, mm5
756    
757      paddsw mm0, mm2
758      paddsw mm1, mm3
759    
760      paddsw mm0, mm6
761      paddsw mm1, mm6
762    
763      psraw mm0, 5
764      psraw mm1, 5
765    
766      lea eax, [eax+edx]
767      packuswb mm0, mm1
768      movq [ecx], mm0
769    %endmacro
770    
771    ALIGN 16
772    interpolate8x8_6tap_lowpass_h_mmx:
773    
774      mov eax, [esp + 16]           ; rounding
775    
776      movq mm6, [rounding_lowpass_mmx + eax * 8]
777    
778      mov ecx, [esp + 4]            ; dst -> edi
779      mov eax, [esp + 8]            ; src -> esi
780      mov edx, [esp + 12]           ; stride -> edx
781    
782      pxor mm7, mm7
783    
784      LOWPASS_6TAP_H_MMX
785      lea ecx, [ecx+edx]
786      LOWPASS_6TAP_H_MMX
787      lea ecx, [ecx+edx]
788      LOWPASS_6TAP_H_MMX
789      lea ecx, [ecx+edx]
790      LOWPASS_6TAP_H_MMX
791      lea ecx, [ecx+edx]
792      LOWPASS_6TAP_H_MMX
793      lea ecx, [ecx+edx]
794      LOWPASS_6TAP_H_MMX
795      lea ecx, [ecx+edx]
796      LOWPASS_6TAP_H_MMX
797      lea ecx, [ecx+edx]
798      LOWPASS_6TAP_H_MMX
799    
800      ret
801    
802    ;-----------------------------------------------------------------------------
803    ;
804    ; void interpolate8x8_6tap_lowpass_v_mmx(uint8_t const *dst,
805    ;                                        const uint8_t * const src,
806    ;                                        const uint32_t stride,
807    ;                                        const uint32_t rounding);
808    ;
809    ;-----------------------------------------------------------------------------
810    
811    %macro LOWPASS_6TAP_V_MMX 0
812      movq mm0, [eax]
813      movq mm2, [eax+edx]
814    
815      movq mm1, mm0
816      movq mm3, mm2
817    
818      punpcklbw mm0, mm7
819      punpcklbw mm2, mm7
820    
821      punpckhbw mm1, mm7
822      punpckhbw mm3, mm7
823    
824      paddw mm0, mm2
825      paddw mm1, mm3
826    
827      psllw mm0, 2
828      psllw mm1, 2
829    
830      movq mm4, [eax+2*edx]
831      sub eax, ebx
832      movq mm2, [eax+2*edx]
833    
834      movq mm3, mm2
835      movq mm5, mm4
836    
837      punpcklbw mm2, mm7
838      punpcklbw mm4, mm7
839    
840      punpckhbw mm3, mm7
841      punpckhbw mm5, mm7
842    
843      paddw mm2, mm4
844      paddw mm3, mm5
845    
846      psubsw mm0, mm2
847      psubsw mm1, mm3
848    
849      pmullw mm0, [mmx_five]
850      pmullw mm1, [mmx_five]
851    
852      movq mm2, [eax+edx]
853      movq mm4, [eax+2*ebx]
854    
855      movq mm3, mm2
856      movq mm5, mm4
857    
858      punpcklbw mm2, mm7
859      punpcklbw mm4, mm7
860    
861      punpckhbw mm3, mm7
862      punpckhbw mm5, mm7
863    
864      paddw mm2, mm4
865      paddw mm3, mm5
866    
867      paddsw mm0, mm2
868      paddsw mm1, mm3
869    
870      paddsw mm0, mm6
871      paddsw mm1, mm6
872    
873      psraw mm0, 5
874      psraw mm1, 5
875    
876      lea eax, [eax+4*edx]
877      packuswb mm0, mm1
878      movq [ecx], mm0
879    %endmacro
880    
881    ALIGN 16
882    interpolate8x8_6tap_lowpass_v_mmx:
883    
884      push ebx
885    
886      mov eax, [esp + 4 + 16]           ; rounding
887    
888      movq mm6, [rounding_lowpass_mmx + eax * 8]
889    
890      mov ecx, [esp + 4 + 4]            ; dst -> edi
891      mov eax, [esp + 4 + 8]            ; src -> esi
892      mov edx, [esp + 4 + 12]           ; stride -> edx
893    
894      mov ebx, edx
895      shl ebx, 1
896      add ebx, edx
897    
898      pxor mm7, mm7
899    
900      LOWPASS_6TAP_V_MMX
901      lea ecx, [ecx+edx]
902      LOWPASS_6TAP_V_MMX
903      lea ecx, [ecx+edx]
904      LOWPASS_6TAP_V_MMX
905      lea ecx, [ecx+edx]
906      LOWPASS_6TAP_V_MMX
907      lea ecx, [ecx+edx]
908      LOWPASS_6TAP_V_MMX
909      lea ecx, [ecx+edx]
910      LOWPASS_6TAP_V_MMX
911      lea ecx, [ecx+edx]
912      LOWPASS_6TAP_V_MMX
913      lea ecx, [ecx+edx]
914      LOWPASS_6TAP_V_MMX
915    
916      pop ebx
917      ret
918    
919    ;===========================================================================
920    ;
921    ; The next functions combine both source halfpel interpolation step and the
922    ; averaging (with rouding) step to avoid wasting memory bandwidth computing
923    ; intermediate halfpel images and then averaging them.
924    ;
925    ;===========================================================================
926    
927    %macro PROLOG0 0
928      mov ecx, [esp+ 4] ; Dst
929      mov eax, [esp+ 8] ; Src
930      mov edx, [esp+12] ; BpS
931    %endmacro
932    
933    %macro PROLOG 2   ; %1: Rounder, %2 load Dst-Rounder
934      pxor mm6, mm6
935      movq mm7, [%1]    ; TODO: dangerous! (eax isn't checked)
936    %if %2
937      movq mm5, [rounding1_mmx]
938    %endif
939    
940      PROLOG0
941    %endmacro
942    
943      ; performs: mm0 == (mm0+mm2)  mm1 == (mm1+mm3)
944    %macro MIX 0
945      punpcklbw mm0, mm6
946      punpcklbw mm2, mm6
947      punpckhbw mm1, mm6
948      punpckhbw mm3, mm6
949      paddusw mm0, mm2
950      paddusw mm1, mm3
951    %endmacro
952    
953    %macro MIX_DST 0
954      movq mm3, mm2
955      paddusw mm0, mm7  ; rounder
956      paddusw mm1, mm7  ; rounder
957      punpcklbw mm2, mm6
958      punpckhbw mm3, mm6
959      psrlw mm0, 1
960      psrlw mm1, 1
961    
962      paddusw mm0, mm2  ; mix Src(mm0/mm1) with Dst(mm2/mm3)
963      paddusw mm1, mm3
964      paddusw mm0, mm5
965      paddusw mm1, mm5
966      psrlw mm0, 1
967      psrlw mm1, 1
968    
969      packuswb mm0, mm1
970    %endmacro
971    
972    %macro MIX2 0
973      punpcklbw mm0, mm6
974      punpcklbw mm2, mm6
975      paddusw mm0, mm2
976      paddusw mm0, mm7
977      punpckhbw mm1, mm6
978      punpckhbw mm3, mm6
979      paddusw mm1, mm7
980      paddusw mm1, mm3
981      psrlw mm0, 1
982      psrlw mm1, 1
983    
984      packuswb mm0, mm1
985    %endmacro
986    
987    ;===========================================================================
988    ;
989    ; void interpolate8x8_halfpel_add_mmx(uint8_t * const dst,
990    ;                       const uint8_t * const src,
991    ;                       const uint32_t stride,
992    ;                       const uint32_t rounding);
993    ;
994    ;
995    ;===========================================================================
996    
997    %macro ADD_FF_MMX 1
998      movq mm0, [eax]
999      movq mm2, [ecx]
1000      movq mm1, mm0
1001      movq mm3, mm2
1002    %if (%1!=0)
1003      lea eax,[eax+%1*edx]
1004    %endif
1005      MIX
1006      paddusw mm0, mm5  ; rounder
1007      paddusw mm1, mm5  ; rounder
1008      psrlw mm0, 1
1009      psrlw mm1, 1
1010    
1011      packuswb mm0, mm1
1012      movq [ecx], mm0
1013    %if (%1!=0)
1014      lea ecx,[ecx+%1*edx]
1015    %endif
1016    %endmacro
1017    
1018    ALIGN 16
1019    interpolate8x8_halfpel_add_mmx:
1020      PROLOG rounding1_mmx, 1
1021      ADD_FF_MMX 1
1022      ADD_FF_MMX 1
1023      ADD_FF_MMX 1
1024      ADD_FF_MMX 1
1025      ADD_FF_MMX 1
1026      ADD_FF_MMX 1
1027      ADD_FF_MMX 1
1028      ADD_FF_MMX 0
1029      ret
1030    
1031    ;===========================================================================
1032    ;
1033    ; void interpolate8x8_halfpel_h_add_mmx(uint8_t * const dst,
1034    ;                       const uint8_t * const src,
1035    ;                       const uint32_t stride,
1036    ;                       const uint32_t rounding);
1037    ;
1038    ;
1039    ;===========================================================================
1040    
1041    %macro ADD_FH_MMX 0
1042      movq mm0, [eax]
1043      movq mm2, [eax+1]
1044      movq mm1, mm0
1045      movq mm3, mm2
1046    
1047      lea eax,[eax+edx]
1048    
1049      MIX
1050      movq mm2, [ecx]   ; prepare mix with Dst[0]
1051      MIX_DST
1052      movq [ecx], mm0
1053    %endmacro
1054    
1055    ALIGN 16
1056    interpolate8x8_halfpel_h_add_mmx:
1057      PROLOG rounding1_mmx, 1
1058    
1059      ADD_FH_MMX
1060      lea ecx,[ecx+edx]
1061      ADD_FH_MMX
1062      lea ecx,[ecx+edx]
1063      ADD_FH_MMX
1064      lea ecx,[ecx+edx]
1065      ADD_FH_MMX
1066      lea ecx,[ecx+edx]
1067      ADD_FH_MMX
1068      lea ecx,[ecx+edx]
1069      ADD_FH_MMX
1070      lea ecx,[ecx+edx]
1071      ADD_FH_MMX
1072      lea ecx,[ecx+edx]
1073      ADD_FH_MMX
1074      ret
1075    
1076    ;===========================================================================
1077    ;
1078    ; void interpolate8x8_halfpel_v_add_mmx(uint8_t * const dst,
1079    ;                       const uint8_t * const src,
1080    ;                       const uint32_t stride,
1081    ;                       const uint32_t rounding);
1082    ;
1083    ;
1084    ;===========================================================================
1085    
1086    %macro ADD_HF_MMX 0
1087      movq mm0, [eax]
1088      movq mm2, [eax+edx]
1089      movq mm1, mm0
1090      movq mm3, mm2
1091    
1092      lea eax,[eax+edx]
1093    
1094      MIX
1095      movq mm2, [ecx]   ; prepare mix with Dst[0]
1096      MIX_DST
1097      movq [ecx], mm0
1098    
1099    %endmacro
1100    
1101    ALIGN 16
1102    interpolate8x8_halfpel_v_add_mmx:
1103      PROLOG rounding1_mmx, 1
1104    
1105      ADD_HF_MMX
1106      lea ecx,[ecx+edx]
1107      ADD_HF_MMX
1108      lea ecx,[ecx+edx]
1109      ADD_HF_MMX
1110      lea ecx,[ecx+edx]
1111      ADD_HF_MMX
1112      lea ecx,[ecx+edx]
1113      ADD_HF_MMX
1114      lea ecx,[ecx+edx]
1115      ADD_HF_MMX
1116      lea ecx,[ecx+edx]
1117      ADD_HF_MMX
1118      lea ecx,[ecx+edx]
1119      ADD_HF_MMX
1120      ret
1121    
1122    ; The trick is to correct the result of 'pavgb' with some combination of the
1123    ; lsb's of the 4 input values i,j,k,l, and their intermediate 'pavgb' (s and t).
1124    ; The boolean relations are:
1125    ;   (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
1126    ;   (i+j+k+l+2)/4 = (s+t+1)/2 - (ij|kl)&st
1127    ;   (i+j+k+l+1)/4 = (s+t+1)/2 - (ij&kl)|st
1128    ;   (i+j+k+l+0)/4 = (s+t+1)/2 - (ij|kl)|st
1129    ; with  s=(i+j+1)/2, t=(k+l+1)/2, ij = i^j, kl = k^l, st = s^t.
1130    
1131    ; Moreover, we process 2 lines at a times, for better overlapping (~15% faster).
1132    
1133    ;===========================================================================
1134    ;
1135    ; void interpolate8x8_halfpel_hv_add_mmx(uint8_t * const dst,
1136    ;                       const uint8_t * const src,
1137    ;                       const uint32_t stride,
1138    ;                       const uint32_t rounding);
1139    ;
1140    ;
1141    ;===========================================================================
1142    
1143    %macro ADD_HH_MMX 0
1144      lea eax,[eax+edx]
1145    
1146        ; transfert prev line to mm0/mm1
1147      movq mm0, mm2
1148      movq mm1, mm3
1149    
1150        ; load new line in mm2/mm3
1151      movq mm2, [eax]
1152      movq mm4, [eax+1]
1153      movq mm3, mm2
1154      movq mm5, mm4
1155    
1156      punpcklbw mm2, mm6
1157      punpcklbw mm4, mm6
1158      paddusw mm2, mm4
1159      punpckhbw mm3, mm6
1160      punpckhbw mm5, mm6
1161      paddusw mm3, mm5
1162    
1163        ; mix current line (mm2/mm3) with previous (mm0,mm1);
1164        ; we'll preserve mm2/mm3 for next line...
1165    
1166      paddusw mm0, mm2
1167      paddusw mm1, mm3
1168    
1169      movq mm4, [ecx]   ; prepare mix with Dst[0]
1170      movq mm5, mm4
1171    
1172      paddusw mm0, mm7  ; finish mixing current line
1173      paddusw mm1, mm7
1174    
1175      punpcklbw mm4, mm6
1176      punpckhbw mm5, mm6
1177    
1178      psrlw mm0, 2
1179      psrlw mm1, 2
1180    
1181      paddusw mm0, mm4  ; mix Src(mm0/mm1) with Dst(mm2/mm3)
1182      paddusw mm1, mm5
1183    
1184      paddusw mm0, [rounding1_mmx]
1185      paddusw mm1, [rounding1_mmx]
1186    
1187      psrlw mm0, 1
1188      psrlw mm1, 1
1189    
1190      packuswb mm0, mm1
1191    
1192      movq [ecx], mm0
1193    %endmacro
1194    
1195    ALIGN 16
1196    interpolate8x8_halfpel_hv_add_mmx:
1197      PROLOG rounding2_mmx, 0    ; mm5 is busy. Don't load dst-rounder
1198    
1199        ; preprocess first line
1200      movq mm0, [eax]
1201      movq mm2, [eax+1]
1202      movq mm1, mm0
1203      movq mm3, mm2
1204    
1205      punpcklbw mm0, mm6
1206      punpcklbw mm2, mm6
1207      punpckhbw mm1, mm6
1208      punpckhbw mm3, mm6
1209      paddusw mm2, mm0
1210      paddusw mm3, mm1
1211    
1212       ; Input: mm2/mm3 contains the value (Src[0]+Src[1]) of previous line
1213    
1214      ADD_HH_MMX
1215      lea ecx,[ecx+edx]
1216      ADD_HH_MMX
1217      lea ecx,[ecx+edx]
1218      ADD_HH_MMX
1219      lea ecx,[ecx+edx]
1220      ADD_HH_MMX
1221      lea ecx,[ecx+edx]
1222      ADD_HH_MMX
1223      lea ecx,[ecx+edx]
1224      ADD_HH_MMX
1225      lea ecx,[ecx+edx]
1226      ADD_HH_MMX
1227      lea ecx,[ecx+edx]
1228      ADD_HH_MMX
1229    
1230      ret
1231    

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

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