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

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