[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.12, Sat Feb 15 15:22:18 2003 UTC revision 1.18, Tue Sep 13 12:12:15 2005 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:  ; ****************************************************************************/
 ; *  
 ; * 05.10.2002  added some qpel mmx code - Isibaar  
 ; * 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
29                    %ifdef MARK_FUNCS
30                            global _%1:function %1.endfunc-%1
31                            %define %1 _%1:function %1.endfunc-%1
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 %1.endfunc-%1
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  align 16  %ifdef FORMAT_COFF
50    SECTION .rodata
51    %else
52    SECTION .rodata align=16
53    %endif
54    
55  ;===========================================================================  ;-----------------------------------------------------------------------------
56  ; (16 - r) rounding table  ; (16 - r) rounding table
57  ;===========================================================================  ;-----------------------------------------------------------------------------
58    
59  rounding_lowpass_mmx  ALIGN 16
60    rounding_lowpass_mmx:
61  times 4 dw 16  times 4 dw 16
62  times 4 dw 15  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  mmx_two  mmx_two:
84  times 8 db 2  times 8 db 2
85    
86  mmx_three  mmx_three:
87  times 8 db 3  times 8 db 3
88    
89  mmx_five  mmx_five:
90  times 4 dw 5  times 4 dw 5
91    
92  mmx_mask  mmx_mask:
93  times 8 db 254  times 8 db 254
94    
95  mmx_mask2  mmx_mask2:
96  times 8 db 252  times 8 db 252
97    
98  section .text  ;=============================================================================
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 interpolate8x4_halfpel_h_mmx
109    cglobal interpolate8x4_halfpel_v_mmx
110    cglobal interpolate8x4_halfpel_hv_mmx
111    
112    cglobal interpolate8x8_avg4_mmx
113    cglobal interpolate8x8_avg2_mmx
114    
115    cglobal interpolate8x8_6tap_lowpass_h_mmx
116    cglobal interpolate8x8_6tap_lowpass_v_mmx
117    
118    cglobal interpolate8x8_halfpel_add_mmx
119    cglobal interpolate8x8_halfpel_h_add_mmx
120    cglobal interpolate8x8_halfpel_v_add_mmx
121    cglobal interpolate8x8_halfpel_hv_add_mmx
122    
123  %macro  CALC_AVG 6  %macro  CALC_AVG 6
124          punpcklbw %3, %6          punpcklbw %3, %6
# Line 100  Line 131 
131    
132          psrlw %1, 1                     ; mm01 >>= 1          psrlw %1, 1                     ; mm01 >>= 1
133          psrlw %2, 1          psrlw %2, 1
   
134  %endmacro  %endmacro
135    
136    
137  ;===========================================================================  ;-----------------------------------------------------------------------------
138  ;  ;
139  ; void interpolate8x8_halfpel_h_mmx(uint8_t * const dst,  ; void interpolate8x8_halfpel_h_mmx(uint8_t * const dst,
140  ;                                               const uint8_t * const src,  ;                                               const uint8_t * const src,
141  ;                                               const uint32_t stride,  ;                                               const uint32_t stride,
142  ;                                               const uint32_t rounding);  ;                                               const uint32_t rounding);
143  ;  ;
144  ;===========================================================================  ;-----------------------------------------------------------------------------
145    
146  %macro COPY_H_MMX 0  %macro COPY_H_MMX 0
147                  movq mm0, [esi]                  movq mm0, [esi]
# Line 131  Line 161 
161                  add edi, edx            ; dst += stride                  add edi, edx            ; dst += stride
162  %endmacro  %endmacro
163    
164  align 16  ALIGN 16
165  cglobal interpolate8x8_halfpel_h_mmx  interpolate8x8_halfpel_h_mmx:
 interpolate8x8_halfpel_h_mmx  
166    
167                  push    esi                  push    esi
168                  push    edi                  push    edi
   
169                  mov     eax, [esp + 8 + 16]             ; rounding                  mov     eax, [esp + 8 + 16]             ; rounding
170    
 interpolate8x8_halfpel_h_mmx.start  
171                  movq mm7, [rounding1_mmx + eax * 8]                  movq mm7, [rounding1_mmx + eax * 8]
172    
173                  mov     edi, [esp + 8 + 4]              ; dst                  mov     edi, [esp + 8 + 4]              ; dst
# Line 162  Line 189 
189                  pop esi                  pop esi
190    
191                  ret                  ret
192    .endfunc
193    
194    
195  ;===========================================================================  ;-----------------------------------------------------------------------------
196  ;  ;
197  ; void interpolate8x8_halfpel_v_mmx(uint8_t * const dst,  ; void interpolate8x8_halfpel_v_mmx(uint8_t * const dst,
198  ;                                               const uint8_t * const src,  ;                                               const uint8_t * const src,
199  ;                                               const uint32_t stride,  ;                                               const uint32_t stride,
200  ;                                               const uint32_t rounding);  ;                                               const uint32_t rounding);
201  ;  ;
202  ;===========================================================================  ;-----------------------------------------------------------------------------
203    
204  %macro COPY_V_MMX 0  %macro COPY_V_MMX 0
205                  movq mm0, [esi]                  movq mm0, [esi]
# Line 191  Line 219 
219                  add edi, edx            ; dst += stride                  add edi, edx            ; dst += stride
220  %endmacro  %endmacro
221    
222  align 16  ALIGN 16
223  cglobal interpolate8x8_halfpel_v_mmx  interpolate8x8_halfpel_v_mmx:
 interpolate8x8_halfpel_v_mmx  
224    
225                  push    esi                  push    esi
226                  push    edi                  push    edi
227    
228                  mov     eax, [esp + 8 + 16]             ; rounding                  mov     eax, [esp + 8 + 16]             ; rounding
229    
 interpolate8x8_halfpel_v_mmx.start  
230                  movq mm7, [rounding1_mmx + eax * 8]                  movq mm7, [rounding1_mmx + eax * 8]
231    
232                  mov     edi, [esp + 8 + 4]              ; dst                  mov     edi, [esp + 8 + 4]              ; dst
# Line 223  Line 249 
249                  pop esi                  pop esi
250    
251                  ret                  ret
252    .endfunc
253    
254    
255  ;===========================================================================  ;-----------------------------------------------------------------------------
256  ;  ;
257  ; void interpolate8x8_halfpel_hv_mmx(uint8_t * const dst,  ; void interpolate8x8_halfpel_hv_mmx(uint8_t * const dst,
258  ;                                               const uint8_t * const src,  ;                                               const uint8_t * const src,
# Line 233  Line 260 
260  ;                                               const uint32_t rounding);  ;                                               const uint32_t rounding);
261  ;  ;
262  ;  ;
263  ;===========================================================================  ;-----------------------------------------------------------------------------
264    
265  %macro COPY_HV_MMX 0  %macro COPY_HV_MMX 0
266                  ; current row                  ; current row
   
267                  movq mm0, [esi]                  movq mm0, [esi]
268                  movq mm2, [esi + 1]                  movq mm2, [esi + 1]
269    
# Line 253  Line 279 
279                  paddusw mm1, mm3                  paddusw mm1, mm3
280    
281                  ; next row                  ; next row
   
282                  movq mm4, [esi + edx]                  movq mm4, [esi + edx]
283                  movq mm2, [esi + edx + 1]                  movq mm2, [esi + edx + 1]
284    
# Line 269  Line 294 
294                  paddusw mm5, mm3                  paddusw mm5, mm3
295    
296                  ; add current + next row                  ; add current + next row
   
297                  paddusw mm0, mm4                ; mm01 += mm45                  paddusw mm0, mm4                ; mm01 += mm45
298                  paddusw mm1, mm5                  paddusw mm1, mm5
299                  paddusw mm0, mm7                ; mm01 += rounding2                  paddusw mm0, mm7                ; mm01 += rounding2
# Line 285  Line 309 
309                  add edi, edx            ; dst += stride                  add edi, edx            ; dst += stride
310  %endmacro  %endmacro
311    
312  align 16  ALIGN 16
313  cglobal interpolate8x8_halfpel_hv_mmx  interpolate8x8_halfpel_hv_mmx:
 interpolate8x8_halfpel_hv_mmx  
314    
315                  push    esi                  push    esi
316                  push    edi                  push    edi
317    
318                  mov     eax, [esp + 8 + 16]             ; rounding                  mov     eax, [esp + 8 + 16]             ; rounding
 interpolate8x8_halfpel_hv_mmx.start  
319    
320                  movq mm7, [rounding2_mmx + eax * 8]                  movq mm7, [rounding2_mmx + eax * 8]
321    
# Line 319  Line 341 
341                  pop esi                  pop esi
342    
343                  ret                  ret
344    .endfunc
345    
346  ;===========================================================================  ;-----------------------------------------------------------------------------
347    ;
348    ; void interpolate8x4_halfpel_h_mmx(uint8_t * const dst,
349    ;                       const uint8_t * const src,
350    ;                       const uint32_t stride,
351    ;                       const uint32_t rounding);
352    ;
353    ;-----------------------------------------------------------------------------
354    
355    ALIGN 16
356    interpolate8x4_halfpel_h_mmx:
357    
358      push esi
359      push edi
360      mov eax, [esp + 8 + 16]       ; rounding
361    
362      movq mm7, [rounding1_mmx + eax * 8]
363    
364      mov edi, [esp + 8 + 4]        ; dst
365      mov esi, [esp + 8 + 8]        ; src
366      mov edx, [esp + 8 + 12]       ; stride
367    
368      pxor mm6, mm6                 ; zero
369    
370      COPY_H_MMX
371      COPY_H_MMX
372      COPY_H_MMX
373      COPY_H_MMX
374    
375      pop edi
376      pop esi
377    
378      ret
379    .endfunc
380    
381    
382    ;-----------------------------------------------------------------------------
383    ;
384    ; void interpolate8x4_halfpel_v_mmx(uint8_t * const dst,
385    ;                       const uint8_t * const src,
386    ;                       const uint32_t stride,
387    ;                       const uint32_t rounding);
388    ;
389    ;-----------------------------------------------------------------------------
390    
391    ALIGN 16
392    interpolate8x4_halfpel_v_mmx:
393    
394      push esi
395      push edi
396    
397      mov eax, [esp + 8 + 16]       ; rounding
398    
399      movq mm7, [rounding1_mmx + eax * 8]
400    
401      mov edi, [esp + 8 + 4]        ; dst
402      mov esi, [esp + 8 + 8]        ; src
403      mov edx, [esp + 8 + 12]       ; stride
404    
405      pxor mm6, mm6                 ; zero
406    
407    
408      COPY_V_MMX
409      COPY_V_MMX
410      COPY_V_MMX
411      COPY_V_MMX
412    
413      pop edi
414      pop esi
415    
416      ret
417    .endfunc
418    
419    
420    ;-----------------------------------------------------------------------------
421    ;
422    ; void interpolate8x4_halfpel_hv_mmx(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    ALIGN 16
431    interpolate8x4_halfpel_hv_mmx:
432    
433      push esi
434      push edi
435    
436      mov eax, [esp + 8 + 16]   ; rounding
437    
438      movq mm7, [rounding2_mmx + eax * 8]
439    
440      mov edi, [esp + 8 + 4]    ; dst
441      mov esi, [esp + 8 + 8]    ; src
442    
443      mov eax, 8
444    
445      pxor mm6, mm6             ; zero
446    
447      mov edx, [esp + 8 + 12]   ; stride
448    
449      COPY_HV_MMX
450      COPY_HV_MMX
451      COPY_HV_MMX
452      COPY_HV_MMX
453    
454      pop edi
455      pop esi
456    
457      ret
458    .endfunc
459    
460    ;-----------------------------------------------------------------------------
461  ;  ;
462  ; void interpolate8x8_avg2_mmx(uint8_t const *dst,  ; void interpolate8x8_avg2_mmx(uint8_t const *dst,
463  ;                                                          const uint8_t * const src1,  ;                                                          const uint8_t * const src1,
# Line 329  Line 466 
466  ;                                                          const uint32_t rounding,  ;                                                          const uint32_t rounding,
467  ;                                                          const uint32_t height);  ;                                                          const uint32_t height);
468  ;  ;
469  ;===========================================================================  ;-----------------------------------------------------------------------------
470    
471  %macro AVG2_MMX_RND0 0  %macro AVG2_MMX_RND0 0
472          movq    mm0, [eax]                      ; src1 -> mm0          movq    mm0, [eax]                      ; src1 -> mm0
# Line 425  Line 562 
562          movq    [ecx+edx], mm4          movq    [ecx+edx], mm4
563  %endmacro  %endmacro
564    
565  align 16  ALIGN 16
566  cglobal interpolate8x8_avg2_mmx  interpolate8x8_avg2_mmx:
 interpolate8x8_avg2_mmx  
567    
568          push ebx          push ebx
569    
# Line 494  Line 630 
630    
631          pop ebx          pop ebx
632          ret          ret
633    .endfunc
634    
635    
636  ;===========================================================================  ;-----------------------------------------------------------------------------
637  ;  ;
638  ; void interpolate8x8_avg4_mmx(uint8_t const *dst,  ; void interpolate8x8_avg4_mmx(uint8_t const *dst,
639  ;                                                          const uint8_t * const src1,  ;                                                          const uint8_t * const src1,
# Line 506  Line 643 
643  ;                                                          const uint32_t stride,  ;                                                          const uint32_t stride,
644  ;                                                          const uint32_t rounding);  ;                                                          const uint32_t rounding);
645  ;  ;
646  ;===========================================================================  ;-----------------------------------------------------------------------------
647    
648  %macro AVG4_MMX_RND0 0  %macro AVG4_MMX_RND0 0
649          movq    mm0, [eax]                      ; src1 -> mm0          movq    mm0, [eax]                      ; src1 -> mm0
# Line 618  Line 755 
755          movq    [ecx], mm0                      ; (src1 + src2 + src3 + src4 + 2) / 4 -> dst          movq    [ecx], mm0                      ; (src1 + src2 + src3 + src4 + 2) / 4 -> dst
756  %endmacro  %endmacro
757    
758  align 16  ALIGN 16
759  cglobal interpolate8x8_avg4_mmx  interpolate8x8_avg4_mmx:
 interpolate8x8_avg4_mmx  
760    
761          push ebx          push ebx
762          push edi          push edi
# Line 683  Line 819 
819          pop edi          pop edi
820          pop ebx          pop ebx
821          ret          ret
822    .endfunc
823    
824    
825  ;===========================================================================  ;-----------------------------------------------------------------------------
826  ;  ;
827  ; void interpolate8x8_6tap_lowpass_h_mmx(uint8_t const *dst,  ; void interpolate8x8_6tap_lowpass_h_mmx(uint8_t const *dst,
828  ;                                                                            const uint8_t * const src,  ;                                                                            const uint8_t * const src,
829  ;                                                                            const uint32_t stride,  ;                                                                            const uint32_t stride,
830  ;                                                                            const uint32_t rounding);  ;                                                                            const uint32_t rounding);
831  ;  ;
832  ;===========================================================================  ;-----------------------------------------------------------------------------
833    
834  %macro LOWPASS_6TAP_H_MMX 0  %macro LOWPASS_6TAP_H_MMX 0
835          movq    mm0, [eax]          movq    mm0, [eax]
# Line 763  Line 900 
900          movq    [ecx], mm0          movq    [ecx], mm0
901  %endmacro  %endmacro
902    
903  align 16  ALIGN 16
904  cglobal interpolate8x8_6tap_lowpass_h_mmx  interpolate8x8_6tap_lowpass_h_mmx:
 interpolate8x8_6tap_lowpass_h_mmx  
905    
906          mov     eax, [esp + 16]                 ; rounding          mov     eax, [esp + 16]                 ; rounding
907    
# Line 794  Line 930 
930          LOWPASS_6TAP_H_MMX          LOWPASS_6TAP_H_MMX
931    
932          ret          ret
933    .endfunc
934    
935  ;===========================================================================  ;-----------------------------------------------------------------------------
936  ;  ;
937  ; void interpolate8x8_6tap_lowpass_v_mmx(uint8_t const *dst,  ; void interpolate8x8_6tap_lowpass_v_mmx(uint8_t const *dst,
938  ;                                                                                const uint8_t * const src,  ;                                                                                const uint8_t * const src,
939  ;                                                                                const uint32_t stride,  ;                                                                                const uint32_t stride,
940  ;                                                                            const uint32_t rounding);  ;                                                                            const uint32_t rounding);
941  ;  ;
942  ;===========================================================================  ;-----------------------------------------------------------------------------
943    
944  %macro LOWPASS_6TAP_V_MMX 0  %macro LOWPASS_6TAP_V_MMX 0
945          movq    mm0, [eax]          movq    mm0, [eax]
# Line 874  Line 1011 
1011          movq    [ecx], mm0          movq    [ecx], mm0
1012  %endmacro  %endmacro
1013    
1014  align 16  ALIGN 16
1015  cglobal interpolate8x8_6tap_lowpass_v_mmx  interpolate8x8_6tap_lowpass_v_mmx:
 interpolate8x8_6tap_lowpass_v_mmx  
1016    
1017          push ebx          push ebx
1018    
# Line 912  Line 1048 
1048    
1049          pop ebx          pop ebx
1050          ret          ret
1051    .endfunc
1052    
1053    ;===========================================================================
1054    ;
1055    ; The next functions combine both source halfpel interpolation step and the
1056    ; averaging (with rouding) step to avoid wasting memory bandwidth computing
1057    ; intermediate halfpel images and then averaging them.
1058    ;
1059    ;===========================================================================
1060    
1061    %macro PROLOG0 0
1062      mov ecx, [esp+ 4] ; Dst
1063      mov eax, [esp+ 8] ; Src
1064      mov edx, [esp+12] ; BpS
1065    %endmacro
1066    
1067    %macro PROLOG 2   ; %1: Rounder, %2 load Dst-Rounder
1068      pxor mm6, mm6
1069      movq mm7, [%1]    ; TODO: dangerous! (eax isn't checked)
1070    %if %2
1071      movq mm5, [rounding1_mmx]
1072    %endif
1073    
1074      PROLOG0
1075    %endmacro
1076    
1077      ; performs: mm0 == (mm0+mm2)  mm1 == (mm1+mm3)
1078    %macro MIX 0
1079      punpcklbw mm0, mm6
1080      punpcklbw mm2, mm6
1081      punpckhbw mm1, mm6
1082      punpckhbw mm3, mm6
1083      paddusw mm0, mm2
1084      paddusw mm1, mm3
1085    %endmacro
1086    
1087    %macro MIX_DST 0
1088      movq mm3, mm2
1089      paddusw mm0, mm7  ; rounder
1090      paddusw mm1, mm7  ; rounder
1091      punpcklbw mm2, mm6
1092      punpckhbw mm3, mm6
1093      psrlw mm0, 1
1094      psrlw mm1, 1
1095    
1096      paddusw mm0, mm2  ; mix Src(mm0/mm1) with Dst(mm2/mm3)
1097      paddusw mm1, mm3
1098      paddusw mm0, mm5
1099      paddusw mm1, mm5
1100      psrlw mm0, 1
1101      psrlw mm1, 1
1102    
1103      packuswb mm0, mm1
1104    %endmacro
1105    
1106    %macro MIX2 0
1107      punpcklbw mm0, mm6
1108      punpcklbw mm2, mm6
1109      paddusw mm0, mm2
1110      paddusw mm0, mm7
1111      punpckhbw mm1, mm6
1112      punpckhbw mm3, mm6
1113      paddusw mm1, mm7
1114      paddusw mm1, mm3
1115      psrlw mm0, 1
1116      psrlw mm1, 1
1117    
1118      packuswb mm0, mm1
1119    %endmacro
1120    
1121    ;===========================================================================
1122    ;
1123    ; void interpolate8x8_halfpel_add_mmx(uint8_t * const dst,
1124    ;                       const uint8_t * const src,
1125    ;                       const uint32_t stride,
1126    ;                       const uint32_t rounding);
1127    ;
1128    ;
1129    ;===========================================================================
1130    
1131    %macro ADD_FF_MMX 1
1132      movq mm0, [eax]
1133      movq mm2, [ecx]
1134      movq mm1, mm0
1135      movq mm3, mm2
1136    %if (%1!=0)
1137      lea eax,[eax+%1*edx]
1138    %endif
1139      MIX
1140      paddusw mm0, mm5  ; rounder
1141      paddusw mm1, mm5  ; rounder
1142      psrlw mm0, 1
1143      psrlw mm1, 1
1144    
1145      packuswb mm0, mm1
1146      movq [ecx], mm0
1147    %if (%1!=0)
1148      lea ecx,[ecx+%1*edx]
1149    %endif
1150    %endmacro
1151    
1152    ALIGN 16
1153    interpolate8x8_halfpel_add_mmx:
1154      PROLOG rounding1_mmx, 1
1155      ADD_FF_MMX 1
1156      ADD_FF_MMX 1
1157      ADD_FF_MMX 1
1158      ADD_FF_MMX 1
1159      ADD_FF_MMX 1
1160      ADD_FF_MMX 1
1161      ADD_FF_MMX 1
1162      ADD_FF_MMX 0
1163      ret
1164    .endfunc
1165    
1166    ;===========================================================================
1167    ;
1168    ; void interpolate8x8_halfpel_h_add_mmx(uint8_t * const dst,
1169    ;                       const uint8_t * const src,
1170    ;                       const uint32_t stride,
1171    ;                       const uint32_t rounding);
1172    ;
1173    ;
1174    ;===========================================================================
1175    
1176    %macro ADD_FH_MMX 0
1177      movq mm0, [eax]
1178      movq mm2, [eax+1]
1179      movq mm1, mm0
1180      movq mm3, mm2
1181    
1182      lea eax,[eax+edx]
1183    
1184      MIX
1185      movq mm2, [ecx]   ; prepare mix with Dst[0]
1186      MIX_DST
1187      movq [ecx], mm0
1188    %endmacro
1189    
1190    ALIGN 16
1191    interpolate8x8_halfpel_h_add_mmx:
1192      PROLOG rounding1_mmx, 1
1193    
1194      ADD_FH_MMX
1195      lea ecx,[ecx+edx]
1196      ADD_FH_MMX
1197      lea ecx,[ecx+edx]
1198      ADD_FH_MMX
1199      lea ecx,[ecx+edx]
1200      ADD_FH_MMX
1201      lea ecx,[ecx+edx]
1202      ADD_FH_MMX
1203      lea ecx,[ecx+edx]
1204      ADD_FH_MMX
1205      lea ecx,[ecx+edx]
1206      ADD_FH_MMX
1207      lea ecx,[ecx+edx]
1208      ADD_FH_MMX
1209      ret
1210    .endfunc
1211    
1212    ;===========================================================================
1213    ;
1214    ; void interpolate8x8_halfpel_v_add_mmx(uint8_t * const dst,
1215    ;                       const uint8_t * const src,
1216    ;                       const uint32_t stride,
1217    ;                       const uint32_t rounding);
1218    ;
1219    ;
1220    ;===========================================================================
1221    
1222    %macro ADD_HF_MMX 0
1223      movq mm0, [eax]
1224      movq mm2, [eax+edx]
1225      movq mm1, mm0
1226      movq mm3, mm2
1227    
1228      lea eax,[eax+edx]
1229    
1230      MIX
1231      movq mm2, [ecx]   ; prepare mix with Dst[0]
1232      MIX_DST
1233      movq [ecx], mm0
1234    
1235    %endmacro
1236    
1237    ALIGN 16
1238    interpolate8x8_halfpel_v_add_mmx:
1239      PROLOG rounding1_mmx, 1
1240    
1241      ADD_HF_MMX
1242      lea ecx,[ecx+edx]
1243      ADD_HF_MMX
1244      lea ecx,[ecx+edx]
1245      ADD_HF_MMX
1246      lea ecx,[ecx+edx]
1247      ADD_HF_MMX
1248      lea ecx,[ecx+edx]
1249      ADD_HF_MMX
1250      lea ecx,[ecx+edx]
1251      ADD_HF_MMX
1252      lea ecx,[ecx+edx]
1253      ADD_HF_MMX
1254      lea ecx,[ecx+edx]
1255      ADD_HF_MMX
1256      ret
1257    .endfunc
1258    
1259    ; The trick is to correct the result of 'pavgb' with some combination of the
1260    ; lsb's of the 4 input values i,j,k,l, and their intermediate 'pavgb' (s and t).
1261    ; The boolean relations are:
1262    ;   (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
1263    ;   (i+j+k+l+2)/4 = (s+t+1)/2 - (ij|kl)&st
1264    ;   (i+j+k+l+1)/4 = (s+t+1)/2 - (ij&kl)|st
1265    ;   (i+j+k+l+0)/4 = (s+t+1)/2 - (ij|kl)|st
1266    ; with  s=(i+j+1)/2, t=(k+l+1)/2, ij = i^j, kl = k^l, st = s^t.
1267    
1268    ; Moreover, we process 2 lines at a times, for better overlapping (~15% faster).
1269    
1270    ;===========================================================================
1271    ;
1272    ; void interpolate8x8_halfpel_hv_add_mmx(uint8_t * const dst,
1273    ;                       const uint8_t * const src,
1274    ;                       const uint32_t stride,
1275    ;                       const uint32_t rounding);
1276    ;
1277    ;
1278    ;===========================================================================
1279    
1280    %macro ADD_HH_MMX 0
1281      lea eax,[eax+edx]
1282    
1283        ; transfert prev line to mm0/mm1
1284      movq mm0, mm2
1285      movq mm1, mm3
1286    
1287        ; load new line in mm2/mm3
1288      movq mm2, [eax]
1289      movq mm4, [eax+1]
1290      movq mm3, mm2
1291      movq mm5, mm4
1292    
1293      punpcklbw mm2, mm6
1294      punpcklbw mm4, mm6
1295      paddusw mm2, mm4
1296      punpckhbw mm3, mm6
1297      punpckhbw mm5, mm6
1298      paddusw mm3, mm5
1299    
1300        ; mix current line (mm2/mm3) with previous (mm0,mm1);
1301        ; we'll preserve mm2/mm3 for next line...
1302    
1303      paddusw mm0, mm2
1304      paddusw mm1, mm3
1305    
1306      movq mm4, [ecx]   ; prepare mix with Dst[0]
1307      movq mm5, mm4
1308    
1309      paddusw mm0, mm7  ; finish mixing current line
1310      paddusw mm1, mm7
1311    
1312      punpcklbw mm4, mm6
1313      punpckhbw mm5, mm6
1314    
1315      psrlw mm0, 2
1316      psrlw mm1, 2
1317    
1318      paddusw mm0, mm4  ; mix Src(mm0/mm1) with Dst(mm2/mm3)
1319      paddusw mm1, mm5
1320    
1321      paddusw mm0, [rounding1_mmx]
1322      paddusw mm1, [rounding1_mmx]
1323    
1324      psrlw mm0, 1
1325      psrlw mm1, 1
1326    
1327      packuswb mm0, mm1
1328    
1329      movq [ecx], mm0
1330    %endmacro
1331    
1332    ALIGN 16
1333    interpolate8x8_halfpel_hv_add_mmx:
1334      PROLOG rounding2_mmx, 0    ; mm5 is busy. Don't load dst-rounder
1335    
1336        ; preprocess first line
1337      movq mm0, [eax]
1338      movq mm2, [eax+1]
1339      movq mm1, mm0
1340      movq mm3, mm2
1341    
1342      punpcklbw mm0, mm6
1343      punpcklbw mm2, mm6
1344      punpckhbw mm1, mm6
1345      punpckhbw mm3, mm6
1346      paddusw mm2, mm0
1347      paddusw mm3, mm1
1348    
1349       ; Input: mm2/mm3 contains the value (Src[0]+Src[1]) of previous line
1350    
1351      ADD_HH_MMX
1352      lea ecx,[ecx+edx]
1353      ADD_HH_MMX
1354      lea ecx,[ecx+edx]
1355      ADD_HH_MMX
1356      lea ecx,[ecx+edx]
1357      ADD_HH_MMX
1358      lea ecx,[ecx+edx]
1359      ADD_HH_MMX
1360      lea ecx,[ecx+edx]
1361      ADD_HH_MMX
1362      lea ecx,[ecx+edx]
1363      ADD_HH_MMX
1364      lea ecx,[ecx+edx]
1365      ADD_HH_MMX
1366    
1367      ret
1368    .endfunc
1369    

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

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