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

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

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

revision 651, Sun Nov 17 00:20:30 2002 UTC revision 1535, Sun Aug 22 11:46:10 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) 2002 Peter Ross <pross@xvid.org>  ; *  Copyright(C) 2001 Peter Ross <pross@xvid.org>
7    ; *               2002 Michael Militzer <isibaar@xvid.org>
8  ; *  ; *
9  ; *  This file is part of XviD, a free MPEG-4 video encoder/decoder  ; *  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
 ; *  XviD is free software; you can redistribute it and/or modify it  
 ; *  under the terms of the GNU General Public License as published by  
11  ; *  the Free Software Foundation; either version 2 of the License, or  ; *  the Free Software Foundation; either version 2 of the License, or
12  ; *  (at your option) any later version.  ; *  (at your option) any later version.
13  ; *  ; *
# Line 21  Line 20 
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA  ; *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
22  ; *  ; *
 ; *  Under section 8 of the GNU General Public License, the copyright  
 ; *  holders of XVID explicitly forbid distribution in the following  
 ; *  countries:  
 ; *  
 ; *    - Japan  
 ; *    - United States of America  
 ; *  
 ; *  Linking XviD statically or dynamically with other modules is making a  
 ; *  combined work based on XviD.  Thus, the terms and conditions of the  
 ; *  GNU General Public License cover the whole combination.  
 ; *  
 ; *  As a special exception, the copyright holders of XviD give you  
 ; *  permission to link XviD with independent modules that communicate with  
 ; *  XviD solely through the VFW1.1 and DShow interfaces, regardless of the  
 ; *  license terms of these independent modules, and to copy and distribute  
 ; *  the resulting combined work under terms of your choice, provided that  
 ; *  every copy of the combined work is accompanied by a complete copy of  
 ; *  the source code of XviD (the version of XviD used to produce the  
 ; *  combined work), being distributed under the terms of the GNU General  
 ; *  Public License plus this exception.  An independent module is a module  
 ; *  which is not derived from or based on XviD.  
 ; *  
 ; *  Note that people who make modified versions of XviD are not obligated  
 ; *  to grant this special exception for their modified versions; it is  
 ; *  their choice whether to do so.  The GNU General Public License gives  
 ; *  permission to release a modified version without this exception; this  
 ; *  exception also makes it possible to release a modified version which  
 ; *  carries forward this exception.  
 ; *  
 ; * $Id: interpolate8x8_mmx.asm,v 1.11 2002-11-17 00:20:30 edgomez Exp $  
 ; *  
23  ; ****************************************************************************/  ; ****************************************************************************/
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
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  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  ;-----------------------------------------------------------------------------
56    ; (16 - r) rounding table
57    ;-----------------------------------------------------------------------------
58    
59    ALIGN 16
60    rounding_lowpass_mmx:
61            times 4 dw 16
62            times 4 dw 15
63    
64  ;===========================================================================  ;-----------------------------------------------------------------------------
65  ; (1 - r) rounding table  ; (1 - r) rounding table
66  ;===========================================================================  ;-----------------------------------------------------------------------------
67    
68  rounding1_mmx  rounding1_mmx:
69  times 4 dw 1  times 4 dw 1
70  times 4 dw 0  times 4 dw 0
71    
72  ;===========================================================================  ;-----------------------------------------------------------------------------
73  ; (2 - r) rounding table  ; (2 - r) rounding table
74  ;===========================================================================  ;-----------------------------------------------------------------------------
75    
76  rounding2_mmx  rounding2_mmx:
77  times 4 dw 2  times 4 dw 2
78  times 4 dw 1  times 4 dw 1
79    
80  mmx_one  mmx_one:
81  times 8 db 1  times 8 db 1
82    
83  section .text  mmx_two:
84            times 8 db 2
85    
86    mmx_three:
87            times 8 db 3
88    
89    mmx_five:
90            times 4 dw 5
91    
92    mmx_mask:
93            times 8 db 254
94    
95    mmx_mask2:
96            times 8 db 252
97    
98    ;=============================================================================
99    ; Code
100    ;=============================================================================
101    
102    SECTION .text
103    
104    cglobal interpolate8x8_halfpel_h_mmx
105    cglobal interpolate8x8_halfpel_v_mmx
106    cglobal interpolate8x8_halfpel_hv_mmx
107    
108    cglobal interpolate8x8_avg4_mmx
109    cglobal interpolate8x8_avg2_mmx
110    
111    cglobal interpolate8x8_6tap_lowpass_h_mmx
112    cglobal interpolate8x8_6tap_lowpass_v_mmx
113    
114    cglobal interpolate8x8_halfpel_add_mmx
115    cglobal interpolate8x8_halfpel_h_add_mmx
116    cglobal interpolate8x8_halfpel_v_add_mmx
117    cglobal interpolate8x8_halfpel_hv_add_mmx
118    
119  %macro  CALC_AVG 6  %macro  CALC_AVG 6
120          punpcklbw %3, %6          punpcklbw %3, %6
# Line 101  Line 127 
127    
128          psrlw %1, 1                     ; mm01 >>= 1          psrlw %1, 1                     ; mm01 >>= 1
129          psrlw %2, 1          psrlw %2, 1
   
130  %endmacro  %endmacro
131    
132    
133  ;===========================================================================  ;-----------------------------------------------------------------------------
134  ;  ;
135  ; void interpolate8x8_halfpel_h_mmx(uint8_t * const dst,  ; void interpolate8x8_halfpel_h_mmx(uint8_t * const dst,
136  ;                                               const uint8_t * const src,  ;                                               const uint8_t * const src,
137  ;                                               const uint32_t stride,  ;                                               const uint32_t stride,
138  ;                                               const uint32_t rounding);  ;                                               const uint32_t rounding);
139  ;  ;
140  ;===========================================================================  ;-----------------------------------------------------------------------------
141    
142  %macro COPY_H_MMX 0  %macro COPY_H_MMX 0
143                  movq mm0, [esi]                  movq mm0, [esi]
# Line 132  Line 157 
157                  add edi, edx            ; dst += stride                  add edi, edx            ; dst += stride
158  %endmacro  %endmacro
159    
160  align 16  ALIGN 16
161  cglobal interpolate8x8_halfpel_h_mmx  interpolate8x8_halfpel_h_mmx:
 interpolate8x8_halfpel_h_mmx  
162    
163                  push    esi                  push    esi
164                  push    edi                  push    edi
   
165                  mov     eax, [esp + 8 + 16]             ; rounding                  mov     eax, [esp + 8 + 16]             ; rounding
166    
 interpolate8x8_halfpel_h_mmx.start  
167                  movq mm7, [rounding1_mmx + eax * 8]                  movq mm7, [rounding1_mmx + eax * 8]
168    
169                  mov     edi, [esp + 8 + 4]              ; dst                  mov     edi, [esp + 8 + 4]              ; dst
# Line 165  Line 187 
187                  ret                  ret
188    
189    
190  ;===========================================================================  ;-----------------------------------------------------------------------------
191  ;  ;
192  ; void interpolate8x8_halfpel_v_mmx(uint8_t * const dst,  ; void interpolate8x8_halfpel_v_mmx(uint8_t * const dst,
193  ;                                               const uint8_t * const src,  ;                                               const uint8_t * const src,
194  ;                                               const uint32_t stride,  ;                                               const uint32_t stride,
195  ;                                               const uint32_t rounding);  ;                                               const uint32_t rounding);
196  ;  ;
197  ;===========================================================================  ;-----------------------------------------------------------------------------
198    
199  %macro COPY_V_MMX 0  %macro COPY_V_MMX 0
200                  movq mm0, [esi]                  movq mm0, [esi]
# Line 192  Line 214 
214                  add edi, edx            ; dst += stride                  add edi, edx            ; dst += stride
215  %endmacro  %endmacro
216    
217  align 16  ALIGN 16
218  cglobal interpolate8x8_halfpel_v_mmx  interpolate8x8_halfpel_v_mmx:
 interpolate8x8_halfpel_v_mmx  
219    
220                  push    esi                  push    esi
221                  push    edi                  push    edi
222    
223                  mov     eax, [esp + 8 + 16]             ; rounding                  mov     eax, [esp + 8 + 16]             ; rounding
224    
 interpolate8x8_halfpel_v_mmx.start  
225                  movq mm7, [rounding1_mmx + eax * 8]                  movq mm7, [rounding1_mmx + eax * 8]
226    
227                  mov     edi, [esp + 8 + 4]              ; dst                  mov     edi, [esp + 8 + 4]              ; dst
# Line 226  Line 246 
246                  ret                  ret
247    
248    
249  ;===========================================================================  ;-----------------------------------------------------------------------------
250  ;  ;
251  ; void interpolate8x8_halfpel_hv_mmx(uint8_t * const dst,  ; void interpolate8x8_halfpel_hv_mmx(uint8_t * const dst,
252  ;                                               const uint8_t * const src,  ;                                               const uint8_t * const src,
# Line 234  Line 254 
254  ;                                               const uint32_t rounding);  ;                                               const uint32_t rounding);
255  ;  ;
256  ;  ;
257  ;===========================================================================  ;-----------------------------------------------------------------------------
258    
259  %macro COPY_HV_MMX 0  %macro COPY_HV_MMX 0
260                  ; current row                  ; current row
   
261                  movq mm0, [esi]                  movq mm0, [esi]
262                  movq mm2, [esi + 1]                  movq mm2, [esi + 1]
263    
# Line 254  Line 273 
273                  paddusw mm1, mm3                  paddusw mm1, mm3
274    
275                  ; next row                  ; next row
   
276                  movq mm4, [esi + edx]                  movq mm4, [esi + edx]
277                  movq mm2, [esi + edx + 1]                  movq mm2, [esi + edx + 1]
278    
# Line 270  Line 288 
288                  paddusw mm5, mm3                  paddusw mm5, mm3
289    
290                  ; add current + next row                  ; add current + next row
   
291                  paddusw mm0, mm4                ; mm01 += mm45                  paddusw mm0, mm4                ; mm01 += mm45
292                  paddusw mm1, mm5                  paddusw mm1, mm5
293                  paddusw mm0, mm7                ; mm01 += rounding2                  paddusw mm0, mm7                ; mm01 += rounding2
# Line 286  Line 303 
303                  add edi, edx            ; dst += stride                  add edi, edx            ; dst += stride
304  %endmacro  %endmacro
305    
306  align 16  ALIGN 16
307  cglobal interpolate8x8_halfpel_hv_mmx  interpolate8x8_halfpel_hv_mmx:
 interpolate8x8_halfpel_hv_mmx  
308    
309                  push    esi                  push    esi
310                  push    edi                  push    edi
311    
312                  mov     eax, [esp + 8 + 16]             ; rounding                  mov     eax, [esp + 8 + 16]             ; rounding
 interpolate8x8_halfpel_hv_mmx.start  
313    
314                  movq mm7, [rounding2_mmx + eax * 8]                  movq mm7, [rounding2_mmx + eax * 8]
315    
# Line 320  Line 335 
335                  pop esi                  pop esi
336    
337                  ret                  ret
338    
339    ;-----------------------------------------------------------------------------
340    ;
341    ; void interpolate8x8_avg2_mmx(uint8_t const *dst,
342    ;                              const uint8_t * const src1,
343    ;                              const uint8_t * const src2,
344    ;                              const uint32_t stride,
345    ;                              const uint32_t rounding,
346    ;                              const uint32_t height);
347    ;
348    ;-----------------------------------------------------------------------------
349    
350    %macro AVG2_MMX_RND0 0
351      movq mm0, [eax]           ; src1 -> mm0
352      movq mm1, [ebx]           ; src2 -> mm1
353    
354      movq mm4, [eax+edx]
355      movq mm5, [ebx+edx]
356    
357      movq mm2, mm0             ; src1 -> mm2
358      movq mm3, mm1             ; src2 -> mm3
359    
360      pand mm2, mm7             ; isolate the lsb
361      pand mm3, mm7             ; isolate the lsb
362    
363      por mm2, mm3              ; ODD(src1) OR ODD(src2) -> mm2
364    
365      movq mm3, mm4
366      movq mm6, mm5
367    
368      pand mm3, mm7
369      pand mm6, mm7
370    
371      por mm3, mm6
372    
373      pand mm0, [mmx_mask]
374      pand mm1, [mmx_mask]
375      pand mm4, [mmx_mask]
376      pand mm5, [mmx_mask]
377    
378      psrlq mm0, 1              ; src1 / 2
379      psrlq mm1, 1              ; src2 / 2
380    
381      psrlq mm4, 1
382      psrlq mm5, 1
383    
384      paddb mm0, mm1            ; src1/2 + src2/2 -> mm0
385      paddb mm0, mm2            ; correct rounding error
386    
387      paddb mm4, mm5
388      paddb mm4, mm3
389    
390      lea eax, [eax+2*edx]
391      lea ebx, [ebx+2*edx]
392    
393      movq [ecx], mm0           ; (src1 + src2 + 1) / 2 -> dst
394      movq [ecx+edx], mm4
395    %endmacro
396    
397    %macro AVG2_MMX_RND1 0
398      movq mm0, [eax]           ; src1 -> mm0
399      movq mm1, [ebx]           ; src2 -> mm1
400    
401      movq mm4, [eax+edx]
402      movq mm5, [ebx+edx]
403    
404      movq mm2, mm0             ; src1 -> mm2
405      movq mm3, mm1             ; src2 -> mm3
406    
407      pand mm2, mm7             ; isolate the lsb
408      pand mm3, mm7             ; isolate the lsb
409    
410      pand mm2, mm3             ; ODD(src1) AND ODD(src2) -> mm2
411    
412      movq mm3, mm4
413      movq mm6, mm5
414    
415      pand mm3, mm7
416      pand mm6, mm7
417    
418      pand mm3, mm6
419    
420      pand mm0, [mmx_mask]
421      pand mm1, [mmx_mask]
422      pand mm4, [mmx_mask]
423      pand mm5, [mmx_mask]
424    
425      psrlq mm0, 1              ; src1 / 2
426      psrlq mm1, 1              ; src2 / 2
427    
428      psrlq mm4, 1
429      psrlq mm5, 1
430    
431      paddb mm0, mm1            ; src1/2 + src2/2 -> mm0
432      paddb mm0, mm2            ; correct rounding error
433    
434      paddb mm4, mm5
435      paddb mm4, mm3
436    
437      lea eax, [eax+2*edx]
438      lea ebx, [ebx+2*edx]
439    
440      movq [ecx], mm0           ; (src1 + src2 + 1) / 2 -> dst
441      movq [ecx+edx], mm4
442    %endmacro
443    
444    ALIGN 16
445    interpolate8x8_avg2_mmx:
446    
447      push ebx
448    
449      mov eax, [esp + 4 + 20]   ; rounding
450      test eax, eax
451    
452      jnz near .rounding1
453    
454      mov eax, [esp + 4 + 24]   ; height -> eax
455      sub eax, 8
456      test eax, eax
457    
458      mov ecx, [esp + 4 + 4]    ; dst -> edi
459      mov eax, [esp + 4 + 8]    ; src1 -> esi
460      mov ebx, [esp + 4 + 12]   ; src2 -> eax
461      mov edx, [esp + 4 + 16]   ; stride -> edx
462    
463      movq mm7, [mmx_one]
464    
465      jz near .start0
466    
467      AVG2_MMX_RND0
468      lea ecx, [ecx+2*edx]
469    
470    .start0
471    
472      AVG2_MMX_RND0
473      lea ecx, [ecx+2*edx]
474      AVG2_MMX_RND0
475      lea ecx, [ecx+2*edx]
476      AVG2_MMX_RND0
477      lea ecx, [ecx+2*edx]
478      AVG2_MMX_RND0
479    
480      pop ebx
481      ret
482    
483    .rounding1
484      mov eax, [esp + 4 + 24]       ; height -> eax
485      sub eax, 8
486      test eax, eax
487    
488      mov ecx, [esp + 4 + 4]        ; dst -> edi
489      mov eax, [esp + 4 + 8]        ; src1 -> esi
490      mov ebx, [esp + 4 + 12]       ; src2 -> eax
491      mov edx, [esp + 4 + 16]       ; stride -> edx
492    
493      movq mm7, [mmx_one]
494    
495      jz near .start1
496    
497      AVG2_MMX_RND1
498      lea ecx, [ecx+2*edx]
499    
500    .start1
501    
502      AVG2_MMX_RND1
503      lea ecx, [ecx+2*edx]
504      AVG2_MMX_RND1
505      lea ecx, [ecx+2*edx]
506      AVG2_MMX_RND1
507      lea ecx, [ecx+2*edx]
508      AVG2_MMX_RND1
509    
510      pop ebx
511      ret
512    
513    
514    ;-----------------------------------------------------------------------------
515    ;
516    ; void interpolate8x8_avg4_mmx(uint8_t const *dst,
517    ;                              const uint8_t * const src1,
518    ;                              const uint8_t * const src2,
519    ;                              const uint8_t * const src3,
520    ;                              const uint8_t * const src4,
521    ;                              const uint32_t stride,
522    ;                              const uint32_t rounding);
523    ;
524    ;-----------------------------------------------------------------------------
525    
526    %macro AVG4_MMX_RND0 0
527      movq mm0, [eax]           ; src1 -> mm0
528      movq mm1, [ebx]           ; src2 -> mm1
529    
530      movq mm2, mm0
531      movq mm3, mm1
532    
533      pand mm2, [mmx_three]
534      pand mm3, [mmx_three]
535    
536      pand mm0, [mmx_mask2]
537      pand mm1, [mmx_mask2]
538    
539      psrlq mm0, 2
540      psrlq mm1, 2
541    
542      lea eax, [eax+edx]
543      lea ebx, [ebx+edx]
544    
545      paddb mm0, mm1
546      paddb mm2, mm3
547    
548      movq mm4, [esi]           ; src3 -> mm0
549      movq mm5, [edi]           ; src4 -> mm1
550    
551      movq mm1, mm4
552      movq mm3, mm5
553    
554      pand mm1, [mmx_three]
555      pand mm3, [mmx_three]
556    
557      pand mm4, [mmx_mask2]
558      pand mm5, [mmx_mask2]
559    
560      psrlq mm4, 2
561      psrlq mm5, 2
562    
563      paddb mm4, mm5
564      paddb mm0, mm4
565    
566      paddb mm1, mm3
567      paddb mm2, mm1
568    
569      paddb mm2, [mmx_two]
570      pand mm2, [mmx_mask2]
571    
572      psrlq mm2, 2
573      paddb mm0, mm2
574    
575      lea esi, [esi+edx]
576      lea edi, [edi+edx]
577    
578      movq [ecx], mm0           ; (src1 + src2 + src3 + src4 + 2) / 4 -> dst
579    %endmacro
580    
581    %macro AVG4_MMX_RND1 0
582      movq mm0, [eax]           ; src1 -> mm0
583      movq mm1, [ebx]           ; src2 -> mm1
584    
585      movq mm2, mm0
586      movq mm3, mm1
587    
588      pand mm2, [mmx_three]
589      pand mm3, [mmx_three]
590    
591      pand mm0, [mmx_mask2]
592      pand mm1, [mmx_mask2]
593    
594      psrlq mm0, 2
595      psrlq mm1, 2
596    
597      lea eax,[eax+edx]
598      lea ebx,[ebx+edx]
599    
600      paddb mm0, mm1
601      paddb mm2, mm3
602    
603      movq mm4, [esi]           ; src3 -> mm0
604      movq mm5, [edi]           ; src4 -> mm1
605    
606      movq mm1, mm4
607      movq mm3, mm5
608    
609      pand mm1, [mmx_three]
610      pand mm3, [mmx_three]
611    
612      pand mm4, [mmx_mask2]
613      pand mm5, [mmx_mask2]
614    
615      psrlq mm4, 2
616      psrlq mm5, 2
617    
618      paddb mm4, mm5
619      paddb mm0, mm4
620    
621      paddb mm1, mm3
622      paddb mm2, mm1
623    
624      paddb mm2, [mmx_one]
625      pand mm2, [mmx_mask2]
626    
627      psrlq mm2, 2
628      paddb mm0, mm2
629    
630      lea esi,[esi+edx]
631      lea edi,[edi+edx]
632    
633      movq [ecx], mm0           ; (src1 + src2 + src3 + src4 + 2) / 4 -> dst
634    %endmacro
635    
636    ALIGN 16
637    interpolate8x8_avg4_mmx:
638    
639      push ebx
640      push edi
641      push esi
642    
643      mov eax, [esp + 12 + 28]      ; rounding
644    
645      test eax, eax
646    
647      mov ecx, [esp + 12 + 4]       ; dst -> edi
648      mov eax, [esp + 12 + 8]       ; src1 -> esi
649      mov ebx, [esp + 12 + 12]      ; src2 -> eax
650      mov esi, [esp + 12 + 16]      ; src3 -> esi
651      mov edi, [esp + 12 + 20]      ; src4 -> edi
652      mov edx, [esp + 12 + 24]      ; stride -> edx
653    
654      movq mm7, [mmx_one]
655    
656      jnz near .rounding1
657    
658      AVG4_MMX_RND0
659      lea ecx, [ecx+edx]
660      AVG4_MMX_RND0
661      lea ecx, [ecx+edx]
662      AVG4_MMX_RND0
663      lea ecx, [ecx+edx]
664      AVG4_MMX_RND0
665      lea ecx, [ecx+edx]
666      AVG4_MMX_RND0
667      lea ecx, [ecx+edx]
668      AVG4_MMX_RND0
669      lea ecx, [ecx+edx]
670      AVG4_MMX_RND0
671      lea ecx, [ecx+edx]
672      AVG4_MMX_RND0
673    
674      pop esi
675      pop edi
676      pop ebx
677      ret
678    
679    .rounding1
680      AVG4_MMX_RND1
681      lea ecx, [ecx+edx]
682      AVG4_MMX_RND1
683      lea ecx, [ecx+edx]
684      AVG4_MMX_RND1
685      lea ecx, [ecx+edx]
686      AVG4_MMX_RND1
687      lea ecx, [ecx+edx]
688      AVG4_MMX_RND1
689      lea ecx, [ecx+edx]
690      AVG4_MMX_RND1
691      lea ecx, [ecx+edx]
692      AVG4_MMX_RND1
693      lea ecx, [ecx+edx]
694      AVG4_MMX_RND1
695    
696      pop esi
697      pop edi
698      pop ebx
699      ret
700    
701    
702    ;-----------------------------------------------------------------------------
703    ;
704    ; void interpolate8x8_6tap_lowpass_h_mmx(uint8_t const *dst,
705    ;                                        const uint8_t * const src,
706    ;                                        const uint32_t stride,
707    ;                                        const uint32_t rounding);
708    ;
709    ;-----------------------------------------------------------------------------
710    
711    %macro LOWPASS_6TAP_H_MMX 0
712      movq mm0, [eax]
713      movq mm2, [eax+1]
714    
715      movq mm1, mm0
716      movq mm3, mm2
717    
718      punpcklbw mm0, mm7
719      punpcklbw mm2, mm7
720    
721      punpckhbw mm1, mm7
722      punpckhbw mm3, mm7
723    
724      paddw mm0, mm2
725      paddw mm1, mm3
726    
727      psllw mm0, 2
728      psllw mm1, 2
729    
730      movq mm2, [eax-1]
731      movq mm4, [eax+2]
732    
733      movq mm3, mm2
734      movq mm5, mm4
735    
736      punpcklbw mm2, mm7
737      punpcklbw mm4, mm7
738    
739      punpckhbw mm3, mm7
740      punpckhbw mm5, mm7
741    
742      paddw mm2, mm4
743      paddw mm3, mm5
744    
745      psubsw mm0, mm2
746      psubsw mm1, mm3
747    
748      pmullw mm0, [mmx_five]
749      pmullw mm1, [mmx_five]
750    
751      movq mm2, [eax-2]
752      movq mm4, [eax+3]
753    
754      movq mm3, mm2
755      movq mm5, mm4
756    
757      punpcklbw mm2, mm7
758      punpcklbw mm4, mm7
759    
760      punpckhbw mm3, mm7
761      punpckhbw mm5, mm7
762    
763      paddw mm2, mm4
764      paddw mm3, mm5
765    
766      paddsw mm0, mm2
767      paddsw mm1, mm3
768    
769      paddsw mm0, mm6
770      paddsw mm1, mm6
771    
772      psraw mm0, 5
773      psraw mm1, 5
774    
775      lea eax, [eax+edx]
776      packuswb mm0, mm1
777      movq [ecx], mm0
778    %endmacro
779    
780    ALIGN 16
781    interpolate8x8_6tap_lowpass_h_mmx:
782    
783      mov eax, [esp + 16]           ; rounding
784    
785      movq mm6, [rounding_lowpass_mmx + eax * 8]
786    
787      mov ecx, [esp + 4]            ; dst -> edi
788      mov eax, [esp + 8]            ; src -> esi
789      mov edx, [esp + 12]           ; stride -> edx
790    
791      pxor mm7, mm7
792    
793      LOWPASS_6TAP_H_MMX
794      lea ecx, [ecx+edx]
795      LOWPASS_6TAP_H_MMX
796      lea ecx, [ecx+edx]
797      LOWPASS_6TAP_H_MMX
798      lea ecx, [ecx+edx]
799      LOWPASS_6TAP_H_MMX
800      lea ecx, [ecx+edx]
801      LOWPASS_6TAP_H_MMX
802      lea ecx, [ecx+edx]
803      LOWPASS_6TAP_H_MMX
804      lea ecx, [ecx+edx]
805      LOWPASS_6TAP_H_MMX
806      lea ecx, [ecx+edx]
807      LOWPASS_6TAP_H_MMX
808    
809      ret
810    
811    ;-----------------------------------------------------------------------------
812    ;
813    ; void interpolate8x8_6tap_lowpass_v_mmx(uint8_t const *dst,
814    ;                                        const uint8_t * const src,
815    ;                                        const uint32_t stride,
816    ;                                        const uint32_t rounding);
817    ;
818    ;-----------------------------------------------------------------------------
819    
820    %macro LOWPASS_6TAP_V_MMX 0
821      movq mm0, [eax]
822      movq mm2, [eax+edx]
823    
824      movq mm1, mm0
825      movq mm3, mm2
826    
827      punpcklbw mm0, mm7
828      punpcklbw mm2, mm7
829    
830      punpckhbw mm1, mm7
831      punpckhbw mm3, mm7
832    
833      paddw mm0, mm2
834      paddw mm1, mm3
835    
836      psllw mm0, 2
837      psllw mm1, 2
838    
839      movq mm4, [eax+2*edx]
840      sub eax, ebx
841      movq mm2, [eax+2*edx]
842    
843      movq mm3, mm2
844      movq mm5, mm4
845    
846      punpcklbw mm2, mm7
847      punpcklbw mm4, mm7
848    
849      punpckhbw mm3, mm7
850      punpckhbw mm5, mm7
851    
852      paddw mm2, mm4
853      paddw mm3, mm5
854    
855      psubsw mm0, mm2
856      psubsw mm1, mm3
857    
858      pmullw mm0, [mmx_five]
859      pmullw mm1, [mmx_five]
860    
861      movq mm2, [eax+edx]
862      movq mm4, [eax+2*ebx]
863    
864      movq mm3, mm2
865      movq mm5, mm4
866    
867      punpcklbw mm2, mm7
868      punpcklbw mm4, mm7
869    
870      punpckhbw mm3, mm7
871      punpckhbw mm5, mm7
872    
873      paddw mm2, mm4
874      paddw mm3, mm5
875    
876      paddsw mm0, mm2
877      paddsw mm1, mm3
878    
879      paddsw mm0, mm6
880      paddsw mm1, mm6
881    
882      psraw mm0, 5
883      psraw mm1, 5
884    
885      lea eax, [eax+4*edx]
886      packuswb mm0, mm1
887      movq [ecx], mm0
888    %endmacro
889    
890    ALIGN 16
891    interpolate8x8_6tap_lowpass_v_mmx:
892    
893      push ebx
894    
895      mov eax, [esp + 4 + 16]           ; rounding
896    
897      movq mm6, [rounding_lowpass_mmx + eax * 8]
898    
899      mov ecx, [esp + 4 + 4]            ; dst -> edi
900      mov eax, [esp + 4 + 8]            ; src -> esi
901      mov edx, [esp + 4 + 12]           ; stride -> edx
902    
903      mov ebx, edx
904      shl ebx, 1
905      add ebx, edx
906    
907      pxor mm7, mm7
908    
909      LOWPASS_6TAP_V_MMX
910      lea ecx, [ecx+edx]
911      LOWPASS_6TAP_V_MMX
912      lea ecx, [ecx+edx]
913      LOWPASS_6TAP_V_MMX
914      lea ecx, [ecx+edx]
915      LOWPASS_6TAP_V_MMX
916      lea ecx, [ecx+edx]
917      LOWPASS_6TAP_V_MMX
918      lea ecx, [ecx+edx]
919      LOWPASS_6TAP_V_MMX
920      lea ecx, [ecx+edx]
921      LOWPASS_6TAP_V_MMX
922      lea ecx, [ecx+edx]
923      LOWPASS_6TAP_V_MMX
924    
925      pop ebx
926      ret
927    
928    ;===========================================================================
929    ;
930    ; The next functions combine both source halfpel interpolation step and the
931    ; averaging (with rouding) step to avoid wasting memory bandwidth computing
932    ; intermediate halfpel images and then averaging them.
933    ;
934    ;===========================================================================
935    
936    %macro PROLOG0 0
937      mov ecx, [esp+ 4] ; Dst
938      mov eax, [esp+ 8] ; Src
939      mov edx, [esp+12] ; BpS
940    %endmacro
941    
942    %macro PROLOG 2   ; %1: Rounder, %2 load Dst-Rounder
943      pxor mm6, mm6
944      movq mm7, [%1]    ; TODO: dangerous! (eax isn't checked)
945    %if %2
946      movq mm5, [rounding1_mmx]
947    %endif
948    
949      PROLOG0
950    %endmacro
951    
952      ; performs: mm0 == (mm0+mm2)  mm1 == (mm1+mm3)
953    %macro MIX 0
954      punpcklbw mm0, mm6
955      punpcklbw mm2, mm6
956      punpckhbw mm1, mm6
957      punpckhbw mm3, mm6
958      paddusw mm0, mm2
959      paddusw mm1, mm3
960    %endmacro
961    
962    %macro MIX_DST 0
963      movq mm3, mm2
964      paddusw mm0, mm7  ; rounder
965      paddusw mm1, mm7  ; rounder
966      punpcklbw mm2, mm6
967      punpckhbw mm3, mm6
968      psrlw mm0, 1
969      psrlw mm1, 1
970    
971      paddusw mm0, mm2  ; mix Src(mm0/mm1) with Dst(mm2/mm3)
972      paddusw mm1, mm3
973      paddusw mm0, mm5
974      paddusw mm1, mm5
975      psrlw mm0, 1
976      psrlw mm1, 1
977    
978      packuswb mm0, mm1
979    %endmacro
980    
981    %macro MIX2 0
982      punpcklbw mm0, mm6
983      punpcklbw mm2, mm6
984      paddusw mm0, mm2
985      paddusw mm0, mm7
986      punpckhbw mm1, mm6
987      punpckhbw mm3, mm6
988      paddusw mm1, mm7
989      paddusw mm1, mm3
990      psrlw mm0, 1
991      psrlw mm1, 1
992    
993      packuswb mm0, mm1
994    %endmacro
995    
996    ;===========================================================================
997    ;
998    ; void interpolate8x8_halfpel_add_mmx(uint8_t * const dst,
999    ;                       const uint8_t * const src,
1000    ;                       const uint32_t stride,
1001    ;                       const uint32_t rounding);
1002    ;
1003    ;
1004    ;===========================================================================
1005    
1006    %macro ADD_FF_MMX 1
1007      movq mm0, [eax]
1008      movq mm2, [ecx]
1009      movq mm1, mm0
1010      movq mm3, mm2
1011    %if (%1!=0)
1012      lea eax,[eax+%1*edx]
1013    %endif
1014      MIX
1015      paddusw mm0, mm5  ; rounder
1016      paddusw mm1, mm5  ; rounder
1017      psrlw mm0, 1
1018      psrlw mm1, 1
1019    
1020      packuswb mm0, mm1
1021      movq [ecx], mm0
1022    %if (%1!=0)
1023      lea ecx,[ecx+%1*edx]
1024    %endif
1025    %endmacro
1026    
1027    ALIGN 16
1028    interpolate8x8_halfpel_add_mmx:
1029      PROLOG rounding1_mmx, 1
1030      ADD_FF_MMX 1
1031      ADD_FF_MMX 1
1032      ADD_FF_MMX 1
1033      ADD_FF_MMX 1
1034      ADD_FF_MMX 1
1035      ADD_FF_MMX 1
1036      ADD_FF_MMX 1
1037      ADD_FF_MMX 0
1038      ret
1039    
1040    ;===========================================================================
1041    ;
1042    ; void interpolate8x8_halfpel_h_add_mmx(uint8_t * const dst,
1043    ;                       const uint8_t * const src,
1044    ;                       const uint32_t stride,
1045    ;                       const uint32_t rounding);
1046    ;
1047    ;
1048    ;===========================================================================
1049    
1050    %macro ADD_FH_MMX 0
1051      movq mm0, [eax]
1052      movq mm2, [eax+1]
1053      movq mm1, mm0
1054      movq mm3, mm2
1055    
1056      lea eax,[eax+edx]
1057    
1058      MIX
1059      movq mm2, [ecx]   ; prepare mix with Dst[0]
1060      MIX_DST
1061      movq [ecx], mm0
1062    %endmacro
1063    
1064    ALIGN 16
1065    interpolate8x8_halfpel_h_add_mmx:
1066      PROLOG rounding1_mmx, 1
1067    
1068      ADD_FH_MMX
1069      lea ecx,[ecx+edx]
1070      ADD_FH_MMX
1071      lea ecx,[ecx+edx]
1072      ADD_FH_MMX
1073      lea ecx,[ecx+edx]
1074      ADD_FH_MMX
1075      lea ecx,[ecx+edx]
1076      ADD_FH_MMX
1077      lea ecx,[ecx+edx]
1078      ADD_FH_MMX
1079      lea ecx,[ecx+edx]
1080      ADD_FH_MMX
1081      lea ecx,[ecx+edx]
1082      ADD_FH_MMX
1083      ret
1084    
1085    ;===========================================================================
1086    ;
1087    ; void interpolate8x8_halfpel_v_add_mmx(uint8_t * const dst,
1088    ;                       const uint8_t * const src,
1089    ;                       const uint32_t stride,
1090    ;                       const uint32_t rounding);
1091    ;
1092    ;
1093    ;===========================================================================
1094    
1095    %macro ADD_HF_MMX 0
1096      movq mm0, [eax]
1097      movq mm2, [eax+edx]
1098      movq mm1, mm0
1099      movq mm3, mm2
1100    
1101      lea eax,[eax+edx]
1102    
1103      MIX
1104      movq mm2, [ecx]   ; prepare mix with Dst[0]
1105      MIX_DST
1106      movq [ecx], mm0
1107    
1108    %endmacro
1109    
1110    ALIGN 16
1111    interpolate8x8_halfpel_v_add_mmx:
1112      PROLOG rounding1_mmx, 1
1113    
1114      ADD_HF_MMX
1115      lea ecx,[ecx+edx]
1116      ADD_HF_MMX
1117      lea ecx,[ecx+edx]
1118      ADD_HF_MMX
1119      lea ecx,[ecx+edx]
1120      ADD_HF_MMX
1121      lea ecx,[ecx+edx]
1122      ADD_HF_MMX
1123      lea ecx,[ecx+edx]
1124      ADD_HF_MMX
1125      lea ecx,[ecx+edx]
1126      ADD_HF_MMX
1127      lea ecx,[ecx+edx]
1128      ADD_HF_MMX
1129      ret
1130    
1131    ; The trick is to correct the result of 'pavgb' with some combination of the
1132    ; lsb's of the 4 input values i,j,k,l, and their intermediate 'pavgb' (s and t).
1133    ; The boolean relations are:
1134    ;   (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
1135    ;   (i+j+k+l+2)/4 = (s+t+1)/2 - (ij|kl)&st
1136    ;   (i+j+k+l+1)/4 = (s+t+1)/2 - (ij&kl)|st
1137    ;   (i+j+k+l+0)/4 = (s+t+1)/2 - (ij|kl)|st
1138    ; with  s=(i+j+1)/2, t=(k+l+1)/2, ij = i^j, kl = k^l, st = s^t.
1139    
1140    ; Moreover, we process 2 lines at a times, for better overlapping (~15% faster).
1141    
1142    ;===========================================================================
1143    ;
1144    ; void interpolate8x8_halfpel_hv_add_mmx(uint8_t * const dst,
1145    ;                       const uint8_t * const src,
1146    ;                       const uint32_t stride,
1147    ;                       const uint32_t rounding);
1148    ;
1149    ;
1150    ;===========================================================================
1151    
1152    %macro ADD_HH_MMX 0
1153      lea eax,[eax+edx]
1154    
1155        ; transfert prev line to mm0/mm1
1156      movq mm0, mm2
1157      movq mm1, mm3
1158    
1159        ; load new line in mm2/mm3
1160      movq mm2, [eax]
1161      movq mm4, [eax+1]
1162      movq mm3, mm2
1163      movq mm5, mm4
1164    
1165      punpcklbw mm2, mm6
1166      punpcklbw mm4, mm6
1167      paddusw mm2, mm4
1168      punpckhbw mm3, mm6
1169      punpckhbw mm5, mm6
1170      paddusw mm3, mm5
1171    
1172        ; mix current line (mm2/mm3) with previous (mm0,mm1);
1173        ; we'll preserve mm2/mm3 for next line...
1174    
1175      paddusw mm0, mm2
1176      paddusw mm1, mm3
1177    
1178      movq mm4, [ecx]   ; prepare mix with Dst[0]
1179      movq mm5, mm4
1180    
1181      paddusw mm0, mm7  ; finish mixing current line
1182      paddusw mm1, mm7
1183    
1184      punpcklbw mm4, mm6
1185      punpckhbw mm5, mm6
1186    
1187      psrlw mm0, 2
1188      psrlw mm1, 2
1189    
1190      paddusw mm0, mm4  ; mix Src(mm0/mm1) with Dst(mm2/mm3)
1191      paddusw mm1, mm5
1192    
1193      paddusw mm0, [rounding1_mmx]
1194      paddusw mm1, [rounding1_mmx]
1195    
1196      psrlw mm0, 1
1197      psrlw mm1, 1
1198    
1199      packuswb mm0, mm1
1200    
1201      movq [ecx], mm0
1202    %endmacro
1203    
1204    ALIGN 16
1205    interpolate8x8_halfpel_hv_add_mmx:
1206      PROLOG rounding2_mmx, 0    ; mm5 is busy. Don't load dst-rounder
1207    
1208        ; preprocess first line
1209      movq mm0, [eax]
1210      movq mm2, [eax+1]
1211      movq mm1, mm0
1212      movq mm3, mm2
1213    
1214      punpcklbw mm0, mm6
1215      punpcklbw mm2, mm6
1216      punpckhbw mm1, mm6
1217      punpckhbw mm3, mm6
1218      paddusw mm2, mm0
1219      paddusw mm3, mm1
1220    
1221       ; Input: mm2/mm3 contains the value (Src[0]+Src[1]) of previous line
1222    
1223      ADD_HH_MMX
1224      lea ecx,[ecx+edx]
1225      ADD_HH_MMX
1226      lea ecx,[ecx+edx]
1227      ADD_HH_MMX
1228      lea ecx,[ecx+edx]
1229      ADD_HH_MMX
1230      lea ecx,[ecx+edx]
1231      ADD_HH_MMX
1232      lea ecx,[ecx+edx]
1233      ADD_HH_MMX
1234      lea ecx,[ecx+edx]
1235      ADD_HH_MMX
1236      lea ecx,[ecx+edx]
1237      ADD_HH_MMX
1238    
1239      ret
1240    

Legend:
Removed from v.651  
changed lines
  Added in v.1535

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