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

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