[svn] / trunk / xvidcore / src / image / x86_asm / interpolate8x8_mmx.asm Repository:
ViewVC logotype

Annotation of /trunk/xvidcore/src/image/x86_asm/interpolate8x8_mmx.asm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1632 - (view) (download)

1 : edgomez 1382 ;/*****************************************************************************
2 : Isibaar 262 ; *
3 : edgomez 1382 ; * XVID MPEG-4 VIDEO CODEC
4 :     ; * - mmx 8x8 block-based halfpel interpolation -
5 : Isibaar 262 ; *
6 : edgomez 1382 ; * Copyright(C) 2001 Peter Ross <pross@xvid.org>
7 :     ; * 2002 Michael Militzer <isibaar@xvid.org>
8 : Isibaar 262 ; *
9 : edgomez 1382 ; * This program is free software ; you can redistribute it and/or modify
10 :     ; * it under the terms of the GNU General Public License as published by
11 :     ; * the Free Software Foundation ; either version 2 of the License, or
12 :     ; * (at your option) any later version.
13 : Isibaar 262 ; *
14 : edgomez 1382 ; * This program is distributed in the hope that it will be useful,
15 :     ; * but WITHOUT ANY WARRANTY ; without even the implied warranty of
16 :     ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 :     ; * GNU General Public License for more details.
18 : Isibaar 262 ; *
19 : edgomez 1382 ; * You should have received a copy of the GNU General Public License
20 :     ; * along with this program ; if not, write to the Free Software
21 :     ; * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 : Isibaar 262 ; *
23 : edgomez 1382 ; ****************************************************************************/
24 : Isibaar 262
25 : edgomez 1382 BITS 32
26 : edgomez 851
27 : edgomez 1382 %macro cglobal 1
28 : Isibaar 262 %ifdef PREFIX
29 : edgomez 1535 %ifdef MARK_FUNCS
30 : edgomez 1540 global _%1:function %1.endfunc-%1
31 :     %define %1 _%1:function %1.endfunc-%1
32 : edgomez 1535 %else
33 :     global _%1
34 :     %define %1 _%1
35 :     %endif
36 : Isibaar 262 %else
37 : edgomez 1535 %ifdef MARK_FUNCS
38 : edgomez 1540 global %1:function %1.endfunc-%1
39 : edgomez 1535 %else
40 :     global %1
41 :     %endif
42 : Isibaar 262 %endif
43 :     %endmacro
44 :    
45 : edgomez 1382 ;=============================================================================
46 :     ; Read only data
47 :     ;=============================================================================
48 : Isibaar 262
49 : edgomez 1382 %ifdef FORMAT_COFF
50 : edgomez 1519 SECTION .rodata
51 : edgomez 1382 %else
52 : edgomez 1519 SECTION .rodata align=16
53 : edgomez 1382 %endif
54 : Isibaar 262
55 : edgomez 1382 ;-----------------------------------------------------------------------------
56 : edgomez 851 ; (16 - r) rounding table
57 : edgomez 1382 ;-----------------------------------------------------------------------------
58 : edgomez 851
59 : edgomez 1382 ALIGN 16
60 :     rounding_lowpass_mmx:
61 :     times 4 dw 16
62 :     times 4 dw 15
63 : edgomez 851
64 : edgomez 1382 ;-----------------------------------------------------------------------------
65 : Isibaar 262 ; (1 - r) rounding table
66 : edgomez 1382 ;-----------------------------------------------------------------------------
67 : Isibaar 262
68 : edgomez 1382 rounding1_mmx:
69 :     times 4 dw 1
70 :     times 4 dw 0
71 : Isibaar 262
72 : edgomez 1382 ;-----------------------------------------------------------------------------
73 :     ; (2 - r) rounding table
74 :     ;-----------------------------------------------------------------------------
75 : Isibaar 262
76 : edgomez 1382 rounding2_mmx:
77 :     times 4 dw 2
78 :     times 4 dw 1
79 : Isibaar 262
80 : edgomez 1382 mmx_one:
81 :     times 8 db 1
82 : Isibaar 262
83 : edgomez 1382 mmx_two:
84 :     times 8 db 2
85 : edgomez 851
86 : edgomez 1382 mmx_three:
87 :     times 8 db 3
88 : edgomez 851
89 : edgomez 1382 mmx_five:
90 :     times 4 dw 5
91 : edgomez 851
92 : edgomez 1382 mmx_mask:
93 :     times 8 db 254
94 : edgomez 851
95 : edgomez 1382 mmx_mask2:
96 :     times 8 db 252
97 : edgomez 851
98 : edgomez 1382 ;=============================================================================
99 :     ; Code
100 :     ;=============================================================================
101 : Isibaar 262
102 : edgomez 1382 SECTION .text
103 :    
104 :     cglobal interpolate8x8_halfpel_h_mmx
105 :     cglobal interpolate8x8_halfpel_v_mmx
106 :     cglobal interpolate8x8_halfpel_hv_mmx
107 : edgomez 1530
108 : suxen_drol 1632 cglobal interpolate8x4_halfpel_h_mmx
109 :     cglobal interpolate8x4_halfpel_v_mmx
110 :     cglobal interpolate8x4_halfpel_hv_mmx
111 :    
112 : edgomez 1382 cglobal interpolate8x8_avg4_mmx
113 :     cglobal interpolate8x8_avg2_mmx
114 : edgomez 1530
115 : edgomez 1382 cglobal interpolate8x8_6tap_lowpass_h_mmx
116 :     cglobal interpolate8x8_6tap_lowpass_v_mmx
117 :    
118 : edgomez 1530 cglobal interpolate8x8_halfpel_add_mmx
119 :     cglobal interpolate8x8_halfpel_h_add_mmx
120 :     cglobal interpolate8x8_halfpel_v_add_mmx
121 :     cglobal interpolate8x8_halfpel_hv_add_mmx
122 :    
123 : Isibaar 262 %macro CALC_AVG 6
124 : edgomez 1382 punpcklbw %3, %6
125 :     punpckhbw %4, %6
126 : Isibaar 262
127 : edgomez 1382 paddusw %1, %3 ; mm01 += mm23
128 :     paddusw %2, %4
129 :     paddusw %1, %5 ; mm01 += rounding
130 :     paddusw %2, %5
131 : Isibaar 262
132 : edgomez 1382 psrlw %1, 1 ; mm01 >>= 1
133 :     psrlw %2, 1
134 : Isibaar 262 %endmacro
135 :    
136 :    
137 : edgomez 1382 ;-----------------------------------------------------------------------------
138 : Isibaar 262 ;
139 :     ; void interpolate8x8_halfpel_h_mmx(uint8_t * const dst,
140 : edgomez 1382 ; const uint8_t * const src,
141 :     ; const uint32_t stride,
142 :     ; const uint32_t rounding);
143 : Isibaar 262 ;
144 : edgomez 1382 ;-----------------------------------------------------------------------------
145 : Isibaar 262
146 :     %macro COPY_H_MMX 0
147 : edgomez 1382 movq mm0, [esi]
148 :     movq mm2, [esi + 1]
149 :     movq mm1, mm0
150 :     movq mm3, mm2
151 : Isibaar 262
152 : edgomez 1382 punpcklbw mm0, mm6 ; mm01 = [src]
153 :     punpckhbw mm1, mm6 ; mm23 = [src + 1]
154 : Isibaar 262
155 : edgomez 1382 CALC_AVG mm0, mm1, mm2, mm3, mm7, mm6
156 : Isibaar 262
157 : edgomez 1382 packuswb mm0, mm1
158 :     movq [edi], mm0 ; [dst] = mm01
159 : Isibaar 262
160 : edgomez 1382 add esi, edx ; src += stride
161 :     add edi, edx ; dst += stride
162 : Isibaar 262 %endmacro
163 :    
164 : edgomez 1382 ALIGN 16
165 :     interpolate8x8_halfpel_h_mmx:
166 : Isibaar 262
167 : edgomez 1382 push esi
168 :     push edi
169 :     mov eax, [esp + 8 + 16] ; rounding
170 : Isibaar 262
171 : edgomez 1382 movq mm7, [rounding1_mmx + eax * 8]
172 : Isibaar 262
173 : edgomez 1382 mov edi, [esp + 8 + 4] ; dst
174 :     mov esi, [esp + 8 + 8] ; src
175 :     mov edx, [esp + 8 + 12] ; stride
176 : Isibaar 262
177 : edgomez 1382 pxor mm6, mm6 ; zero
178 : Isibaar 262
179 : edgomez 1382 COPY_H_MMX
180 :     COPY_H_MMX
181 :     COPY_H_MMX
182 :     COPY_H_MMX
183 :     COPY_H_MMX
184 :     COPY_H_MMX
185 :     COPY_H_MMX
186 :     COPY_H_MMX
187 : Isibaar 262
188 : edgomez 1382 pop edi
189 :     pop esi
190 : Isibaar 262
191 : edgomez 1382 ret
192 : edgomez 1540 .endfunc
193 : Isibaar 262
194 :    
195 : edgomez 1382 ;-----------------------------------------------------------------------------
196 : Isibaar 262 ;
197 :     ; void interpolate8x8_halfpel_v_mmx(uint8_t * const dst,
198 : edgomez 1382 ; const uint8_t * const src,
199 :     ; const uint32_t stride,
200 :     ; const uint32_t rounding);
201 : Isibaar 262 ;
202 : edgomez 1382 ;-----------------------------------------------------------------------------
203 : Isibaar 262
204 :     %macro COPY_V_MMX 0
205 : edgomez 1382 movq mm0, [esi]
206 :     movq mm2, [esi + edx]
207 :     movq mm1, mm0
208 :     movq mm3, mm2
209 : Isibaar 262
210 : edgomez 1382 punpcklbw mm0, mm6 ; mm01 = [src]
211 :     punpckhbw mm1, mm6 ; mm23 = [src + 1]
212 : Isibaar 262
213 : edgomez 1382 CALC_AVG mm0, mm1, mm2, mm3, mm7, mm6
214 : Isibaar 262
215 : edgomez 1382 packuswb mm0, mm1
216 :     movq [edi], mm0 ; [dst] = mm01
217 : Isibaar 262
218 : edgomez 1382 add esi, edx ; src += stride
219 :     add edi, edx ; dst += stride
220 : Isibaar 262 %endmacro
221 :    
222 : edgomez 1382 ALIGN 16
223 :     interpolate8x8_halfpel_v_mmx:
224 : Isibaar 262
225 : edgomez 1382 push esi
226 :     push edi
227 : Isibaar 262
228 : edgomez 1382 mov eax, [esp + 8 + 16] ; rounding
229 : Isibaar 262
230 : edgomez 1382 movq mm7, [rounding1_mmx + eax * 8]
231 : Isibaar 262
232 : edgomez 1382 mov edi, [esp + 8 + 4] ; dst
233 :     mov esi, [esp + 8 + 8] ; src
234 :     mov edx, [esp + 8 + 12] ; stride
235 : Isibaar 262
236 : edgomez 1382 pxor mm6, mm6 ; zero
237 : Isibaar 262
238 :    
239 : edgomez 1382 COPY_V_MMX
240 :     COPY_V_MMX
241 :     COPY_V_MMX
242 :     COPY_V_MMX
243 :     COPY_V_MMX
244 :     COPY_V_MMX
245 :     COPY_V_MMX
246 :     COPY_V_MMX
247 : Isibaar 262
248 : edgomez 1382 pop edi
249 :     pop esi
250 : Isibaar 262
251 : edgomez 1382 ret
252 : edgomez 1540 .endfunc
253 : Isibaar 262
254 : edgomez 1382
255 :     ;-----------------------------------------------------------------------------
256 : Isibaar 262 ;
257 :     ; void interpolate8x8_halfpel_hv_mmx(uint8_t * const dst,
258 : edgomez 1382 ; const uint8_t * const src,
259 :     ; const uint32_t stride,
260 :     ; const uint32_t rounding);
261 : Isibaar 262 ;
262 :     ;
263 : edgomez 1382 ;-----------------------------------------------------------------------------
264 : Isibaar 262
265 :     %macro COPY_HV_MMX 0
266 : edgomez 1382 ; current row
267 :     movq mm0, [esi]
268 :     movq mm2, [esi + 1]
269 : Isibaar 262
270 : edgomez 1382 movq mm1, mm0
271 :     movq mm3, mm2
272 : Isibaar 262
273 : edgomez 1382 punpcklbw mm0, mm6 ; mm01 = [src]
274 :     punpcklbw mm2, mm6 ; mm23 = [src + 1]
275 :     punpckhbw mm1, mm6
276 :     punpckhbw mm3, mm6
277 : Isibaar 262
278 : edgomez 1382 paddusw mm0, mm2 ; mm01 += mm23
279 :     paddusw mm1, mm3
280 : Isibaar 262
281 : edgomez 1382 ; next row
282 :     movq mm4, [esi + edx]
283 :     movq mm2, [esi + edx + 1]
284 : Isibaar 262
285 : edgomez 1382 movq mm5, mm4
286 :     movq mm3, mm2
287 : Isibaar 262
288 : edgomez 1382 punpcklbw mm4, mm6 ; mm45 = [src + stride]
289 :     punpcklbw mm2, mm6 ; mm23 = [src + stride + 1]
290 :     punpckhbw mm5, mm6
291 :     punpckhbw mm3, mm6
292 : Isibaar 262
293 : edgomez 1382 paddusw mm4, mm2 ; mm45 += mm23
294 :     paddusw mm5, mm3
295 : Isibaar 262
296 : edgomez 1382 ; add current + next row
297 :     paddusw mm0, mm4 ; mm01 += mm45
298 :     paddusw mm1, mm5
299 :     paddusw mm0, mm7 ; mm01 += rounding2
300 :     paddusw mm1, mm7
301 : Isibaar 262
302 : edgomez 1382 psrlw mm0, 2 ; mm01 >>= 2
303 :     psrlw mm1, 2
304 : Isibaar 262
305 : edgomez 1382 packuswb mm0, mm1
306 :     movq [edi], mm0 ; [dst] = mm01
307 : Isibaar 262
308 : edgomez 1382 add esi, edx ; src += stride
309 :     add edi, edx ; dst += stride
310 : Isibaar 262 %endmacro
311 :    
312 : edgomez 1382 ALIGN 16
313 :     interpolate8x8_halfpel_hv_mmx:
314 : Isibaar 262
315 : edgomez 1382 push esi
316 :     push edi
317 : Isibaar 262
318 : edgomez 1382 mov eax, [esp + 8 + 16] ; rounding
319 : Isibaar 262
320 : edgomez 1382 movq mm7, [rounding2_mmx + eax * 8]
321 : Isibaar 262
322 : edgomez 1382 mov edi, [esp + 8 + 4] ; dst
323 :     mov esi, [esp + 8 + 8] ; src
324 : Isibaar 262
325 : edgomez 1382 mov eax, 8
326 : Isibaar 262
327 : edgomez 1382 pxor mm6, mm6 ; zero
328 : Isibaar 262
329 : edgomez 1382 mov edx, [esp + 8 + 12] ; stride
330 : Isibaar 262
331 : edgomez 1382 COPY_HV_MMX
332 :     COPY_HV_MMX
333 :     COPY_HV_MMX
334 :     COPY_HV_MMX
335 :     COPY_HV_MMX
336 :     COPY_HV_MMX
337 :     COPY_HV_MMX
338 :     COPY_HV_MMX
339 : edgomez 851
340 : edgomez 1382 pop edi
341 :     pop esi
342 :    
343 :     ret
344 : edgomez 1540 .endfunc
345 : edgomez 1382
346 :     ;-----------------------------------------------------------------------------
347 : edgomez 851 ;
348 : suxen_drol 1632 ; void interpolate8x4_halfpel_h_mmx(uint8_t * const dst,
349 :     ; const uint8_t * const src,
350 :     ; const uint32_t stride,
351 :     ; const uint32_t rounding);
352 :     ;
353 :     ;-----------------------------------------------------------------------------
354 :    
355 :     ALIGN 16
356 :     interpolate8x4_halfpel_h_mmx:
357 :    
358 :     push esi
359 :     push edi
360 :     mov eax, [esp + 8 + 16] ; rounding
361 :    
362 :     movq mm7, [rounding1_mmx + eax * 8]
363 :    
364 :     mov edi, [esp + 8 + 4] ; dst
365 :     mov esi, [esp + 8 + 8] ; src
366 :     mov edx, [esp + 8 + 12] ; stride
367 :    
368 :     pxor mm6, mm6 ; zero
369 :    
370 :     COPY_H_MMX
371 :     COPY_H_MMX
372 :     COPY_H_MMX
373 :     COPY_H_MMX
374 :    
375 :     pop edi
376 :     pop esi
377 :    
378 :     ret
379 :     .endfunc
380 :    
381 :    
382 :     ;-----------------------------------------------------------------------------
383 :     ;
384 :     ; void interpolate8x4_halfpel_v_mmx(uint8_t * const dst,
385 :     ; const uint8_t * const src,
386 :     ; const uint32_t stride,
387 :     ; const uint32_t rounding);
388 :     ;
389 :     ;-----------------------------------------------------------------------------
390 :    
391 :     ALIGN 16
392 :     interpolate8x4_halfpel_v_mmx:
393 :    
394 :     push esi
395 :     push edi
396 :    
397 :     mov eax, [esp + 8 + 16] ; rounding
398 :    
399 :     movq mm7, [rounding1_mmx + eax * 8]
400 :    
401 :     mov edi, [esp + 8 + 4] ; dst
402 :     mov esi, [esp + 8 + 8] ; src
403 :     mov edx, [esp + 8 + 12] ; stride
404 :    
405 :     pxor mm6, mm6 ; zero
406 :    
407 :    
408 :     COPY_V_MMX
409 :     COPY_V_MMX
410 :     COPY_V_MMX
411 :     COPY_V_MMX
412 :    
413 :     pop edi
414 :     pop esi
415 :    
416 :     ret
417 :     .endfunc
418 :    
419 :    
420 :     ;-----------------------------------------------------------------------------
421 :     ;
422 :     ; void interpolate8x4_halfpel_hv_mmx(uint8_t * const dst,
423 :     ; const uint8_t * const src,
424 :     ; const uint32_t stride,
425 :     ; const uint32_t rounding);
426 :     ;
427 :     ;
428 :     ;-----------------------------------------------------------------------------
429 :    
430 :     ALIGN 16
431 :     interpolate8x4_halfpel_hv_mmx:
432 :    
433 :     push esi
434 :     push edi
435 :    
436 :     mov eax, [esp + 8 + 16] ; rounding
437 :    
438 :     movq mm7, [rounding2_mmx + eax * 8]
439 :    
440 :     mov edi, [esp + 8 + 4] ; dst
441 :     mov esi, [esp + 8 + 8] ; src
442 :    
443 :     mov eax, 8
444 :    
445 :     pxor mm6, mm6 ; zero
446 :    
447 :     mov edx, [esp + 8 + 12] ; stride
448 :    
449 :     COPY_HV_MMX
450 :     COPY_HV_MMX
451 :     COPY_HV_MMX
452 :     COPY_HV_MMX
453 :    
454 :     pop edi
455 :     pop esi
456 :    
457 :     ret
458 :     .endfunc
459 :    
460 :     ;-----------------------------------------------------------------------------
461 :     ;
462 : edgomez 851 ; void interpolate8x8_avg2_mmx(uint8_t const *dst,
463 : edgomez 1382 ; const uint8_t * const src1,
464 :     ; const uint8_t * const src2,
465 :     ; const uint32_t stride,
466 :     ; const uint32_t rounding,
467 :     ; const uint32_t height);
468 : edgomez 851 ;
469 : edgomez 1382 ;-----------------------------------------------------------------------------
470 : edgomez 851
471 :     %macro AVG2_MMX_RND0 0
472 : edgomez 1382 movq mm0, [eax] ; src1 -> mm0
473 :     movq mm1, [ebx] ; src2 -> mm1
474 : edgomez 851
475 : edgomez 1382 movq mm4, [eax+edx]
476 :     movq mm5, [ebx+edx]
477 : edgomez 851
478 : edgomez 1382 movq mm2, mm0 ; src1 -> mm2
479 :     movq mm3, mm1 ; src2 -> mm3
480 : edgomez 851
481 : edgomez 1382 pand mm2, mm7 ; isolate the lsb
482 :     pand mm3, mm7 ; isolate the lsb
483 : edgomez 851
484 : edgomez 1382 por mm2, mm3 ; ODD(src1) OR ODD(src2) -> mm2
485 : edgomez 851
486 : edgomez 1382 movq mm3, mm4
487 :     movq mm6, mm5
488 : edgomez 851
489 : edgomez 1382 pand mm3, mm7
490 :     pand mm6, mm7
491 : edgomez 851
492 : edgomez 1382 por mm3, mm6
493 : edgomez 851
494 : edgomez 1382 pand mm0, [mmx_mask]
495 :     pand mm1, [mmx_mask]
496 :     pand mm4, [mmx_mask]
497 :     pand mm5, [mmx_mask]
498 : edgomez 851
499 : edgomez 1382 psrlq mm0, 1 ; src1 / 2
500 :     psrlq mm1, 1 ; src2 / 2
501 : edgomez 851
502 : edgomez 1382 psrlq mm4, 1
503 :     psrlq mm5, 1
504 : edgomez 851
505 : edgomez 1382 paddb mm0, mm1 ; src1/2 + src2/2 -> mm0
506 :     paddb mm0, mm2 ; correct rounding error
507 : edgomez 851
508 : edgomez 1382 paddb mm4, mm5
509 :     paddb mm4, mm3
510 : edgomez 851
511 : edgomez 1382 lea eax, [eax+2*edx]
512 :     lea ebx, [ebx+2*edx]
513 :    
514 :     movq [ecx], mm0 ; (src1 + src2 + 1) / 2 -> dst
515 :     movq [ecx+edx], mm4
516 : edgomez 851 %endmacro
517 :    
518 :     %macro AVG2_MMX_RND1 0
519 : edgomez 1382 movq mm0, [eax] ; src1 -> mm0
520 :     movq mm1, [ebx] ; src2 -> mm1
521 : edgomez 851
522 : edgomez 1382 movq mm4, [eax+edx]
523 :     movq mm5, [ebx+edx]
524 : edgomez 851
525 : edgomez 1382 movq mm2, mm0 ; src1 -> mm2
526 :     movq mm3, mm1 ; src2 -> mm3
527 : edgomez 851
528 : edgomez 1382 pand mm2, mm7 ; isolate the lsb
529 :     pand mm3, mm7 ; isolate the lsb
530 : edgomez 851
531 : edgomez 1382 pand mm2, mm3 ; ODD(src1) AND ODD(src2) -> mm2
532 : edgomez 851
533 : edgomez 1382 movq mm3, mm4
534 :     movq mm6, mm5
535 : edgomez 851
536 : edgomez 1382 pand mm3, mm7
537 :     pand mm6, mm7
538 : edgomez 851
539 : edgomez 1382 pand mm3, mm6
540 : edgomez 851
541 : edgomez 1382 pand mm0, [mmx_mask]
542 :     pand mm1, [mmx_mask]
543 :     pand mm4, [mmx_mask]
544 :     pand mm5, [mmx_mask]
545 : edgomez 851
546 : edgomez 1382 psrlq mm0, 1 ; src1 / 2
547 :     psrlq mm1, 1 ; src2 / 2
548 : edgomez 851
549 : edgomez 1382 psrlq mm4, 1
550 :     psrlq mm5, 1
551 : edgomez 851
552 : edgomez 1382 paddb mm0, mm1 ; src1/2 + src2/2 -> mm0
553 :     paddb mm0, mm2 ; correct rounding error
554 : edgomez 851
555 : edgomez 1382 paddb mm4, mm5
556 :     paddb mm4, mm3
557 :    
558 :     lea eax, [eax+2*edx]
559 :     lea ebx, [ebx+2*edx]
560 :    
561 :     movq [ecx], mm0 ; (src1 + src2 + 1) / 2 -> dst
562 :     movq [ecx+edx], mm4
563 : edgomez 851 %endmacro
564 :    
565 : edgomez 1382 ALIGN 16
566 :     interpolate8x8_avg2_mmx:
567 : edgomez 851
568 : edgomez 1382 push ebx
569 : edgomez 851
570 : edgomez 1382 mov eax, [esp + 4 + 20] ; rounding
571 :     test eax, eax
572 : edgomez 851
573 : edgomez 1382 jnz near .rounding1
574 : edgomez 851
575 : edgomez 1382 mov eax, [esp + 4 + 24] ; height -> eax
576 :     sub eax, 8
577 :     test eax, eax
578 : edgomez 851
579 : edgomez 1382 mov ecx, [esp + 4 + 4] ; dst -> edi
580 :     mov eax, [esp + 4 + 8] ; src1 -> esi
581 :     mov ebx, [esp + 4 + 12] ; src2 -> eax
582 :     mov edx, [esp + 4 + 16] ; stride -> edx
583 : edgomez 851
584 : edgomez 1382 movq mm7, [mmx_one]
585 : edgomez 851
586 : edgomez 1382 jz near .start0
587 : edgomez 851
588 : edgomez 1382 AVG2_MMX_RND0
589 :     lea ecx, [ecx+2*edx]
590 :    
591 : edgomez 851 .start0
592 :    
593 : edgomez 1382 AVG2_MMX_RND0
594 :     lea ecx, [ecx+2*edx]
595 :     AVG2_MMX_RND0
596 :     lea ecx, [ecx+2*edx]
597 :     AVG2_MMX_RND0
598 :     lea ecx, [ecx+2*edx]
599 :     AVG2_MMX_RND0
600 : edgomez 851
601 : edgomez 1382 pop ebx
602 :     ret
603 :    
604 : edgomez 851 .rounding1
605 : edgomez 1382 mov eax, [esp + 4 + 24] ; height -> eax
606 :     sub eax, 8
607 :     test eax, eax
608 : edgomez 851
609 : edgomez 1382 mov ecx, [esp + 4 + 4] ; dst -> edi
610 :     mov eax, [esp + 4 + 8] ; src1 -> esi
611 :     mov ebx, [esp + 4 + 12] ; src2 -> eax
612 :     mov edx, [esp + 4 + 16] ; stride -> edx
613 : edgomez 851
614 : edgomez 1382 movq mm7, [mmx_one]
615 : edgomez 851
616 : edgomez 1382 jz near .start1
617 : edgomez 851
618 : edgomez 1382 AVG2_MMX_RND1
619 :     lea ecx, [ecx+2*edx]
620 : edgomez 851
621 :     .start1
622 :    
623 : edgomez 1382 AVG2_MMX_RND1
624 :     lea ecx, [ecx+2*edx]
625 :     AVG2_MMX_RND1
626 :     lea ecx, [ecx+2*edx]
627 :     AVG2_MMX_RND1
628 :     lea ecx, [ecx+2*edx]
629 :     AVG2_MMX_RND1
630 : edgomez 851
631 : edgomez 1382 pop ebx
632 :     ret
633 : edgomez 1540 .endfunc
634 : edgomez 851
635 :    
636 : edgomez 1382 ;-----------------------------------------------------------------------------
637 : edgomez 851 ;
638 :     ; void interpolate8x8_avg4_mmx(uint8_t const *dst,
639 : edgomez 1382 ; const uint8_t * const src1,
640 :     ; const uint8_t * const src2,
641 :     ; const uint8_t * const src3,
642 :     ; const uint8_t * const src4,
643 :     ; const uint32_t stride,
644 :     ; const uint32_t rounding);
645 : edgomez 851 ;
646 : edgomez 1382 ;-----------------------------------------------------------------------------
647 : edgomez 851
648 :     %macro AVG4_MMX_RND0 0
649 : edgomez 1382 movq mm0, [eax] ; src1 -> mm0
650 :     movq mm1, [ebx] ; src2 -> mm1
651 : edgomez 851
652 : edgomez 1382 movq mm2, mm0
653 :     movq mm3, mm1
654 : edgomez 851
655 : edgomez 1382 pand mm2, [mmx_three]
656 :     pand mm3, [mmx_three]
657 : edgomez 851
658 : edgomez 1382 pand mm0, [mmx_mask2]
659 :     pand mm1, [mmx_mask2]
660 : edgomez 851
661 : edgomez 1382 psrlq mm0, 2
662 :     psrlq mm1, 2
663 : edgomez 851
664 : edgomez 1382 lea eax, [eax+edx]
665 :     lea ebx, [ebx+edx]
666 : edgomez 851
667 : edgomez 1382 paddb mm0, mm1
668 :     paddb mm2, mm3
669 : edgomez 851
670 : edgomez 1382 movq mm4, [esi] ; src3 -> mm0
671 :     movq mm5, [edi] ; src4 -> mm1
672 : edgomez 851
673 : edgomez 1382 movq mm1, mm4
674 :     movq mm3, mm5
675 : edgomez 851
676 : edgomez 1382 pand mm1, [mmx_three]
677 :     pand mm3, [mmx_three]
678 : edgomez 851
679 : edgomez 1382 pand mm4, [mmx_mask2]
680 :     pand mm5, [mmx_mask2]
681 : edgomez 851
682 : edgomez 1382 psrlq mm4, 2
683 :     psrlq mm5, 2
684 : edgomez 851
685 : edgomez 1382 paddb mm4, mm5
686 :     paddb mm0, mm4
687 : edgomez 851
688 : edgomez 1382 paddb mm1, mm3
689 :     paddb mm2, mm1
690 :    
691 :     paddb mm2, [mmx_two]
692 :     pand mm2, [mmx_mask2]
693 :    
694 :     psrlq mm2, 2
695 :     paddb mm0, mm2
696 :    
697 :     lea esi, [esi+edx]
698 :     lea edi, [edi+edx]
699 :    
700 :     movq [ecx], mm0 ; (src1 + src2 + src3 + src4 + 2) / 4 -> dst
701 : edgomez 851 %endmacro
702 :    
703 :     %macro AVG4_MMX_RND1 0
704 : edgomez 1382 movq mm0, [eax] ; src1 -> mm0
705 :     movq mm1, [ebx] ; src2 -> mm1
706 : edgomez 851
707 : edgomez 1382 movq mm2, mm0
708 :     movq mm3, mm1
709 : edgomez 851
710 : edgomez 1382 pand mm2, [mmx_three]
711 :     pand mm3, [mmx_three]
712 : edgomez 851
713 : edgomez 1382 pand mm0, [mmx_mask2]
714 :     pand mm1, [mmx_mask2]
715 : edgomez 851
716 : edgomez 1382 psrlq mm0, 2
717 :     psrlq mm1, 2
718 : edgomez 851
719 : edgomez 1382 lea eax,[eax+edx]
720 :     lea ebx,[ebx+edx]
721 : edgomez 851
722 : edgomez 1382 paddb mm0, mm1
723 :     paddb mm2, mm3
724 : edgomez 851
725 : edgomez 1382 movq mm4, [esi] ; src3 -> mm0
726 :     movq mm5, [edi] ; src4 -> mm1
727 : edgomez 851
728 : edgomez 1382 movq mm1, mm4
729 :     movq mm3, mm5
730 : edgomez 851
731 : edgomez 1382 pand mm1, [mmx_three]
732 :     pand mm3, [mmx_three]
733 : edgomez 851
734 : edgomez 1382 pand mm4, [mmx_mask2]
735 :     pand mm5, [mmx_mask2]
736 : edgomez 851
737 : edgomez 1382 psrlq mm4, 2
738 :     psrlq mm5, 2
739 : edgomez 851
740 : edgomez 1382 paddb mm4, mm5
741 :     paddb mm0, mm4
742 : edgomez 851
743 : edgomez 1382 paddb mm1, mm3
744 :     paddb mm2, mm1
745 :    
746 :     paddb mm2, [mmx_one]
747 :     pand mm2, [mmx_mask2]
748 :    
749 :     psrlq mm2, 2
750 :     paddb mm0, mm2
751 :    
752 :     lea esi,[esi+edx]
753 :     lea edi,[edi+edx]
754 :    
755 :     movq [ecx], mm0 ; (src1 + src2 + src3 + src4 + 2) / 4 -> dst
756 : edgomez 851 %endmacro
757 :    
758 : edgomez 1382 ALIGN 16
759 :     interpolate8x8_avg4_mmx:
760 : edgomez 851
761 : edgomez 1382 push ebx
762 :     push edi
763 :     push esi
764 : edgomez 851
765 : edgomez 1382 mov eax, [esp + 12 + 28] ; rounding
766 : edgomez 851
767 : edgomez 1382 test eax, eax
768 : edgomez 851
769 : edgomez 1382 mov ecx, [esp + 12 + 4] ; dst -> edi
770 :     mov eax, [esp + 12 + 8] ; src1 -> esi
771 :     mov ebx, [esp + 12 + 12] ; src2 -> eax
772 :     mov esi, [esp + 12 + 16] ; src3 -> esi
773 :     mov edi, [esp + 12 + 20] ; src4 -> edi
774 :     mov edx, [esp + 12 + 24] ; stride -> edx
775 : edgomez 851
776 : edgomez 1382 movq mm7, [mmx_one]
777 : edgomez 851
778 : edgomez 1382 jnz near .rounding1
779 : edgomez 851
780 : edgomez 1382 AVG4_MMX_RND0
781 :     lea ecx, [ecx+edx]
782 :     AVG4_MMX_RND0
783 :     lea ecx, [ecx+edx]
784 :     AVG4_MMX_RND0
785 :     lea ecx, [ecx+edx]
786 :     AVG4_MMX_RND0
787 :     lea ecx, [ecx+edx]
788 :     AVG4_MMX_RND0
789 :     lea ecx, [ecx+edx]
790 :     AVG4_MMX_RND0
791 :     lea ecx, [ecx+edx]
792 :     AVG4_MMX_RND0
793 :     lea ecx, [ecx+edx]
794 :     AVG4_MMX_RND0
795 :    
796 :     pop esi
797 :     pop edi
798 :     pop ebx
799 :     ret
800 :    
801 : edgomez 851 .rounding1
802 : edgomez 1382 AVG4_MMX_RND1
803 :     lea ecx, [ecx+edx]
804 :     AVG4_MMX_RND1
805 :     lea ecx, [ecx+edx]
806 :     AVG4_MMX_RND1
807 :     lea ecx, [ecx+edx]
808 :     AVG4_MMX_RND1
809 :     lea ecx, [ecx+edx]
810 :     AVG4_MMX_RND1
811 :     lea ecx, [ecx+edx]
812 :     AVG4_MMX_RND1
813 :     lea ecx, [ecx+edx]
814 :     AVG4_MMX_RND1
815 :     lea ecx, [ecx+edx]
816 :     AVG4_MMX_RND1
817 : edgomez 851
818 : edgomez 1382 pop esi
819 :     pop edi
820 :     pop ebx
821 :     ret
822 : edgomez 1540 .endfunc
823 : edgomez 851
824 :    
825 : edgomez 1382 ;-----------------------------------------------------------------------------
826 : edgomez 851 ;
827 :     ; void interpolate8x8_6tap_lowpass_h_mmx(uint8_t const *dst,
828 : edgomez 1382 ; const uint8_t * const src,
829 :     ; const uint32_t stride,
830 :     ; const uint32_t rounding);
831 : edgomez 851 ;
832 : edgomez 1382 ;-----------------------------------------------------------------------------
833 : edgomez 851
834 :     %macro LOWPASS_6TAP_H_MMX 0
835 : edgomez 1382 movq mm0, [eax]
836 :     movq mm2, [eax+1]
837 : edgomez 851
838 : edgomez 1382 movq mm1, mm0
839 :     movq mm3, mm2
840 : edgomez 851
841 : edgomez 1382 punpcklbw mm0, mm7
842 :     punpcklbw mm2, mm7
843 : edgomez 851
844 : edgomez 1382 punpckhbw mm1, mm7
845 :     punpckhbw mm3, mm7
846 : edgomez 851
847 : edgomez 1382 paddw mm0, mm2
848 :     paddw mm1, mm3
849 : edgomez 851
850 : edgomez 1382 psllw mm0, 2
851 :     psllw mm1, 2
852 : edgomez 851
853 : edgomez 1382 movq mm2, [eax-1]
854 :     movq mm4, [eax+2]
855 : edgomez 851
856 : edgomez 1382 movq mm3, mm2
857 :     movq mm5, mm4
858 : edgomez 851
859 : edgomez 1382 punpcklbw mm2, mm7
860 :     punpcklbw mm4, mm7
861 : edgomez 851
862 : edgomez 1382 punpckhbw mm3, mm7
863 :     punpckhbw mm5, mm7
864 : edgomez 851
865 : edgomez 1382 paddw mm2, mm4
866 :     paddw mm3, mm5
867 : edgomez 851
868 : edgomez 1382 psubsw mm0, mm2
869 :     psubsw mm1, mm3
870 : edgomez 851
871 : edgomez 1382 pmullw mm0, [mmx_five]
872 :     pmullw mm1, [mmx_five]
873 : edgomez 851
874 : edgomez 1382 movq mm2, [eax-2]
875 :     movq mm4, [eax+3]
876 : edgomez 851
877 : edgomez 1382 movq mm3, mm2
878 :     movq mm5, mm4
879 : edgomez 851
880 : edgomez 1382 punpcklbw mm2, mm7
881 :     punpcklbw mm4, mm7
882 : edgomez 851
883 : edgomez 1382 punpckhbw mm3, mm7
884 :     punpckhbw mm5, mm7
885 : edgomez 851
886 : edgomez 1382 paddw mm2, mm4
887 :     paddw mm3, mm5
888 : edgomez 851
889 : edgomez 1382 paddsw mm0, mm2
890 :     paddsw mm1, mm3
891 : edgomez 851
892 : edgomez 1382 paddsw mm0, mm6
893 :     paddsw mm1, mm6
894 : edgomez 851
895 : edgomez 1382 psraw mm0, 5
896 :     psraw mm1, 5
897 : edgomez 851
898 : edgomez 1382 lea eax, [eax+edx]
899 :     packuswb mm0, mm1
900 :     movq [ecx], mm0
901 : edgomez 851 %endmacro
902 :    
903 : edgomez 1382 ALIGN 16
904 :     interpolate8x8_6tap_lowpass_h_mmx:
905 : edgomez 851
906 : edgomez 1382 mov eax, [esp + 16] ; rounding
907 : edgomez 851
908 : edgomez 1382 movq mm6, [rounding_lowpass_mmx + eax * 8]
909 : edgomez 851
910 : edgomez 1382 mov ecx, [esp + 4] ; dst -> edi
911 :     mov eax, [esp + 8] ; src -> esi
912 :     mov edx, [esp + 12] ; stride -> edx
913 : edgomez 851
914 : edgomez 1382 pxor mm7, mm7
915 : edgomez 851
916 : edgomez 1382 LOWPASS_6TAP_H_MMX
917 :     lea ecx, [ecx+edx]
918 :     LOWPASS_6TAP_H_MMX
919 :     lea ecx, [ecx+edx]
920 :     LOWPASS_6TAP_H_MMX
921 :     lea ecx, [ecx+edx]
922 :     LOWPASS_6TAP_H_MMX
923 :     lea ecx, [ecx+edx]
924 :     LOWPASS_6TAP_H_MMX
925 :     lea ecx, [ecx+edx]
926 :     LOWPASS_6TAP_H_MMX
927 :     lea ecx, [ecx+edx]
928 :     LOWPASS_6TAP_H_MMX
929 :     lea ecx, [ecx+edx]
930 :     LOWPASS_6TAP_H_MMX
931 : edgomez 851
932 : edgomez 1382 ret
933 : edgomez 1540 .endfunc
934 : edgomez 1382
935 :     ;-----------------------------------------------------------------------------
936 : edgomez 851 ;
937 :     ; void interpolate8x8_6tap_lowpass_v_mmx(uint8_t const *dst,
938 : edgomez 1382 ; const uint8_t * const src,
939 :     ; const uint32_t stride,
940 :     ; const uint32_t rounding);
941 : edgomez 851 ;
942 : edgomez 1382 ;-----------------------------------------------------------------------------
943 : edgomez 851
944 :     %macro LOWPASS_6TAP_V_MMX 0
945 : edgomez 1382 movq mm0, [eax]
946 :     movq mm2, [eax+edx]
947 : edgomez 851
948 : edgomez 1382 movq mm1, mm0
949 :     movq mm3, mm2
950 : edgomez 851
951 : edgomez 1382 punpcklbw mm0, mm7
952 :     punpcklbw mm2, mm7
953 : edgomez 851
954 : edgomez 1382 punpckhbw mm1, mm7
955 :     punpckhbw mm3, mm7
956 : edgomez 851
957 : edgomez 1382 paddw mm0, mm2
958 :     paddw mm1, mm3
959 : edgomez 851
960 : edgomez 1382 psllw mm0, 2
961 :     psllw mm1, 2
962 : edgomez 851
963 : edgomez 1382 movq mm4, [eax+2*edx]
964 :     sub eax, ebx
965 :     movq mm2, [eax+2*edx]
966 : edgomez 851
967 : edgomez 1382 movq mm3, mm2
968 :     movq mm5, mm4
969 : edgomez 851
970 : edgomez 1382 punpcklbw mm2, mm7
971 :     punpcklbw mm4, mm7
972 : edgomez 851
973 : edgomez 1382 punpckhbw mm3, mm7
974 :     punpckhbw mm5, mm7
975 : edgomez 851
976 : edgomez 1382 paddw mm2, mm4
977 :     paddw mm3, mm5
978 : edgomez 851
979 : edgomez 1382 psubsw mm0, mm2
980 :     psubsw mm1, mm3
981 : edgomez 851
982 : edgomez 1382 pmullw mm0, [mmx_five]
983 :     pmullw mm1, [mmx_five]
984 : edgomez 851
985 : edgomez 1382 movq mm2, [eax+edx]
986 :     movq mm4, [eax+2*ebx]
987 : edgomez 851
988 : edgomez 1382 movq mm3, mm2
989 :     movq mm5, mm4
990 : edgomez 851
991 : edgomez 1382 punpcklbw mm2, mm7
992 :     punpcklbw mm4, mm7
993 : edgomez 851
994 : edgomez 1382 punpckhbw mm3, mm7
995 :     punpckhbw mm5, mm7
996 : edgomez 851
997 : edgomez 1382 paddw mm2, mm4
998 :     paddw mm3, mm5
999 : edgomez 851
1000 : edgomez 1382 paddsw mm0, mm2
1001 :     paddsw mm1, mm3
1002 : edgomez 851
1003 : edgomez 1382 paddsw mm0, mm6
1004 :     paddsw mm1, mm6
1005 : edgomez 851
1006 : edgomez 1382 psraw mm0, 5
1007 :     psraw mm1, 5
1008 : edgomez 851
1009 : edgomez 1382 lea eax, [eax+4*edx]
1010 :     packuswb mm0, mm1
1011 :     movq [ecx], mm0
1012 : edgomez 851 %endmacro
1013 :    
1014 : edgomez 1382 ALIGN 16
1015 :     interpolate8x8_6tap_lowpass_v_mmx:
1016 : edgomez 851
1017 : edgomez 1382 push ebx
1018 : edgomez 851
1019 : edgomez 1382 mov eax, [esp + 4 + 16] ; rounding
1020 : edgomez 851
1021 : edgomez 1382 movq mm6, [rounding_lowpass_mmx + eax * 8]
1022 : edgomez 851
1023 : edgomez 1382 mov ecx, [esp + 4 + 4] ; dst -> edi
1024 :     mov eax, [esp + 4 + 8] ; src -> esi
1025 :     mov edx, [esp + 4 + 12] ; stride -> edx
1026 : edgomez 851
1027 : edgomez 1382 mov ebx, edx
1028 :     shl ebx, 1
1029 :     add ebx, edx
1030 : edgomez 851
1031 : edgomez 1382 pxor mm7, mm7
1032 : edgomez 851
1033 : edgomez 1382 LOWPASS_6TAP_V_MMX
1034 :     lea ecx, [ecx+edx]
1035 :     LOWPASS_6TAP_V_MMX
1036 :     lea ecx, [ecx+edx]
1037 :     LOWPASS_6TAP_V_MMX
1038 :     lea ecx, [ecx+edx]
1039 :     LOWPASS_6TAP_V_MMX
1040 :     lea ecx, [ecx+edx]
1041 :     LOWPASS_6TAP_V_MMX
1042 :     lea ecx, [ecx+edx]
1043 :     LOWPASS_6TAP_V_MMX
1044 :     lea ecx, [ecx+edx]
1045 :     LOWPASS_6TAP_V_MMX
1046 :     lea ecx, [ecx+edx]
1047 :     LOWPASS_6TAP_V_MMX
1048 : edgomez 851
1049 : edgomez 1382 pop ebx
1050 :     ret
1051 : edgomez 1540 .endfunc
1052 : edgomez 1530
1053 :     ;===========================================================================
1054 :     ;
1055 :     ; The next functions combine both source halfpel interpolation step and the
1056 :     ; averaging (with rouding) step to avoid wasting memory bandwidth computing
1057 :     ; intermediate halfpel images and then averaging them.
1058 :     ;
1059 :     ;===========================================================================
1060 :    
1061 :     %macro PROLOG0 0
1062 :     mov ecx, [esp+ 4] ; Dst
1063 :     mov eax, [esp+ 8] ; Src
1064 :     mov edx, [esp+12] ; BpS
1065 :     %endmacro
1066 :    
1067 :     %macro PROLOG 2 ; %1: Rounder, %2 load Dst-Rounder
1068 :     pxor mm6, mm6
1069 :     movq mm7, [%1] ; TODO: dangerous! (eax isn't checked)
1070 :     %if %2
1071 :     movq mm5, [rounding1_mmx]
1072 :     %endif
1073 :    
1074 :     PROLOG0
1075 :     %endmacro
1076 :    
1077 :     ; performs: mm0 == (mm0+mm2) mm1 == (mm1+mm3)
1078 :     %macro MIX 0
1079 :     punpcklbw mm0, mm6
1080 :     punpcklbw mm2, mm6
1081 :     punpckhbw mm1, mm6
1082 :     punpckhbw mm3, mm6
1083 :     paddusw mm0, mm2
1084 :     paddusw mm1, mm3
1085 :     %endmacro
1086 :    
1087 :     %macro MIX_DST 0
1088 :     movq mm3, mm2
1089 :     paddusw mm0, mm7 ; rounder
1090 :     paddusw mm1, mm7 ; rounder
1091 :     punpcklbw mm2, mm6
1092 :     punpckhbw mm3, mm6
1093 :     psrlw mm0, 1
1094 :     psrlw mm1, 1
1095 :    
1096 :     paddusw mm0, mm2 ; mix Src(mm0/mm1) with Dst(mm2/mm3)
1097 :     paddusw mm1, mm3
1098 :     paddusw mm0, mm5
1099 :     paddusw mm1, mm5
1100 :     psrlw mm0, 1
1101 :     psrlw mm1, 1
1102 :    
1103 :     packuswb mm0, mm1
1104 :     %endmacro
1105 :    
1106 :     %macro MIX2 0
1107 :     punpcklbw mm0, mm6
1108 :     punpcklbw mm2, mm6
1109 :     paddusw mm0, mm2
1110 :     paddusw mm0, mm7
1111 :     punpckhbw mm1, mm6
1112 :     punpckhbw mm3, mm6
1113 :     paddusw mm1, mm7
1114 :     paddusw mm1, mm3
1115 :     psrlw mm0, 1
1116 :     psrlw mm1, 1
1117 :    
1118 :     packuswb mm0, mm1
1119 :     %endmacro
1120 :    
1121 :     ;===========================================================================
1122 :     ;
1123 :     ; void interpolate8x8_halfpel_add_mmx(uint8_t * const dst,
1124 :     ; const uint8_t * const src,
1125 :     ; const uint32_t stride,
1126 :     ; const uint32_t rounding);
1127 :     ;
1128 :     ;
1129 :     ;===========================================================================
1130 :    
1131 :     %macro ADD_FF_MMX 1
1132 :     movq mm0, [eax]
1133 :     movq mm2, [ecx]
1134 :     movq mm1, mm0
1135 :     movq mm3, mm2
1136 :     %if (%1!=0)
1137 :     lea eax,[eax+%1*edx]
1138 :     %endif
1139 :     MIX
1140 :     paddusw mm0, mm5 ; rounder
1141 :     paddusw mm1, mm5 ; rounder
1142 :     psrlw mm0, 1
1143 :     psrlw mm1, 1
1144 :    
1145 :     packuswb mm0, mm1
1146 :     movq [ecx], mm0
1147 :     %if (%1!=0)
1148 :     lea ecx,[ecx+%1*edx]
1149 :     %endif
1150 :     %endmacro
1151 :    
1152 :     ALIGN 16
1153 :     interpolate8x8_halfpel_add_mmx:
1154 :     PROLOG rounding1_mmx, 1
1155 :     ADD_FF_MMX 1
1156 :     ADD_FF_MMX 1
1157 :     ADD_FF_MMX 1
1158 :     ADD_FF_MMX 1
1159 :     ADD_FF_MMX 1
1160 :     ADD_FF_MMX 1
1161 :     ADD_FF_MMX 1
1162 :     ADD_FF_MMX 0
1163 :     ret
1164 : edgomez 1540 .endfunc
1165 : edgomez 1530
1166 :     ;===========================================================================
1167 :     ;
1168 :     ; void interpolate8x8_halfpel_h_add_mmx(uint8_t * const dst,
1169 :     ; const uint8_t * const src,
1170 :     ; const uint32_t stride,
1171 :     ; const uint32_t rounding);
1172 :     ;
1173 :     ;
1174 :     ;===========================================================================
1175 :    
1176 :     %macro ADD_FH_MMX 0
1177 :     movq mm0, [eax]
1178 :     movq mm2, [eax+1]
1179 :     movq mm1, mm0
1180 :     movq mm3, mm2
1181 :    
1182 :     lea eax,[eax+edx]
1183 :    
1184 :     MIX
1185 :     movq mm2, [ecx] ; prepare mix with Dst[0]
1186 :     MIX_DST
1187 :     movq [ecx], mm0
1188 :     %endmacro
1189 :    
1190 :     ALIGN 16
1191 :     interpolate8x8_halfpel_h_add_mmx:
1192 :     PROLOG rounding1_mmx, 1
1193 :    
1194 :     ADD_FH_MMX
1195 :     lea ecx,[ecx+edx]
1196 :     ADD_FH_MMX
1197 :     lea ecx,[ecx+edx]
1198 :     ADD_FH_MMX
1199 :     lea ecx,[ecx+edx]
1200 :     ADD_FH_MMX
1201 :     lea ecx,[ecx+edx]
1202 :     ADD_FH_MMX
1203 :     lea ecx,[ecx+edx]
1204 :     ADD_FH_MMX
1205 :     lea ecx,[ecx+edx]
1206 :     ADD_FH_MMX
1207 :     lea ecx,[ecx+edx]
1208 :     ADD_FH_MMX
1209 :     ret
1210 : edgomez 1540 .endfunc
1211 : edgomez 1530
1212 :     ;===========================================================================
1213 :     ;
1214 :     ; void interpolate8x8_halfpel_v_add_mmx(uint8_t * const dst,
1215 :     ; const uint8_t * const src,
1216 :     ; const uint32_t stride,
1217 :     ; const uint32_t rounding);
1218 :     ;
1219 :     ;
1220 :     ;===========================================================================
1221 :    
1222 :     %macro ADD_HF_MMX 0
1223 :     movq mm0, [eax]
1224 :     movq mm2, [eax+edx]
1225 :     movq mm1, mm0
1226 :     movq mm3, mm2
1227 :    
1228 :     lea eax,[eax+edx]
1229 :    
1230 :     MIX
1231 :     movq mm2, [ecx] ; prepare mix with Dst[0]
1232 :     MIX_DST
1233 :     movq [ecx], mm0
1234 :    
1235 :     %endmacro
1236 :    
1237 :     ALIGN 16
1238 :     interpolate8x8_halfpel_v_add_mmx:
1239 :     PROLOG rounding1_mmx, 1
1240 :    
1241 :     ADD_HF_MMX
1242 :     lea ecx,[ecx+edx]
1243 :     ADD_HF_MMX
1244 :     lea ecx,[ecx+edx]
1245 :     ADD_HF_MMX
1246 :     lea ecx,[ecx+edx]
1247 :     ADD_HF_MMX
1248 :     lea ecx,[ecx+edx]
1249 :     ADD_HF_MMX
1250 :     lea ecx,[ecx+edx]
1251 :     ADD_HF_MMX
1252 :     lea ecx,[ecx+edx]
1253 :     ADD_HF_MMX
1254 :     lea ecx,[ecx+edx]
1255 :     ADD_HF_MMX
1256 :     ret
1257 : edgomez 1540 .endfunc
1258 : edgomez 1530
1259 :     ; The trick is to correct the result of 'pavgb' with some combination of the
1260 :     ; lsb's of the 4 input values i,j,k,l, and their intermediate 'pavgb' (s and t).
1261 :     ; The boolean relations are:
1262 :     ; (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
1263 :     ; (i+j+k+l+2)/4 = (s+t+1)/2 - (ij|kl)&st
1264 :     ; (i+j+k+l+1)/4 = (s+t+1)/2 - (ij&kl)|st
1265 :     ; (i+j+k+l+0)/4 = (s+t+1)/2 - (ij|kl)|st
1266 :     ; with s=(i+j+1)/2, t=(k+l+1)/2, ij = i^j, kl = k^l, st = s^t.
1267 :    
1268 :     ; Moreover, we process 2 lines at a times, for better overlapping (~15% faster).
1269 :    
1270 :     ;===========================================================================
1271 :     ;
1272 :     ; void interpolate8x8_halfpel_hv_add_mmx(uint8_t * const dst,
1273 :     ; const uint8_t * const src,
1274 :     ; const uint32_t stride,
1275 :     ; const uint32_t rounding);
1276 :     ;
1277 :     ;
1278 :     ;===========================================================================
1279 :    
1280 :     %macro ADD_HH_MMX 0
1281 :     lea eax,[eax+edx]
1282 :    
1283 :     ; transfert prev line to mm0/mm1
1284 :     movq mm0, mm2
1285 :     movq mm1, mm3
1286 :    
1287 :     ; load new line in mm2/mm3
1288 :     movq mm2, [eax]
1289 :     movq mm4, [eax+1]
1290 :     movq mm3, mm2
1291 :     movq mm5, mm4
1292 :    
1293 :     punpcklbw mm2, mm6
1294 :     punpcklbw mm4, mm6
1295 :     paddusw mm2, mm4
1296 :     punpckhbw mm3, mm6
1297 :     punpckhbw mm5, mm6
1298 :     paddusw mm3, mm5
1299 :    
1300 :     ; mix current line (mm2/mm3) with previous (mm0,mm1);
1301 :     ; we'll preserve mm2/mm3 for next line...
1302 :    
1303 :     paddusw mm0, mm2
1304 :     paddusw mm1, mm3
1305 :    
1306 :     movq mm4, [ecx] ; prepare mix with Dst[0]
1307 :     movq mm5, mm4
1308 :    
1309 :     paddusw mm0, mm7 ; finish mixing current line
1310 :     paddusw mm1, mm7
1311 :    
1312 :     punpcklbw mm4, mm6
1313 :     punpckhbw mm5, mm6
1314 :    
1315 :     psrlw mm0, 2
1316 :     psrlw mm1, 2
1317 :    
1318 :     paddusw mm0, mm4 ; mix Src(mm0/mm1) with Dst(mm2/mm3)
1319 :     paddusw mm1, mm5
1320 :    
1321 :     paddusw mm0, [rounding1_mmx]
1322 :     paddusw mm1, [rounding1_mmx]
1323 :    
1324 :     psrlw mm0, 1
1325 :     psrlw mm1, 1
1326 :    
1327 :     packuswb mm0, mm1
1328 :    
1329 :     movq [ecx], mm0
1330 :     %endmacro
1331 :    
1332 :     ALIGN 16
1333 :     interpolate8x8_halfpel_hv_add_mmx:
1334 :     PROLOG rounding2_mmx, 0 ; mm5 is busy. Don't load dst-rounder
1335 :    
1336 :     ; preprocess first line
1337 :     movq mm0, [eax]
1338 :     movq mm2, [eax+1]
1339 :     movq mm1, mm0
1340 :     movq mm3, mm2
1341 :    
1342 :     punpcklbw mm0, mm6
1343 :     punpcklbw mm2, mm6
1344 :     punpckhbw mm1, mm6
1345 :     punpckhbw mm3, mm6
1346 :     paddusw mm2, mm0
1347 :     paddusw mm3, mm1
1348 :    
1349 :     ; Input: mm2/mm3 contains the value (Src[0]+Src[1]) of previous line
1350 :    
1351 :     ADD_HH_MMX
1352 :     lea ecx,[ecx+edx]
1353 :     ADD_HH_MMX
1354 :     lea ecx,[ecx+edx]
1355 :     ADD_HH_MMX
1356 :     lea ecx,[ecx+edx]
1357 :     ADD_HH_MMX
1358 :     lea ecx,[ecx+edx]
1359 :     ADD_HH_MMX
1360 :     lea ecx,[ecx+edx]
1361 :     ADD_HH_MMX
1362 :     lea ecx,[ecx+edx]
1363 :     ADD_HH_MMX
1364 :     lea ecx,[ecx+edx]
1365 :     ADD_HH_MMX
1366 :    
1367 :     ret
1368 : edgomez 1540 .endfunc
1369 : edgomez 1530

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