[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 851, Sat Feb 15 15:22:19 2003 UTC revision 1540, Sun Aug 29 10:02:38 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
 ; *  
 ; *************************************************************************/  
   
 ;/**************************************************************************  
 ; *  
 ; *     History:  
22  ; *  ; *
23  ; * 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 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 100  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 131  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 162  Line 185 
185                  pop esi                  pop esi
186    
187                  ret                  ret
188    .endfunc
189    
190    
191  ;===========================================================================  ;-----------------------------------------------------------------------------
192  ;  ;
193  ; void interpolate8x8_halfpel_v_mmx(uint8_t * const dst,  ; void interpolate8x8_halfpel_v_mmx(uint8_t * const dst,
194  ;                                               const uint8_t * const src,  ;                                               const uint8_t * const src,
195  ;                                               const uint32_t stride,  ;                                               const uint32_t stride,
196  ;                                               const uint32_t rounding);  ;                                               const uint32_t rounding);
197  ;  ;
198  ;===========================================================================  ;-----------------------------------------------------------------------------
199    
200  %macro COPY_V_MMX 0  %macro COPY_V_MMX 0
201                  movq mm0, [esi]                  movq mm0, [esi]
# Line 191  Line 215 
215                  add edi, edx            ; dst += stride                  add edi, edx            ; dst += stride
216  %endmacro  %endmacro
217    
218  align 16  ALIGN 16
219  cglobal interpolate8x8_halfpel_v_mmx  interpolate8x8_halfpel_v_mmx:
 interpolate8x8_halfpel_v_mmx  
220    
221                  push    esi                  push    esi
222                  push    edi                  push    edi
223    
224                  mov     eax, [esp + 8 + 16]             ; rounding                  mov     eax, [esp + 8 + 16]             ; rounding
225    
 interpolate8x8_halfpel_v_mmx.start  
226                  movq mm7, [rounding1_mmx + eax * 8]                  movq mm7, [rounding1_mmx + eax * 8]
227    
228                  mov     edi, [esp + 8 + 4]              ; dst                  mov     edi, [esp + 8 + 4]              ; dst
# Line 223  Line 245 
245                  pop esi                  pop esi
246    
247                  ret                  ret
248    .endfunc
249    
250    
251  ;===========================================================================  ;-----------------------------------------------------------------------------
252  ;  ;
253  ; void interpolate8x8_halfpel_hv_mmx(uint8_t * const dst,  ; void interpolate8x8_halfpel_hv_mmx(uint8_t * const dst,
254  ;                                               const uint8_t * const src,  ;                                               const uint8_t * const src,
# Line 233  Line 256 
256  ;                                               const uint32_t rounding);  ;                                               const uint32_t rounding);
257  ;  ;
258  ;  ;
259  ;===========================================================================  ;-----------------------------------------------------------------------------
260    
261  %macro COPY_HV_MMX 0  %macro COPY_HV_MMX 0
262                  ; current row                  ; current row
   
263                  movq mm0, [esi]                  movq mm0, [esi]
264                  movq mm2, [esi + 1]                  movq mm2, [esi + 1]
265    
# Line 253  Line 275 
275                  paddusw mm1, mm3                  paddusw mm1, mm3
276    
277                  ; next row                  ; next row
   
278                  movq mm4, [esi + edx]                  movq mm4, [esi + edx]
279                  movq mm2, [esi + edx + 1]                  movq mm2, [esi + edx + 1]
280    
# Line 269  Line 290 
290                  paddusw mm5, mm3                  paddusw mm5, mm3
291    
292                  ; add current + next row                  ; add current + next row
   
293                  paddusw mm0, mm4                ; mm01 += mm45                  paddusw mm0, mm4                ; mm01 += mm45
294                  paddusw mm1, mm5                  paddusw mm1, mm5
295                  paddusw mm0, mm7                ; mm01 += rounding2                  paddusw mm0, mm7                ; mm01 += rounding2
# Line 285  Line 305 
305                  add edi, edx            ; dst += stride                  add edi, edx            ; dst += stride
306  %endmacro  %endmacro
307    
308  align 16  ALIGN 16
309  cglobal interpolate8x8_halfpel_hv_mmx  interpolate8x8_halfpel_hv_mmx:
 interpolate8x8_halfpel_hv_mmx  
310    
311                  push    esi                  push    esi
312                  push    edi                  push    edi
313    
314                  mov     eax, [esp + 8 + 16]             ; rounding                  mov     eax, [esp + 8 + 16]             ; rounding
 interpolate8x8_halfpel_hv_mmx.start  
315    
316                  movq mm7, [rounding2_mmx + eax * 8]                  movq mm7, [rounding2_mmx + eax * 8]
317    
# Line 319  Line 337 
337                  pop esi                  pop esi
338    
339                  ret                  ret
340    .endfunc
341    
342  ;===========================================================================  ;-----------------------------------------------------------------------------
343  ;  ;
344  ; void interpolate8x8_avg2_mmx(uint8_t const *dst,  ; void interpolate8x8_avg2_mmx(uint8_t const *dst,
345  ;                                                          const uint8_t * const src1,  ;                                                          const uint8_t * const src1,
# Line 329  Line 348 
348  ;                                                          const uint32_t rounding,  ;                                                          const uint32_t rounding,
349  ;                                                          const uint32_t height);  ;                                                          const uint32_t height);
350  ;  ;
351  ;===========================================================================  ;-----------------------------------------------------------------------------
352    
353  %macro AVG2_MMX_RND0 0  %macro AVG2_MMX_RND0 0
354          movq    mm0, [eax]                      ; src1 -> mm0          movq    mm0, [eax]                      ; src1 -> mm0
# Line 425  Line 444 
444          movq    [ecx+edx], mm4          movq    [ecx+edx], mm4
445  %endmacro  %endmacro
446    
447  align 16  ALIGN 16
448  cglobal interpolate8x8_avg2_mmx  interpolate8x8_avg2_mmx:
 interpolate8x8_avg2_mmx  
449    
450          push ebx          push ebx
451    
# Line 494  Line 512 
512    
513          pop ebx          pop ebx
514          ret          ret
515    .endfunc
516    
517    
518  ;===========================================================================  ;-----------------------------------------------------------------------------
519  ;  ;
520  ; void interpolate8x8_avg4_mmx(uint8_t const *dst,  ; void interpolate8x8_avg4_mmx(uint8_t const *dst,
521  ;                                                          const uint8_t * const src1,  ;                                                          const uint8_t * const src1,
# Line 506  Line 525 
525  ;                                                          const uint32_t stride,  ;                                                          const uint32_t stride,
526  ;                                                          const uint32_t rounding);  ;                                                          const uint32_t rounding);
527  ;  ;
528  ;===========================================================================  ;-----------------------------------------------------------------------------
529    
530  %macro AVG4_MMX_RND0 0  %macro AVG4_MMX_RND0 0
531          movq    mm0, [eax]                      ; src1 -> mm0          movq    mm0, [eax]                      ; src1 -> mm0
# Line 618  Line 637 
637          movq    [ecx], mm0                      ; (src1 + src2 + src3 + src4 + 2) / 4 -> dst          movq    [ecx], mm0                      ; (src1 + src2 + src3 + src4 + 2) / 4 -> dst
638  %endmacro  %endmacro
639    
640  align 16  ALIGN 16
641  cglobal interpolate8x8_avg4_mmx  interpolate8x8_avg4_mmx:
 interpolate8x8_avg4_mmx  
642    
643          push ebx          push ebx
644          push edi          push edi
# Line 683  Line 701 
701          pop edi          pop edi
702          pop ebx          pop ebx
703          ret          ret
704    .endfunc
705    
706    
707  ;===========================================================================  ;-----------------------------------------------------------------------------
708  ;  ;
709  ; void interpolate8x8_6tap_lowpass_h_mmx(uint8_t const *dst,  ; void interpolate8x8_6tap_lowpass_h_mmx(uint8_t const *dst,
710  ;                                                                            const uint8_t * const src,  ;                                                                            const uint8_t * const src,
711  ;                                                                            const uint32_t stride,  ;                                                                            const uint32_t stride,
712  ;                                                                            const uint32_t rounding);  ;                                                                            const uint32_t rounding);
713  ;  ;
714  ;===========================================================================  ;-----------------------------------------------------------------------------
715    
716  %macro LOWPASS_6TAP_H_MMX 0  %macro LOWPASS_6TAP_H_MMX 0
717          movq    mm0, [eax]          movq    mm0, [eax]
# Line 763  Line 782 
782          movq    [ecx], mm0          movq    [ecx], mm0
783  %endmacro  %endmacro
784    
785  align 16  ALIGN 16
786  cglobal interpolate8x8_6tap_lowpass_h_mmx  interpolate8x8_6tap_lowpass_h_mmx:
 interpolate8x8_6tap_lowpass_h_mmx  
787    
788          mov     eax, [esp + 16]                 ; rounding          mov     eax, [esp + 16]                 ; rounding
789    
# Line 794  Line 812 
812          LOWPASS_6TAP_H_MMX          LOWPASS_6TAP_H_MMX
813    
814          ret          ret
815    .endfunc
816    
817  ;===========================================================================  ;-----------------------------------------------------------------------------
818  ;  ;
819  ; void interpolate8x8_6tap_lowpass_v_mmx(uint8_t const *dst,  ; void interpolate8x8_6tap_lowpass_v_mmx(uint8_t const *dst,
820  ;                                                                                const uint8_t * const src,  ;                                                                                const uint8_t * const src,
821  ;                                                                                const uint32_t stride,  ;                                                                                const uint32_t stride,
822  ;                                                                            const uint32_t rounding);  ;                                                                            const uint32_t rounding);
823  ;  ;
824  ;===========================================================================  ;-----------------------------------------------------------------------------
825    
826  %macro LOWPASS_6TAP_V_MMX 0  %macro LOWPASS_6TAP_V_MMX 0
827          movq    mm0, [eax]          movq    mm0, [eax]
# Line 874  Line 893 
893          movq    [ecx], mm0          movq    [ecx], mm0
894  %endmacro  %endmacro
895    
896  align 16  ALIGN 16
897  cglobal interpolate8x8_6tap_lowpass_v_mmx  interpolate8x8_6tap_lowpass_v_mmx:
 interpolate8x8_6tap_lowpass_v_mmx  
898    
899          push ebx          push ebx
900    
# Line 912  Line 930 
930    
931          pop ebx          pop ebx
932          ret          ret
933    .endfunc
934    
935    ;===========================================================================
936    ;
937    ; The next functions combine both source halfpel interpolation step and the
938    ; averaging (with rouding) step to avoid wasting memory bandwidth computing
939    ; intermediate halfpel images and then averaging them.
940    ;
941    ;===========================================================================
942    
943    %macro PROLOG0 0
944      mov ecx, [esp+ 4] ; Dst
945      mov eax, [esp+ 8] ; Src
946      mov edx, [esp+12] ; BpS
947    %endmacro
948    
949    %macro PROLOG 2   ; %1: Rounder, %2 load Dst-Rounder
950      pxor mm6, mm6
951      movq mm7, [%1]    ; TODO: dangerous! (eax isn't checked)
952    %if %2
953      movq mm5, [rounding1_mmx]
954    %endif
955    
956      PROLOG0
957    %endmacro
958    
959      ; performs: mm0 == (mm0+mm2)  mm1 == (mm1+mm3)
960    %macro MIX 0
961      punpcklbw mm0, mm6
962      punpcklbw mm2, mm6
963      punpckhbw mm1, mm6
964      punpckhbw mm3, mm6
965      paddusw mm0, mm2
966      paddusw mm1, mm3
967    %endmacro
968    
969    %macro MIX_DST 0
970      movq mm3, mm2
971      paddusw mm0, mm7  ; rounder
972      paddusw mm1, mm7  ; rounder
973      punpcklbw mm2, mm6
974      punpckhbw mm3, mm6
975      psrlw mm0, 1
976      psrlw mm1, 1
977    
978      paddusw mm0, mm2  ; mix Src(mm0/mm1) with Dst(mm2/mm3)
979      paddusw mm1, mm3
980      paddusw mm0, mm5
981      paddusw mm1, mm5
982      psrlw mm0, 1
983      psrlw mm1, 1
984    
985      packuswb mm0, mm1
986    %endmacro
987    
988    %macro MIX2 0
989      punpcklbw mm0, mm6
990      punpcklbw mm2, mm6
991      paddusw mm0, mm2
992      paddusw mm0, mm7
993      punpckhbw mm1, mm6
994      punpckhbw mm3, mm6
995      paddusw mm1, mm7
996      paddusw mm1, mm3
997      psrlw mm0, 1
998      psrlw mm1, 1
999    
1000      packuswb mm0, mm1
1001    %endmacro
1002    
1003    ;===========================================================================
1004    ;
1005    ; void interpolate8x8_halfpel_add_mmx(uint8_t * const dst,
1006    ;                       const uint8_t * const src,
1007    ;                       const uint32_t stride,
1008    ;                       const uint32_t rounding);
1009    ;
1010    ;
1011    ;===========================================================================
1012    
1013    %macro ADD_FF_MMX 1
1014      movq mm0, [eax]
1015      movq mm2, [ecx]
1016      movq mm1, mm0
1017      movq mm3, mm2
1018    %if (%1!=0)
1019      lea eax,[eax+%1*edx]
1020    %endif
1021      MIX
1022      paddusw mm0, mm5  ; rounder
1023      paddusw mm1, mm5  ; rounder
1024      psrlw mm0, 1
1025      psrlw mm1, 1
1026    
1027      packuswb mm0, mm1
1028      movq [ecx], mm0
1029    %if (%1!=0)
1030      lea ecx,[ecx+%1*edx]
1031    %endif
1032    %endmacro
1033    
1034    ALIGN 16
1035    interpolate8x8_halfpel_add_mmx:
1036      PROLOG rounding1_mmx, 1
1037      ADD_FF_MMX 1
1038      ADD_FF_MMX 1
1039      ADD_FF_MMX 1
1040      ADD_FF_MMX 1
1041      ADD_FF_MMX 1
1042      ADD_FF_MMX 1
1043      ADD_FF_MMX 1
1044      ADD_FF_MMX 0
1045      ret
1046    .endfunc
1047    
1048    ;===========================================================================
1049    ;
1050    ; void interpolate8x8_halfpel_h_add_mmx(uint8_t * const dst,
1051    ;                       const uint8_t * const src,
1052    ;                       const uint32_t stride,
1053    ;                       const uint32_t rounding);
1054    ;
1055    ;
1056    ;===========================================================================
1057    
1058    %macro ADD_FH_MMX 0
1059      movq mm0, [eax]
1060      movq mm2, [eax+1]
1061      movq mm1, mm0
1062      movq mm3, mm2
1063    
1064      lea eax,[eax+edx]
1065    
1066      MIX
1067      movq mm2, [ecx]   ; prepare mix with Dst[0]
1068      MIX_DST
1069      movq [ecx], mm0
1070    %endmacro
1071    
1072    ALIGN 16
1073    interpolate8x8_halfpel_h_add_mmx:
1074      PROLOG rounding1_mmx, 1
1075    
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      lea ecx,[ecx+edx]
1084      ADD_FH_MMX
1085      lea ecx,[ecx+edx]
1086      ADD_FH_MMX
1087      lea ecx,[ecx+edx]
1088      ADD_FH_MMX
1089      lea ecx,[ecx+edx]
1090      ADD_FH_MMX
1091      ret
1092    .endfunc
1093    
1094    ;===========================================================================
1095    ;
1096    ; void interpolate8x8_halfpel_v_add_mmx(uint8_t * const dst,
1097    ;                       const uint8_t * const src,
1098    ;                       const uint32_t stride,
1099    ;                       const uint32_t rounding);
1100    ;
1101    ;
1102    ;===========================================================================
1103    
1104    %macro ADD_HF_MMX 0
1105      movq mm0, [eax]
1106      movq mm2, [eax+edx]
1107      movq mm1, mm0
1108      movq mm3, mm2
1109    
1110      lea eax,[eax+edx]
1111    
1112      MIX
1113      movq mm2, [ecx]   ; prepare mix with Dst[0]
1114      MIX_DST
1115      movq [ecx], mm0
1116    
1117    %endmacro
1118    
1119    ALIGN 16
1120    interpolate8x8_halfpel_v_add_mmx:
1121      PROLOG rounding1_mmx, 1
1122    
1123      ADD_HF_MMX
1124      lea ecx,[ecx+edx]
1125      ADD_HF_MMX
1126      lea ecx,[ecx+edx]
1127      ADD_HF_MMX
1128      lea ecx,[ecx+edx]
1129      ADD_HF_MMX
1130      lea ecx,[ecx+edx]
1131      ADD_HF_MMX
1132      lea ecx,[ecx+edx]
1133      ADD_HF_MMX
1134      lea ecx,[ecx+edx]
1135      ADD_HF_MMX
1136      lea ecx,[ecx+edx]
1137      ADD_HF_MMX
1138      ret
1139    .endfunc
1140    
1141    ; The trick is to correct the result of 'pavgb' with some combination of the
1142    ; lsb's of the 4 input values i,j,k,l, and their intermediate 'pavgb' (s and t).
1143    ; The boolean relations are:
1144    ;   (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
1145    ;   (i+j+k+l+2)/4 = (s+t+1)/2 - (ij|kl)&st
1146    ;   (i+j+k+l+1)/4 = (s+t+1)/2 - (ij&kl)|st
1147    ;   (i+j+k+l+0)/4 = (s+t+1)/2 - (ij|kl)|st
1148    ; with  s=(i+j+1)/2, t=(k+l+1)/2, ij = i^j, kl = k^l, st = s^t.
1149    
1150    ; Moreover, we process 2 lines at a times, for better overlapping (~15% faster).
1151    
1152    ;===========================================================================
1153    ;
1154    ; void interpolate8x8_halfpel_hv_add_mmx(uint8_t * const dst,
1155    ;                       const uint8_t * const src,
1156    ;                       const uint32_t stride,
1157    ;                       const uint32_t rounding);
1158    ;
1159    ;
1160    ;===========================================================================
1161    
1162    %macro ADD_HH_MMX 0
1163      lea eax,[eax+edx]
1164    
1165        ; transfert prev line to mm0/mm1
1166      movq mm0, mm2
1167      movq mm1, mm3
1168    
1169        ; load new line in mm2/mm3
1170      movq mm2, [eax]
1171      movq mm4, [eax+1]
1172      movq mm3, mm2
1173      movq mm5, mm4
1174    
1175      punpcklbw mm2, mm6
1176      punpcklbw mm4, mm6
1177      paddusw mm2, mm4
1178      punpckhbw mm3, mm6
1179      punpckhbw mm5, mm6
1180      paddusw mm3, mm5
1181    
1182        ; mix current line (mm2/mm3) with previous (mm0,mm1);
1183        ; we'll preserve mm2/mm3 for next line...
1184    
1185      paddusw mm0, mm2
1186      paddusw mm1, mm3
1187    
1188      movq mm4, [ecx]   ; prepare mix with Dst[0]
1189      movq mm5, mm4
1190    
1191      paddusw mm0, mm7  ; finish mixing current line
1192      paddusw mm1, mm7
1193    
1194      punpcklbw mm4, mm6
1195      punpckhbw mm5, mm6
1196    
1197      psrlw mm0, 2
1198      psrlw mm1, 2
1199    
1200      paddusw mm0, mm4  ; mix Src(mm0/mm1) with Dst(mm2/mm3)
1201      paddusw mm1, mm5
1202    
1203      paddusw mm0, [rounding1_mmx]
1204      paddusw mm1, [rounding1_mmx]
1205    
1206      psrlw mm0, 1
1207      psrlw mm1, 1
1208    
1209      packuswb mm0, mm1
1210    
1211      movq [ecx], mm0
1212    %endmacro
1213    
1214    ALIGN 16
1215    interpolate8x8_halfpel_hv_add_mmx:
1216      PROLOG rounding2_mmx, 0    ; mm5 is busy. Don't load dst-rounder
1217    
1218        ; preprocess first line
1219      movq mm0, [eax]
1220      movq mm2, [eax+1]
1221      movq mm1, mm0
1222      movq mm3, mm2
1223    
1224      punpcklbw mm0, mm6
1225      punpcklbw mm2, mm6
1226      punpckhbw mm1, mm6
1227      punpckhbw mm3, mm6
1228      paddusw mm2, mm0
1229      paddusw mm3, mm1
1230    
1231       ; Input: mm2/mm3 contains the value (Src[0]+Src[1]) of previous line
1232    
1233      ADD_HH_MMX
1234      lea ecx,[ecx+edx]
1235      ADD_HH_MMX
1236      lea ecx,[ecx+edx]
1237      ADD_HH_MMX
1238      lea ecx,[ecx+edx]
1239      ADD_HH_MMX
1240      lea ecx,[ecx+edx]
1241      ADD_HH_MMX
1242      lea ecx,[ecx+edx]
1243      ADD_HH_MMX
1244      lea ecx,[ecx+edx]
1245      ADD_HH_MMX
1246      lea ecx,[ecx+edx]
1247      ADD_HH_MMX
1248    
1249      ret
1250    .endfunc
1251    

Legend:
Removed from v.851  
changed lines
  Added in v.1540

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