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

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