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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 308 - (view) (download)

1 : Isibaar 262 ;/**************************************************************************
2 :     ; *
3 :     ; * XVID MPEG-4 VIDEO CODEC
4 :     ; * sse2 sum of absolute difference
5 :     ; *
6 :     ; * This program is free software; you can redistribute it and/or modify
7 :     ; * it under the terms of the GNU General Public License as published by
8 :     ; * the Free Software Foundation; either version 2 of the License, or
9 :     ; * (at your option) any later version.
10 :     ; *
11 :     ; * This program is distributed in the hope that it will be useful,
12 :     ; * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 :     ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 :     ; * GNU General Public License for more details.
15 :     ; *
16 :     ; * You should have received a copy of the GNU General Public License
17 :     ; * along with this program; if not, write to the Free Software
18 :     ; * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 :     ; *
20 :     ; *************************************************************************/
21 :    
22 :     ;/**************************************************************************
23 :     ; *
24 :     ; * History:
25 :     ; *
26 :     ; * 24.05.2002 inital version; (c)2002 Dmitry Rozhdestvensky
27 :     ; *
28 :     ; *************************************************************************/
29 :    
30 :     bits 32
31 :    
32 :     %macro cglobal 1
33 :     %ifdef PREFIX
34 :     global _%1
35 :     %define %1 _%1
36 :     %else
37 :     global %1
38 :     %endif
39 :     %endmacro
40 :    
41 :     %define sad_debug 0 ;1=unaligned 2=ref unaligned 3=aligned 0=autodetect
42 :     %define dev_debug 2 ;1=unaligned 2=aligned 0=autodetect
43 :     %define test_stride_alignment 0 ;test stride for alignment while autodetect
44 :     %define early_return 0 ;use early return in sad
45 :    
46 :     section .data
47 :    
48 :     align 64
49 :     buffer times 4*8 dd 0 ;8 128-bit words
50 :     zero times 4 dd 0
51 :    
52 :     section .text
53 :    
54 :     cglobal sad16_sse2
55 :     cglobal dev16_sse2
56 :    
57 :     ;===========================================================================
58 :     ; General macros for SSE2 code
59 :     ;===========================================================================
60 :    
61 :     %macro load_stride 1
62 :     mov ecx,%1
63 :     add ecx,ecx
64 :     mov edx,ecx
65 :     add ecx,%1 ;stride*3
66 :     add edx,edx ;stride*4
67 :     %endmacro
68 :    
69 :     %macro sad8lines 1
70 :    
71 :     psadbw xmm0,[%1]
72 :     psadbw xmm1,[%1+ebx]
73 :     psadbw xmm2,[%1+ebx*2]
74 :     psadbw xmm3,[%1+ecx]
75 :    
76 :     add %1,edx
77 :    
78 :     psadbw xmm4,[%1]
79 :     psadbw xmm5,[%1+ebx]
80 :     psadbw xmm6,[%1+ebx*2]
81 :     psadbw xmm7,[%1+ecx]
82 :    
83 :     add %1,edx
84 :     %endmacro
85 :    
86 :     %macro after_sad 1 ; Summarizes 0th and 4th words of all xmm registers
87 :    
88 :     paddusw xmm0,xmm1
89 :     paddusw xmm2,xmm3
90 :     paddusw xmm4,xmm5
91 :     paddusw xmm6,xmm7
92 :    
93 :     paddusw xmm0,xmm2
94 :     paddusw xmm4,xmm6
95 :    
96 :     paddusw xmm4,xmm0
97 :     pshufd xmm5,xmm4,11111110b
98 :     paddusw xmm5,xmm4
99 :    
100 :     pextrw %1,xmm5,0 ;less latency then movd
101 :     %endmacro
102 :    
103 :     %macro restore 1 ;restores used registers
104 :    
105 :     %if %1=1
106 :     pop ebp
107 :     %endif
108 :     pop edi
109 :     pop esi
110 :     pop ebx
111 :     %endmacro
112 :    
113 :     ;===========================================================================
114 :     ;
115 :     ; uint32_t sad16_sse2 (const uint8_t * const cur,
116 :     ; const uint8_t * const ref,
117 :     ; const uint32_t stride,
118 :     ; const uint32_t best_sad);
119 :     ;
120 :     ;
121 :     ;===========================================================================
122 :    
123 :     align 16
124 :     sad16_sse2
125 :     push ebx
126 :     push esi
127 :     push edi
128 :    
129 :     mov ebx,[esp + 3*4 + 12] ;stride
130 :    
131 :     %if sad_debug<>0
132 :     mov edi,[esp + 3*4 + 4]
133 :     mov esi,[esp + 3*4 + 8]
134 :     %endif
135 :    
136 :     %if sad_debug=1
137 :     jmp sad16_sse2_ul
138 :     %endif
139 :     %if sad_debug=2
140 :     jmp sad16_sse2_semial
141 :     %endif
142 :     %if sad_debug=3
143 :     jmp sad16_sse2_al
144 :     %endif
145 :    
146 :     %if test_stride_alignment<>0
147 :     test ebx,15
148 :     jnz sad16_sse2_ul
149 :     %endif
150 :     mov edi,[esp + 3*4 + 4] ;cur (most likely aligned)
151 :    
152 :     test edi,15
153 :     cmovz esi,[esp + 3*4 + 8] ;load esi if edi is aligned
154 :     cmovnz esi,edi ;move to esi and load edi
155 :     cmovnz edi,[esp + 3*4 + 8] ;if not
156 :     jnz esi_unaligned
157 :    
158 :     test esi,15
159 :     jnz near sad16_sse2_semial
160 :     jmp sad16_sse2_al
161 :    
162 :     esi_unaligned: test edi,15
163 :     jnz near sad16_sse2_ul
164 :     jmp sad16_sse2_semial
165 :    
166 :     ;===========================================================================
167 :     ; Branch requires 16-byte alignment of esi and edi and stride
168 :     ;===========================================================================
169 :    
170 :     %macro sad16x8_al 1
171 :    
172 :     movdqa xmm0,[esi]
173 :     movdqa xmm1,[esi+ebx]
174 :     movdqa xmm2,[esi+ebx*2]
175 :     movdqa xmm3,[esi+ecx]
176 :    
177 :     add esi,edx
178 :    
179 :     movdqa xmm4,[esi]
180 :     movdqa xmm5,[esi+ebx]
181 :     movdqa xmm6,[esi+ebx*2]
182 :     movdqa xmm7,[esi+ecx]
183 :    
184 :     add esi,edx
185 :    
186 :     sad8lines edi
187 :    
188 :     after_sad %1
189 :    
190 :     %endmacro
191 :    
192 :     align 16
193 :     sad16_sse2_al
194 :    
195 :     load_stride ebx
196 :    
197 :     sad16x8_al eax
198 :    
199 :     %if early_return=1
200 :     cmp eax,[esp + 3*4 + 16] ;best_sad
201 :     jg continue_al
202 :     %endif
203 :    
204 :     sad16x8_al ebx
205 :    
206 :     add eax,ebx
207 :    
208 :     continue_al: restore 0
209 :    
210 :     ret
211 :    
212 :     ;===========================================================================
213 :     ; Branch requires 16-byte alignment of the edi and stride only
214 :     ;===========================================================================
215 :    
216 :     %macro sad16x8_semial 1
217 :    
218 :     movdqu xmm0,[esi]
219 :     movdqu xmm1,[esi+ebx]
220 :     movdqu xmm2,[esi+ebx*2]
221 :     movdqu xmm3,[esi+ecx]
222 :    
223 :     add esi,edx
224 :    
225 :     movdqu xmm4,[esi]
226 :     movdqu xmm5,[esi+ebx]
227 :     movdqu xmm6,[esi+ebx*2]
228 :     movdqu xmm7,[esi+ecx]
229 :    
230 :     add esi,edx
231 :    
232 :     sad8lines edi
233 :    
234 :     after_sad %1
235 :    
236 :     %endmacro
237 :    
238 :     align 16
239 :     sad16_sse2_semial
240 :    
241 :     load_stride ebx
242 :    
243 :     sad16x8_semial eax
244 :    
245 :     %if early_return=1
246 :     cmp eax,[esp + 3*4 + 16] ;best_sad
247 :     jg cont_semial
248 :     %endif
249 :    
250 :     sad16x8_semial ebx
251 :    
252 :     add eax,ebx
253 :    
254 :     cont_semial: restore 0
255 :    
256 :     ret
257 :    
258 :    
259 :     ;===========================================================================
260 :     ; Branch does not require alignment, even stride
261 :     ;===========================================================================
262 :    
263 :     %macro sad16x4_ul 1
264 :    
265 :     movdqu xmm0,[esi]
266 :     movdqu xmm1,[esi+ebx]
267 :     movdqu xmm2,[esi+ebx*2]
268 :     movdqu xmm3,[esi+ecx]
269 :    
270 :     add esi,edx
271 :    
272 :     movdqu xmm4,[edi]
273 :     movdqu xmm5,[edi+ebx]
274 :     movdqu xmm6,[edi+ebx*2]
275 :     movdqu xmm7,[edi+ecx]
276 :    
277 :     add edi,edx
278 :    
279 :     psadbw xmm4,xmm0
280 :     psadbw xmm5,xmm1
281 :     psadbw xmm6,xmm2
282 :     psadbw xmm7,xmm3
283 :    
284 :     paddusw xmm4,xmm5
285 :     paddusw xmm6,xmm7
286 :    
287 :     paddusw xmm4,xmm6
288 :     pshufd xmm7,xmm4,11111110b
289 :     paddusw xmm7,xmm4
290 :    
291 :     pextrw %1,xmm7,0
292 :     %endmacro
293 :    
294 :    
295 :     align 16
296 :     sad16_sse2_ul
297 :    
298 :     load_stride ebx
299 :    
300 :     push ebp
301 :    
302 :     sad16x4_ul eax
303 :    
304 :     %if early_return=1
305 :     cmp eax,[esp + 4*4 + 16] ;best_sad
306 :     jg continue_ul
307 :     %endif
308 :    
309 :     sad16x4_ul ebp
310 :     add eax,ebp
311 :    
312 :     %if early_return=1
313 :     cmp eax,[esp + 4*4 + 16] ;best_sad
314 :     jg continue_ul
315 :     %endif
316 :    
317 :     sad16x4_ul ebp
318 :     add eax,ebp
319 :    
320 :     %if early_return=1
321 :     cmp eax,[esp + 4*4 + 16] ;best_sad
322 :     jg continue_ul
323 :     %endif
324 :    
325 :     sad16x4_ul ebp
326 :     add eax,ebp
327 :    
328 :     continue_ul: restore 1
329 :    
330 :     ret
331 :    
332 :     ;===========================================================================
333 :     ;
334 :     ; uint32_t dev16_sse2(const uint8_t * const cur,
335 :     ; const uint32_t stride);
336 :     ;
337 :     ; experimental!
338 :     ;
339 :     ;===========================================================================
340 :    
341 :     align 16
342 :     dev16_sse2
343 :    
344 :     push ebx
345 :     push esi
346 :     push edi
347 :     push ebp
348 :    
349 :     mov esi, [esp + 4*4 + 4] ; cur
350 :     mov ebx, [esp + 4*4 + 8] ; stride
351 :     mov edi, buffer
352 :    
353 :     %if dev_debug=1
354 :     jmp dev16_sse2_ul
355 :     %endif
356 :    
357 :     %if dev_debug=2
358 :     jmp dev16_sse2_al
359 :     %endif
360 :    
361 :     test esi,15
362 :     jnz near dev16_sse2_ul
363 :    
364 :     %if test_stride_alignment=1
365 :     test ebx,15
366 :     jnz dev16_sse2_ul
367 :     %endif
368 :    
369 :     mov edi,esi
370 :     jmp dev16_sse2_al
371 :    
372 :     ;===========================================================================
373 :     ; Branch requires alignment of both the cur and stride
374 :     ;===========================================================================
375 :    
376 :     %macro make_mean 0
377 :     add eax,ebp ;mean 16-bit
378 :     mov al,ah ;eax= {0 0 mean/256 mean/256}
379 :     mov ebp,eax
380 :     shl ebp,16
381 :     or eax,ebp
382 :     %endmacro
383 :    
384 :     %macro sad_mean16x8_al 3 ;destination,0=zero,1=mean from eax,source
385 :    
386 :     %if %2=0
387 :     pxor xmm0,xmm0
388 :     %else
389 :     movd xmm0,eax
390 :     pshufd xmm0,xmm0,0
391 :     %endif
392 :     movdqa xmm1,xmm0
393 :     movdqa xmm2,xmm0
394 :     movdqa xmm3,xmm0
395 :     movdqa xmm4,xmm0
396 :     movdqa xmm5,xmm0
397 :     movdqa xmm6,xmm0
398 :     movdqa xmm7,xmm0
399 :    
400 :     sad8lines %3
401 :    
402 :     after_sad %1
403 :    
404 :     %endmacro
405 :    
406 :     align 16
407 :     dev16_sse2_al
408 :    
409 :     load_stride ebx
410 :    
411 :     sad_mean16x8_al eax,0,esi
412 :     sad_mean16x8_al ebp,0,esi
413 :    
414 :     make_mean
415 :    
416 :     sad_mean16x8_al ebp,1,edi
417 :     sad_mean16x8_al eax,1,edi
418 :    
419 :     add eax,ebp
420 :    
421 :     restore 1
422 :    
423 :     ret
424 :    
425 :     ;===========================================================================
426 :     ; Branch does not require alignment
427 :     ;===========================================================================
428 :    
429 :     %macro sad_mean16x8_ul 2
430 :    
431 :     pxor xmm7,xmm7
432 :    
433 :     movdqu xmm0,[%1]
434 :     movdqu xmm1,[%1+ebx]
435 :     movdqu xmm2,[%1+ebx*2]
436 :     movdqu xmm3,[%1+ecx]
437 :    
438 :     add %1,edx
439 :    
440 :     movdqa [buffer+16*0],xmm0
441 :     movdqa [buffer+16*1],xmm1
442 :     movdqa [buffer+16*2],xmm2
443 :     movdqa [buffer+16*3],xmm3
444 :    
445 :     movdqu xmm4,[%1]
446 :     movdqu xmm5,[%1+ebx]
447 :     movdqu xmm6,[%1+ebx*2]
448 :     movdqa [buffer+16*4],xmm4
449 :     movdqa [buffer+16*5],xmm5
450 :     movdqa [buffer+16*6],xmm6
451 :    
452 :     psadbw xmm0,xmm7
453 :     psadbw xmm1,xmm7
454 :     psadbw xmm2,xmm7
455 :     psadbw xmm3,xmm7
456 :     psadbw xmm4,xmm7
457 :     psadbw xmm5,xmm7
458 :     psadbw xmm6,xmm7
459 :    
460 :     movdqu xmm7,[%1+ecx]
461 :     movdqa [buffer+16*7],xmm7
462 :     psadbw xmm7,[zero]
463 :    
464 :     add %1,edx
465 :    
466 :     after_sad %2
467 :     %endmacro
468 :    
469 :     align 16
470 :     dev16_sse2_ul
471 :    
472 :     load_stride ebx
473 :    
474 :     sad_mean16x8_ul esi,eax
475 :     sad_mean16x8_ul esi,ebp
476 :    
477 :     make_mean
478 :    
479 :     sad_mean16x8_al ebp,1,edi
480 :     sad_mean16x8_al eax,1,edi
481 :    
482 :     add eax,ebp
483 :    
484 :     restore 1
485 :    
486 :     ret

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