[svn] / trunk / xvidcore / src / motion / x86_asm / sad_sse2.asm Repository:
ViewVC logotype

Diff of /trunk/xvidcore/src/motion/x86_asm/sad_sse2.asm

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

revision 851, Sat Feb 15 15:22:19 2003 UTC revision 1764, Wed Dec 6 19:55:07 2006 UTC
# Line 1  Line 1 
1  ;/**************************************************************************  ;/****************************************************************************
2  ; *  ; *
3  ; *     XVID MPEG-4 VIDEO CODEC  ; *     XVID MPEG-4 VIDEO CODEC
4  ; *     sse2 sum of absolute difference  ; *  - SSE2 optimized SAD operators -
5  ; *  ; *
6  ; *     This program is free software; you can redistribute it and/or modify  ; *  Copyright(C) 2003 Pascal Massimino <skal@planet-d.net>
7  ; *     it under the terms of the GNU General Public License as published by  ; *
8    ; *
9    ; *  This program is free software; you can redistribute it and/or modify it
10    ; *  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 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  ; *     24.05.2002      inital version; (c)2002 Dmitry Rozhdestvensky  ; * $Id: sad_sse2.asm,v 1.13 2006-12-06 19:55:07 Isibaar Exp $
24  ; *  ; *
25  ; *************************************************************************/  ; ***************************************************************************/
26    
27  bits 32  BITS 32
28    
29  %macro cglobal 1  %macro cglobal 1
30          %ifdef PREFIX          %ifdef PREFIX
31                    %ifdef MARK_FUNCS
32                            global _%1:function %1.endfunc-%1
33                            %define %1 _%1:function %1.endfunc-%1
34                    %else
35                  global _%1                  global _%1
36                  %define %1 _%1                  %define %1 _%1
37                    %endif
38            %else
39                    %ifdef MARK_FUNCS
40                            global %1:function %1.endfunc-%1
41          %else          %else
42                  global %1                  global %1
43          %endif          %endif
44            %endif
45  %endmacro  %endmacro
46    
47  %define sad_debug 0 ;1=unaligned 2=ref unaligned 3=aligned 0=autodetect  ;=============================================================================
48  %define dev_debug 2 ;1=unaligned 2=aligned 0=autodetect  ; Read only data
49  %define test_stride_alignment 0 ;test stride for alignment while autodetect  ;=============================================================================
 %define early_return 0 ;use early return in sad  
50    
51  section .data  %ifdef FORMAT_COFF
52    SECTION .rodata
53    %else
54    SECTION .rodata align=16
55    %endif
56    
57  align 64  ALIGN 64
 buffer  times 4*8 dd 0   ;8 128-bit words  
58  zero    times 4   dd 0  zero    times 4   dd 0
59    
60  section .text  ;=============================================================================
61    ; Code
62    ;=============================================================================
63    
64    SECTION .text
65    
66  cglobal  sad16_sse2  cglobal  sad16_sse2
67  cglobal  dev16_sse2  cglobal  dev16_sse2
68    
69  ;===========================================================================  cglobal  sad16_sse3
70  ;               General macros for SSE2 code  cglobal  dev16_sse3
 ;===========================================================================  
   
 %macro load_stride 1  
                 mov     ecx,%1  
                 add     ecx,ecx  
                 mov     edx,ecx  
                 add     ecx,%1          ;stride*3  
                 add     edx,edx         ;stride*4  
 %endmacro  
   
 %macro sad8lines 1  
   
                 psadbw  xmm0,[%1]  
                 psadbw  xmm1,[%1+ebx]  
                 psadbw  xmm2,[%1+ebx*2]  
                 psadbw  xmm3,[%1+ecx]  
   
                 add     %1,edx  
   
                 psadbw  xmm4,[%1]  
                 psadbw  xmm5,[%1+ebx]  
                 psadbw  xmm6,[%1+ebx*2]  
                 psadbw  xmm7,[%1+ecx]  
   
                 add     %1,edx  
 %endmacro  
   
 %macro after_sad 1 ; Summarizes 0th and 4th words of all xmm registers  
   
                 paddusw xmm0,xmm1  
                 paddusw xmm2,xmm3  
                 paddusw xmm4,xmm5  
                 paddusw xmm6,xmm7  
   
                 paddusw xmm0,xmm2  
                 paddusw xmm4,xmm6  
   
                 paddusw xmm4,xmm0  
                 pshufd  xmm5,xmm4,11111110b  
                 paddusw xmm5,xmm4  
   
                 pextrw  %1,xmm5,0       ;less latency then movd  
 %endmacro  
   
 %macro restore 1  ;restores used registers  
   
 %if %1=1  
                 pop ebp  
 %endif  
                 pop edi  
                 pop esi  
                 pop ebx  
 %endmacro  
71    
72  ;===========================================================================  ;-----------------------------------------------------------------------------
73  ;  ; uint32_t sad16_sse2 (const uint8_t * const cur, <- assumed aligned!
 ; uint32_t sad16_sse2 (const uint8_t * const cur,  
74  ;                                       const uint8_t * const ref,  ;                                       const uint8_t * const ref,
75  ;                                       const uint32_t stride,  ;                                       const uint32_t stride,
76  ;                                       const uint32_t best_sad);  ;                      const uint32_t /*ignored*/);
77  ;  ;-----------------------------------------------------------------------------
 ;  
 ;===========================================================================  
   
 align 16  
 sad16_sse2  
                 push    ebx  
                 push    esi  
                 push    edi  
   
                 mov     ebx,[esp + 3*4 + 12]    ;stride  
   
 %if sad_debug<>0  
                 mov     edi,[esp + 3*4 + 4]  
                 mov     esi,[esp + 3*4 + 8]  
 %endif  
   
 %if sad_debug=1  
                 jmp     sad16_sse2_ul  
 %endif  
 %if sad_debug=2  
                 jmp     sad16_sse2_semial  
 %endif  
 %if sad_debug=3  
                 jmp     sad16_sse2_al  
 %endif  
   
 %if test_stride_alignment<>0  
                 test    ebx,15  
                 jnz     sad16_sse2_ul  
 %endif  
                 mov     edi,[esp + 3*4 + 4]     ;cur (most likely aligned)  
78    
                 test    edi,15  
                 cmovz   esi,[esp + 3*4 + 8]     ;load esi if edi is aligned  
                 cmovnz  esi,edi                 ;move to esi and load edi  
                 cmovnz  edi,[esp + 3*4 + 8]     ;if not  
                 jnz     esi_unaligned  
   
                 test    esi,15  
                 jnz     near sad16_sse2_semial  
                 jmp     sad16_sse2_al  
   
 esi_unaligned:  test    edi,15  
                 jnz     near sad16_sse2_ul  
                 jmp     sad16_sse2_semial  
   
 ;===========================================================================  
 ;       Branch requires 16-byte alignment of esi and edi and stride  
 ;===========================================================================  
   
 %macro sad16x8_al 1  
   
                 movdqa  xmm0,[esi]  
                 movdqa  xmm1,[esi+ebx]  
                 movdqa  xmm2,[esi+ebx*2]  
                 movdqa  xmm3,[esi+ecx]  
   
                 add     esi,edx  
   
                 movdqa  xmm4,[esi]  
                 movdqa  xmm5,[esi+ebx]  
                 movdqa  xmm6,[esi+ebx*2]  
                 movdqa  xmm7,[esi+ecx]  
   
                 add     esi,edx  
   
                 sad8lines edi  
   
                 after_sad %1  
   
 %endmacro  
   
 align 16  
 sad16_sse2_al  
   
                 load_stride ebx  
   
                 sad16x8_al eax  
   
 %if early_return=1  
                 cmp     eax,[esp + 3*4 + 16]    ;best_sad  
                 jg      continue_al  
 %endif  
   
                 sad16x8_al ebx  
   
                 add     eax,ebx  
   
 continue_al:    restore 0  
79    
80    %macro SAD_16x16_SSE2 1
81      %1  xmm0, [edx]
82      %1  xmm1, [edx+ecx]
83      lea edx,[edx+2*ecx]
84      movdqa  xmm2, [eax]
85      movdqa  xmm3, [eax+ecx]
86      lea eax,[eax+2*ecx]
87      psadbw  xmm0, xmm2
88      paddusw xmm6,xmm0
89      psadbw  xmm1, xmm3
90      paddusw xmm6,xmm1
91    %endmacro
92    
93    %macro SAD16_SSE2_SSE3 1
94      mov eax, [esp+ 4] ; cur (assumed aligned)
95      mov edx, [esp+ 8] ; ref
96      mov ecx, [esp+12] ; stride
97    
98      pxor xmm6, xmm6 ; accum
99    
100      SAD_16x16_SSE2 %1
101      SAD_16x16_SSE2 %1
102      SAD_16x16_SSE2 %1
103      SAD_16x16_SSE2 %1
104      SAD_16x16_SSE2 %1
105      SAD_16x16_SSE2 %1
106      SAD_16x16_SSE2 %1
107      SAD_16x16_SSE2 %1
108    
109      pshufd  xmm5, xmm6, 00000010b
110      paddusw xmm6, xmm5
111      pextrw  eax, xmm6, 0
112                  ret                  ret
   
 ;===========================================================================  
 ;       Branch requires 16-byte alignment of the edi and stride only  
 ;===========================================================================  
   
 %macro sad16x8_semial 1  
   
                 movdqu  xmm0,[esi]  
                 movdqu  xmm1,[esi+ebx]  
                 movdqu  xmm2,[esi+ebx*2]  
                 movdqu  xmm3,[esi+ecx]  
   
                 add     esi,edx  
   
                 movdqu  xmm4,[esi]  
                 movdqu  xmm5,[esi+ebx]  
                 movdqu  xmm6,[esi+ebx*2]  
                 movdqu  xmm7,[esi+ecx]  
   
                 add     esi,edx  
   
                 sad8lines edi  
   
                 after_sad %1  
   
113  %endmacro  %endmacro
114    
115  align 16  ALIGN 16
116  sad16_sse2_semial  sad16_sse2:
117      SAD16_SSE2_SSE3 movdqu
118                  load_stride ebx  .endfunc
119    
120                  sad16x8_semial eax  
121    ALIGN 16
122  %if early_return=1  sad16_sse3:
123                  cmp     eax,[esp + 3*4 + 16]    ;best_sad    SAD16_SSE2_SSE3 lddqu
124                  jg      cont_semial  .endfunc
125  %endif  
126    
127                  sad16x8_semial ebx  ;-----------------------------------------------------------------------------
128    ; uint32_t dev16_sse2(const uint8_t * const cur, const uint32_t stride);
129                  add     eax,ebx  ;-----------------------------------------------------------------------------
130    
131  cont_semial:    restore 0  %macro MEAN_16x16_SSE2 1  ; eax: src, ecx:stride, mm7: zero or mean => mm6: result
132      %1 xmm0, [eax]
133                  ret    %1 xmm1, [eax+ecx]
134      lea eax, [eax+2*ecx]    ; + 2*stride
   
 ;===========================================================================  
 ;               Branch does not require alignment, even stride  
 ;===========================================================================  
   
 %macro sad16x4_ul 1  
   
                 movdqu  xmm0,[esi]  
                 movdqu  xmm1,[esi+ebx]  
                 movdqu  xmm2,[esi+ebx*2]  
                 movdqu  xmm3,[esi+ecx]  
   
                 add     esi,edx  
   
                 movdqu  xmm4,[edi]  
                 movdqu  xmm5,[edi+ebx]  
                 movdqu  xmm6,[edi+ebx*2]  
                 movdqu  xmm7,[edi+ecx]  
   
                 add     edi,edx  
   
                 psadbw  xmm4,xmm0  
                 psadbw  xmm5,xmm1  
                 psadbw  xmm6,xmm2  
                 psadbw  xmm7,xmm3  
   
                 paddusw xmm4,xmm5  
                 paddusw xmm6,xmm7  
   
                 paddusw xmm4,xmm6  
                 pshufd  xmm7,xmm4,11111110b  
                 paddusw xmm7,xmm4  
   
                 pextrw  %1,xmm7,0  
 %endmacro  
   
   
 align 16  
 sad16_sse2_ul  
   
                 load_stride ebx  
   
                 push ebp  
   
                 sad16x4_ul eax  
   
 %if early_return=1  
                 cmp     eax,[esp + 4*4 + 16]    ;best_sad  
                 jg      continue_ul  
 %endif  
   
                 sad16x4_ul ebp  
                 add     eax,ebp  
   
 %if early_return=1  
                 cmp     eax,[esp + 4*4 + 16]    ;best_sad  
                 jg      continue_ul  
 %endif  
   
                 sad16x4_ul ebp  
                 add     eax,ebp  
   
 %if early_return=1  
                 cmp     eax,[esp + 4*4 + 16]    ;best_sad  
                 jg      continue_ul  
 %endif  
   
                 sad16x4_ul ebp  
                 add     eax,ebp  
   
 continue_ul:    restore 1  
   
                 ret  
   
 ;===========================================================================  
 ;  
 ; uint32_t dev16_sse2(const uint8_t * const cur,  
 ;                                       const uint32_t stride);  
 ;  
 ; experimental!  
 ;  
 ;===========================================================================  
   
 align 16  
 dev16_sse2  
   
                 push    ebx  
                 push    esi  
                 push    edi  
                 push    ebp  
   
                 mov     esi, [esp + 4*4 + 4]      ; cur  
                 mov     ebx, [esp + 4*4 + 8]      ; stride  
                 mov     edi, buffer  
   
 %if dev_debug=1  
                 jmp     dev16_sse2_ul  
 %endif  
   
 %if dev_debug=2  
                 jmp     dev16_sse2_al  
 %endif  
   
                 test    esi,15  
                 jnz     near dev16_sse2_ul  
   
 %if test_stride_alignment=1  
                 test    ebx,15  
                 jnz     dev16_sse2_ul  
 %endif  
   
                 mov     edi,esi  
                 jmp     dev16_sse2_al  
   
 ;===========================================================================  
 ;               Branch requires alignment of both the cur and stride  
 ;===========================================================================  
   
 %macro make_mean 0  
                 add     eax,ebp         ;mean 16-bit  
                 mov     al,ah           ;eax= {0 0 mean/256 mean/256}  
                 mov     ebp,eax  
                 shl     ebp,16  
                 or      eax,ebp  
 %endmacro  
   
 %macro sad_mean16x8_al 3        ;destination,0=zero,1=mean from eax,source  
   
 %if %2=0  
                 pxor    xmm0,xmm0  
 %else  
                 movd    xmm0,eax  
                 pshufd  xmm0,xmm0,0  
 %endif  
                 movdqa  xmm1,xmm0  
                 movdqa  xmm2,xmm0  
                 movdqa  xmm3,xmm0  
                 movdqa  xmm4,xmm0  
                 movdqa  xmm5,xmm0  
                 movdqa  xmm6,xmm0  
                 movdqa  xmm7,xmm0  
   
                 sad8lines %3  
   
                 after_sad %1  
   
 %endmacro  
   
 align 16  
 dev16_sse2_al  
   
                 load_stride ebx  
   
                 sad_mean16x8_al eax,0,esi  
                 sad_mean16x8_al ebp,0,esi  
   
                 make_mean  
   
                 sad_mean16x8_al ebp,1,edi  
                 sad_mean16x8_al eax,1,edi  
   
                 add eax,ebp  
   
                 restore 1  
   
                 ret  
   
 ;===========================================================================  
 ;               Branch does not require alignment  
 ;===========================================================================  
   
 %macro sad_mean16x8_ul 2  
   
                 pxor    xmm7,xmm7  
   
                 movdqu  xmm0,[%1]  
                 movdqu  xmm1,[%1+ebx]  
                 movdqu  xmm2,[%1+ebx*2]  
                 movdqu  xmm3,[%1+ecx]  
   
                 add     %1,edx  
   
                 movdqa  [buffer+16*0],xmm0  
                 movdqa  [buffer+16*1],xmm1  
                 movdqa  [buffer+16*2],xmm2  
                 movdqa  [buffer+16*3],xmm3  
   
                 movdqu  xmm4,[%1]  
                 movdqu  xmm5,[%1+ebx]  
                 movdqu  xmm6,[%1+ebx*2]  
                 movdqa  [buffer+16*4],xmm4  
                 movdqa  [buffer+16*5],xmm5  
                 movdqa  [buffer+16*6],xmm6  
   
135                  psadbw  xmm0,xmm7                  psadbw  xmm0,xmm7
136      paddusw xmm6, xmm0
137                  psadbw  xmm1,xmm7                  psadbw  xmm1,xmm7
138                  psadbw  xmm2,xmm7    paddusw xmm6, xmm1
                 psadbw  xmm3,xmm7  
                 psadbw  xmm4,xmm7  
                 psadbw  xmm5,xmm7  
                 psadbw  xmm6,xmm7  
   
                 movdqu  xmm7,[%1+ecx]  
                 movdqa  [buffer+16*7],xmm7  
                 psadbw  xmm7,[zero]  
   
                 add     %1,edx  
   
                 after_sad %2  
139  %endmacro  %endmacro
140    
 align 16  
 dev16_sse2_ul  
   
                 load_stride ebx  
   
                 sad_mean16x8_ul esi,eax  
                 sad_mean16x8_ul esi,ebp  
   
                 make_mean  
   
                 sad_mean16x8_al ebp,1,edi  
                 sad_mean16x8_al eax,1,edi  
   
                 add     eax,ebp  
   
                 restore 1  
141    
142    %macro MEAN16_SSE2_SSE3 1
143      mov eax, [esp+ 4]   ; src
144      mov ecx, [esp+ 8]   ; stride
145    
146      pxor xmm6, xmm6     ; accum
147      pxor xmm7, xmm7     ; zero
148    
149      MEAN_16x16_SSE2 %1
150      MEAN_16x16_SSE2 %1
151      MEAN_16x16_SSE2 %1
152      MEAN_16x16_SSE2 %1
153    
154      MEAN_16x16_SSE2 %1
155      MEAN_16x16_SSE2 %1
156      MEAN_16x16_SSE2 %1
157      MEAN_16x16_SSE2 %1
158    
159      mov eax, [esp+ 4]       ; src again
160    
161      pshufd   xmm7, xmm6, 10b
162      paddusw  xmm7, xmm6
163      pxor     xmm6, xmm6     ; zero accum
164      psrlw    xmm7, 8        ; => Mean
165      pshuflw  xmm7, xmm7, 0  ; replicate Mean
166      packuswb xmm7, xmm7
167      pshufd   xmm7, xmm7, 00000000b
168    
169      MEAN_16x16_SSE2 %1
170      MEAN_16x16_SSE2 %1
171      MEAN_16x16_SSE2 %1
172      MEAN_16x16_SSE2 %1
173    
174      MEAN_16x16_SSE2 %1
175      MEAN_16x16_SSE2 %1
176      MEAN_16x16_SSE2 %1
177      MEAN_16x16_SSE2 %1
178    
179      pshufd   xmm7, xmm6, 10b
180      paddusw  xmm7, xmm6
181      pextrw eax, xmm7, 0
182                  ret                  ret
183    %endmacro
184    
185    ALIGN 16
186    dev16_sse2:
187      MEAN16_SSE2_SSE3 movdqu
188    .endfunc
189    
190    ALIGN 16
191    dev16_sse3:
192      MEAN16_SSE2_SSE3 lddqu
193    .endfunc

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

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