[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 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  ; *     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.12 2004-08-29 10:02:38 edgomez 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  ;===========================================================================  ;-----------------------------------------------------------------------------
70  ;               General macros for SSE2 code  ; uint32_t sad16_sse2 (const uint8_t * const cur, <- assumed aligned!
 ;===========================================================================  
   
 %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  
   
 ;===========================================================================  
 ;  
 ; uint32_t sad16_sse2 (const uint8_t * const cur,  
71  ;                                       const uint8_t * const ref,  ;                                       const uint8_t * const ref,
72  ;                                       const uint32_t stride,  ;                                       const uint32_t stride,
73  ;                                       const uint32_t best_sad);  ;                      const uint32_t /*ignored*/);
74  ;  ;-----------------------------------------------------------------------------
 ;  
 ;===========================================================================  
   
 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)  
   
                 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  
   
                 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  
   
 %endmacro  
   
 align 16  
 sad16_sse2_semial  
75    
                 load_stride ebx  
   
                 sad16x8_semial eax  
   
 %if early_return=1  
                 cmp     eax,[esp + 3*4 + 16]    ;best_sad  
                 jg      cont_semial  
 %endif  
   
                 sad16x8_semial ebx  
   
                 add     eax,ebx  
   
 cont_semial:    restore 0  
   
                 ret  
   
   
 ;===========================================================================  
 ;               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  
76    
77    %macro SAD_16x16_SSE2 0
78      movdqu  xmm0, [edx]
79      movdqu  xmm1, [edx+ecx]
80      lea edx,[edx+2*ecx]
81      movdqa  xmm2, [eax]
82      movdqa  xmm3, [eax+ecx]
83      lea eax,[eax+2*ecx]
84      psadbw  xmm0, xmm2
85      paddusw xmm6,xmm0
86      psadbw  xmm1, xmm3
87      paddusw xmm6,xmm1
88    %endmacro
89    
90    ALIGN 16
91    sad16_sse2:
92      mov eax, [esp+ 4] ; cur (assumed aligned)
93      mov edx, [esp+ 8] ; ref
94      mov ecx, [esp+12] ; stride
95    
96      pxor xmm6, xmm6 ; accum
97    
98      SAD_16x16_SSE2
99      SAD_16x16_SSE2
100      SAD_16x16_SSE2
101      SAD_16x16_SSE2
102      SAD_16x16_SSE2
103      SAD_16x16_SSE2
104      SAD_16x16_SSE2
105      SAD_16x16_SSE2
106    
107      pshufd  xmm5, xmm6, 00000010b
108      paddusw xmm6, xmm5
109      pextrw  eax, xmm6, 0
110                  ret                  ret
111    .endfunc
112    
 ;===========================================================================  
 ;  
 ; 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  
113    
114  %if dev_debug=1  ;-----------------------------------------------------------------------------
115                  jmp     dev16_sse2_ul  ; uint32_t dev16_sse2(const uint8_t * const cur, const uint32_t stride);
116  %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  
117    
118    %macro MEAN_16x16_SSE2 0  ; eax: src, ecx:stride, mm7: zero or mean => mm6: result
119      movdqu xmm0, [eax]
120      movdqu xmm1, [eax+ecx]
121      lea eax, [eax+2*ecx]    ; + 2*stride
122                  psadbw  xmm0,xmm7                  psadbw  xmm0,xmm7
123      paddusw xmm6, xmm0
124                  psadbw  xmm1,xmm7                  psadbw  xmm1,xmm7
125                  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  
126  %endmacro  %endmacro
127    
 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  
128    
129    ALIGN 16
130    dev16_sse2:
131      mov eax, [esp+ 4]   ; src
132      mov ecx, [esp+ 8]   ; stride
133    
134      pxor xmm6, xmm6     ; accum
135      pxor xmm7, xmm7     ; zero
136    
137      MEAN_16x16_SSE2
138      MEAN_16x16_SSE2
139      MEAN_16x16_SSE2
140      MEAN_16x16_SSE2
141    
142      MEAN_16x16_SSE2
143      MEAN_16x16_SSE2
144      MEAN_16x16_SSE2
145      MEAN_16x16_SSE2
146    
147      mov eax, [esp+ 4]       ; src again
148    
149      pshufd   xmm7, xmm6, 10b
150      paddusw  xmm7, xmm6
151      pxor     xmm6, xmm6     ; zero accum
152      psrlw    xmm7, 8        ; => Mean
153      pshuflw  xmm7, xmm7, 0  ; replicate Mean
154      packuswb xmm7, xmm7
155      pshufd   xmm7, xmm7, 00000000b
156    
157      MEAN_16x16_SSE2
158      MEAN_16x16_SSE2
159      MEAN_16x16_SSE2
160      MEAN_16x16_SSE2
161    
162      MEAN_16x16_SSE2
163      MEAN_16x16_SSE2
164      MEAN_16x16_SSE2
165      MEAN_16x16_SSE2
166    
167      pshufd   xmm7, xmm6, 10b
168      paddusw  xmm7, xmm6
169      pextrw eax, xmm7, 0
170                  ret                  ret
171    .endfunc
172    

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