[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 262, Sun Jul 7 09:45:40 2002 UTC revision 1833, Mon Dec 1 14:45:46 2008 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.17 2008-12-01 14:45:45 Isibaar Exp $
24  ; *  ; *
25  ; *************************************************************************/  ; ***************************************************************************/
26    
27  bits 32  %include "nasm.inc"
28    
29  %macro cglobal 1  ;=============================================================================
30          %ifdef PREFIX  ; Read only data
31                  global _%1  ;=============================================================================
                 %define %1 _%1  
         %else  
                 global %1  
         %endif  
 %endmacro  
32    
33  %define sad_debug 0 ;1=unaligned 2=ref unaligned 3=aligned 0=autodetect  DATA
 %define dev_debug 2 ;1=unaligned 2=aligned 0=autodetect  
 %define test_stride_alignment 0 ;test stride for alignment while autodetect  
 %define early_return 0 ;use early return in sad  
34    
35  section .data  ALIGN SECTION_ALIGN
   
 align 64  
 buffer  times 4*8 dd 0   ;8 128-bit words  
36  zero    times 4   dd 0  zero    times 4   dd 0
37    
38  section .text  ;=============================================================================
39    ; Code
40    ;=============================================================================
41    
42    SECTION .rotext align=SECTION_ALIGN
43    
44  cglobal  sad16_sse2  cglobal  sad16_sse2
45  cglobal  dev16_sse2  cglobal  dev16_sse2
46    
47  ;===========================================================================  cglobal  sad16_sse3
48  ;               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  
49    
50                  paddusw xmm0,xmm1  ;-----------------------------------------------------------------------------
51                  paddusw xmm2,xmm3  ; uint32_t sad16_sse2 (const uint8_t * const cur, <- assumed aligned!
                 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,  
52  ;                                       const uint8_t * const ref,  ;                                       const uint8_t * const ref,
53  ;                                       const uint32_t stride,  ;                                       const uint32_t stride,
54  ;                                       const uint32_t best_sad);  ;                      const uint32_t /*ignored*/);
55  ;  ;-----------------------------------------------------------------------------
 ;  
 ;===========================================================================  
   
 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]  
 cglobal sad16_sse2  
                 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  
56    
                 after_sad %1  
57    
58  %endmacro  %macro SAD_16x16_SSE2 1
59      %1  xmm0, [TMP1]
60  align 16    %1  xmm1, [TMP1+TMP0]
61  sad16_sse2_semial    lea TMP1,[TMP1+2*TMP0]
62      movdqa  xmm2, [_EAX]
63                  load_stride ebx    movdqa  xmm3, [_EAX+TMP0]
64      lea _EAX,[_EAX+2*TMP0]
65                  sad16x8_semial eax    psadbw  xmm0, xmm2
66      paddusw xmm6,xmm0
67  %if early_return=1    psadbw  xmm1, xmm3
68                  cmp     eax,[esp + 3*4 + 16]    ;best_sad    paddusw xmm6,xmm1
69                  jg      cont_semial  %endmacro
70  %endif  
71    %macro SAD16_SSE2_SSE3 1
72                  sad16x8_semial ebx    PUSH_XMM6_XMM7
73      mov _EAX, prm1 ; cur (assumed aligned)
74                  add     eax,ebx    mov TMP1, prm2 ; ref
75      mov TMP0, prm3 ; stride
76  cont_semial:    restore 0  
77      pxor xmm6, xmm6 ; accum
78    
79      SAD_16x16_SSE2 %1
80      SAD_16x16_SSE2 %1
81      SAD_16x16_SSE2 %1
82      SAD_16x16_SSE2 %1
83      SAD_16x16_SSE2 %1
84      SAD_16x16_SSE2 %1
85      SAD_16x16_SSE2 %1
86      SAD_16x16_SSE2 %1
87    
88      pshufd  xmm5, xmm6, 00000010b
89      paddusw xmm6, xmm5
90      pextrw  eax, xmm6, 0
91    
92      POP_XMM6_XMM7
93                  ret                  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  
94  %endmacro  %endmacro
95    
96    ALIGN SECTION_ALIGN
97  align 16  sad16_sse2:
98  sad16_sse2_ul    SAD16_SSE2_SSE3 movdqu
99    ENDFUNC
100                  load_stride ebx  
101    
102                  push ebp  ALIGN SECTION_ALIGN
103    sad16_sse3:
104                  sad16x4_ul eax    SAD16_SSE2_SSE3 lddqu
105    ENDFUNC
106  %if early_return=1  
107                  cmp     eax,[esp + 4*4 + 16]    ;best_sad  
108                  jg      continue_ul  ;-----------------------------------------------------------------------------
109  %endif  ; uint32_t dev16_sse2(const uint8_t * const cur, const uint32_t stride);
110    ;-----------------------------------------------------------------------------
111                  sad16x4_ul ebp  
112                  add     eax,ebp  %macro MEAN_16x16_SSE2 1  ; _EAX: src, TMP0:stride, mm7: zero or mean => mm6: result
113      %1 xmm0, [_EAX]
114  %if early_return=1    %1 xmm1, [_EAX+TMP0]
115                  cmp     eax,[esp + 4*4 + 16]    ;best_sad    lea _EAX, [_EAX+2*TMP0]    ; + 2*stride
116                  jg      continue_ul    psadbw xmm0, xmm7
117  %endif    paddusw xmm6, xmm0
118      psadbw xmm1, xmm7
119                  sad16x4_ul ebp    paddusw xmm6, xmm1
                 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  
 cglobal dev16_sse2  
                 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  
120  %endmacro  %endmacro
121    
 %macro sad_mean16x8_al 3        ;destination,0=zero,1=mean from eax,source  
122    
123  %if %2=0  %macro MEAN16_SSE2_SSE3 1
124                  pxor    xmm0,xmm0    PUSH_XMM6_XMM7
125  %else    mov _EAX, prm1   ; src
126                  movd    xmm0,eax    mov TMP0, prm2   ; stride
                 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  
127    
128                  after_sad %1    pxor xmm6, xmm6     ; accum
129      pxor xmm7, xmm7     ; zero
 %endmacro  
130    
131  align 16    MEAN_16x16_SSE2 %1
132  dev16_sse2_al    MEAN_16x16_SSE2 %1
133      MEAN_16x16_SSE2 %1
134      MEAN_16x16_SSE2 %1
135    
136                  load_stride ebx    MEAN_16x16_SSE2 %1
137      MEAN_16x16_SSE2 %1
138      MEAN_16x16_SSE2 %1
139      MEAN_16x16_SSE2 %1
140    
141                  sad_mean16x8_al eax,0,esi    mov _EAX, prm1       ; src again
                 sad_mean16x8_al ebp,0,esi  
142    
143                  make_mean    pshufd   xmm7, xmm6, 10b
144      paddusw  xmm7, xmm6
145      pxor     xmm6, xmm6     ; zero accum
146      psrlw    xmm7, 8        ; => Mean
147      pshuflw  xmm7, xmm7, 0  ; replicate Mean
148      packuswb xmm7, xmm7
149      pshufd   xmm7, xmm7, 00000000b
150    
151                  sad_mean16x8_al ebp,1,edi    MEAN_16x16_SSE2 %1
152                  sad_mean16x8_al eax,1,edi    MEAN_16x16_SSE2 %1
153      MEAN_16x16_SSE2 %1
154      MEAN_16x16_SSE2 %1
155    
156                  add eax,ebp    MEAN_16x16_SSE2 %1
157      MEAN_16x16_SSE2 %1
158      MEAN_16x16_SSE2 %1
159      MEAN_16x16_SSE2 %1
160    
161                  restore 1    pshufd   xmm7, xmm6, 10b
162      paddusw  xmm7, xmm6
163      pextrw eax, xmm7, 0
164    
165      POP_XMM6_XMM7
166                  ret                  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  
   
                 psadbw  xmm0,xmm7  
                 psadbw  xmm1,xmm7  
                 psadbw  xmm2,xmm7  
                 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  
167  %endmacro  %endmacro
168    
169  align 16  ALIGN SECTION_ALIGN
170  dev16_sse2_ul  dev16_sse2:
171      MEAN16_SSE2_SSE3 movdqu
172                  load_stride ebx  ENDFUNC
173    
174                  sad_mean16x8_ul esi,eax  ALIGN SECTION_ALIGN
175                  sad_mean16x8_ul esi,ebp  dev16_sse3:
176      MEAN16_SSE2_SSE3 lddqu
177    ENDFUNC
178    
                 make_mean  
179    
180                  sad_mean16x8_al ebp,1,edi  %ifidn __OUTPUT_FORMAT__,elf
181                  sad_mean16x8_al eax,1,edi  section ".note.GNU-stack" noalloc noexec nowrite progbits
182    %endif
                 add     eax,ebp  
   
                 restore 1  
183    
                 ret  

Legend:
Removed from v.262  
changed lines
  Added in v.1833

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