[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 1839, Tue Dec 2 13:44:55 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.18 2008-12-02 13:44:55 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]  
56    
                 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  
57    
58    %macro SAD_16x16_SSE2 1
59      %1  xmm0, [TMP1]
60      %1  xmm1, [TMP1+TMP0]
61      lea TMP1,[TMP1+2*TMP0]
62      movdqa  xmm2, [_EAX]
63      movdqa  xmm3, [_EAX+TMP0]
64      lea _EAX,[_EAX+2*TMP0]
65      psadbw  xmm0, xmm2
66      paddusw xmm4,xmm0
67      psadbw  xmm1, xmm3
68      paddusw xmm4,xmm1
69  %endmacro  %endmacro
70    
71  align 16  %macro SAD16_SSE2_SSE3 1
72  sad16_sse2_semial    mov _EAX, prm1 ; cur (assumed aligned)
73      mov TMP1, prm2 ; ref
74                  load_stride ebx    mov TMP0, prm3 ; stride
75    
76                  sad16x8_semial eax    pxor xmm4, xmm4 ; accum
77    
78  %if early_return=1    SAD_16x16_SSE2 %1
79                  cmp     eax,[esp + 3*4 + 16]    ;best_sad    SAD_16x16_SSE2 %1
80                  jg      cont_semial    SAD_16x16_SSE2 %1
81  %endif    SAD_16x16_SSE2 %1
82      SAD_16x16_SSE2 %1
83                  sad16x8_semial ebx    SAD_16x16_SSE2 %1
84      SAD_16x16_SSE2 %1
85                  add     eax,ebx    SAD_16x16_SSE2 %1
   
 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  
86    
87      pshufd  xmm5, xmm4, 00000010b
88                  paddusw xmm4,xmm5                  paddusw xmm4,xmm5
89                  paddusw xmm6,xmm7    pextrw  eax, xmm4, 0
   
                 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  
90    
91                  ret                  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  
92  %endmacro  %endmacro
93    
94  %macro sad_mean16x8_al 3        ;destination,0=zero,1=mean from eax,source  ALIGN SECTION_ALIGN
95    sad16_sse2:
96  %if %2=0    SAD16_SSE2_SSE3 movdqu
97                  pxor    xmm0,xmm0  ENDFUNC
98  %else  
99                  movd    xmm0,eax  
100                  pshufd  xmm0,xmm0,0  ALIGN SECTION_ALIGN
101  %endif  sad16_sse3:
102                  movdqa  xmm1,xmm0    SAD16_SSE2_SSE3 lddqu
103                  movdqa  xmm2,xmm0  ENDFUNC
104                  movdqa  xmm3,xmm0  
105                  movdqa  xmm4,xmm0  
106                  movdqa  xmm5,xmm0  ;-----------------------------------------------------------------------------
107                  movdqa  xmm6,xmm0  ; uint32_t dev16_sse2(const uint8_t * const cur, const uint32_t stride);
108                  movdqa  xmm7,xmm0  ;-----------------------------------------------------------------------------
109    
110                  sad8lines %3  %macro MEAN_16x16_SSE2 1  ; _EAX: src, TMP0:stride, mm7: zero or mean => mm6: result
111      %1 xmm0, [_EAX]
112                  after_sad %1    %1 xmm1, [_EAX+TMP0]
113      lea _EAX, [_EAX+2*TMP0]    ; + 2*stride
114      psadbw xmm0, xmm5
115      paddusw xmm4, xmm0
116      psadbw xmm1, xmm5
117      paddusw xmm4, xmm1
118  %endmacro  %endmacro
119    
 align 16  
 dev16_sse2_al  
120    
121                  load_stride ebx  %macro MEAN16_SSE2_SSE3 1
122      mov _EAX, prm1   ; src
123      mov TMP0, prm2   ; stride
124    
125                  sad_mean16x8_al eax,0,esi    pxor xmm4, xmm4     ; accum
126                  sad_mean16x8_al ebp,0,esi    pxor xmm5, xmm5     ; zero
127    
128                  make_mean    MEAN_16x16_SSE2 %1
129      MEAN_16x16_SSE2 %1
130      MEAN_16x16_SSE2 %1
131      MEAN_16x16_SSE2 %1
132    
133                  sad_mean16x8_al ebp,1,edi    MEAN_16x16_SSE2 %1
134                  sad_mean16x8_al eax,1,edi    MEAN_16x16_SSE2 %1
135      MEAN_16x16_SSE2 %1
136      MEAN_16x16_SSE2 %1
137    
138                  add eax,ebp    mov _EAX, prm1       ; src again
139    
140                  restore 1    pshufd   xmm5, xmm4, 10b
141      paddusw  xmm5, xmm4
142                  ret    pxor     xmm4, xmm4     ; zero accum
143      psrlw    xmm5, 8        ; => Mean
144  ;===========================================================================    pshuflw  xmm5, xmm5, 0  ; replicate Mean
145  ;               Branch does not require alignment    packuswb xmm5, xmm5
146  ;===========================================================================    pshufd   xmm5, xmm5, 00000000b
147    
148  %macro sad_mean16x8_ul 2    MEAN_16x16_SSE2 %1
149      MEAN_16x16_SSE2 %1
150                  pxor    xmm7,xmm7    MEAN_16x16_SSE2 %1
151      MEAN_16x16_SSE2 %1
152                  movdqu  xmm0,[%1]  
153                  movdqu  xmm1,[%1+ebx]    MEAN_16x16_SSE2 %1
154                  movdqu  xmm2,[%1+ebx*2]    MEAN_16x16_SSE2 %1
155                  movdqu  xmm3,[%1+ecx]    MEAN_16x16_SSE2 %1
156      MEAN_16x16_SSE2 %1
                 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]  
157    
158                  add     %1,edx    pshufd   xmm5, xmm4, 10b
159      paddusw  xmm5, xmm4
160      pextrw eax, xmm5, 0
161    
162                  after_sad %2    ret
163  %endmacro  %endmacro
164    
165  align 16  ALIGN SECTION_ALIGN
166  dev16_sse2_ul  dev16_sse2:
167      MEAN16_SSE2_SSE3 movdqu
168                  load_stride ebx  ENDFUNC
169    
170                  sad_mean16x8_ul esi,eax  ALIGN SECTION_ALIGN
171                  sad_mean16x8_ul esi,ebp  dev16_sse3:
172      MEAN16_SSE2_SSE3 lddqu
173    ENDFUNC
174    
                 make_mean  
175    
176                  sad_mean16x8_al ebp,1,edi  %ifidn __OUTPUT_FORMAT__,elf
177                  sad_mean16x8_al eax,1,edi  section ".note.GNU-stack" noalloc noexec nowrite progbits
178    %endif
                 add     eax,ebp  
   
                 restore 1  
179    
                 ret  

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

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