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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 851, Sat Feb 15 15:22:19 2003 UTC revision 1834, Mon Dec 1 15:00:44 2008 UTC
# Line 1  Line 1 
1  ;/**************************************************************************  ;/*****************************************************************************
2  ; *  ; *
3  ; *     XVID MPEG-4 VIDEO CODEC  ; *     XVID MPEG-4 VIDEO CODEC
4  ; *     mmx 8x8 block-based halfpel interpolation  ; *  - mmx 8x8 block-based halfpel interpolation -
5    ; *
6    ; *  Copyright(C) 2001 Peter Ross <pross@xvid.org>
7    ; *               2002-2008 Michael Militzer <michael@xvid.org>
8  ; *  ; *
9  ; *     This program is free software; you can redistribute it and/or modify  ; *     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  ; *     it under the terms of the GNU General Public License as published by
# Line 15  Line 18 
18  ; *  ; *
19  ; *     You should have received a copy of the GNU General Public License  ; *     You should have received a copy of the GNU General Public License
20  ; *     along with this program; if not, write to the Free Software  ; *     along with this program; if not, write to the Free Software
21  ; *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  ; *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 ; *  
 ; *************************************************************************/  
   
 ;/**************************************************************************  
 ; *  
 ; *     History:  
 ; *  
 ; * 05.10.2002  added some qpel mmx code - Isibaar  
 ; * 06.07.2002  mmx cleanup - Isibaar  
 ; *     22.12.2001      inital version; (c)2001 peter ross <pross@cs.rmit.edu.au>  
22  ; *  ; *
23  ; *************************************************************************/  ; ****************************************************************************/
24    
25    %include "nasm.inc"
26    
27  bits 32  ;=============================================================================
28    ; Read only data
29  %macro cglobal 1  ;=============================================================================
         %ifdef PREFIX  
                 global _%1  
                 %define %1 _%1  
         %else  
                 global %1  
         %endif  
 %endmacro  
   
 section .data  
30    
31  align 16  DATA
32    
33  ;===========================================================================  ;-----------------------------------------------------------------------------
34  ; (16 - r) rounding table  ; (16 - r) rounding table
35  ;===========================================================================  ;-----------------------------------------------------------------------------
36    
37  rounding_lowpass_mmx  ALIGN SECTION_ALIGN
38    rounding_lowpass_mmx:
39  times 4 dw 16  times 4 dw 16
40  times 4 dw 15  times 4 dw 15
41    
42  ;===========================================================================  ;-----------------------------------------------------------------------------
43  ; (1 - r) rounding table  ; (1 - r) rounding table
44  ;===========================================================================  ;-----------------------------------------------------------------------------
45    
46  rounding1_mmx  rounding1_mmx:
47  times 4 dw 1  times 4 dw 1
48  times 4 dw 0  times 4 dw 0
49    
50  ;===========================================================================  ;-----------------------------------------------------------------------------
51  ; (2 - r) rounding table  ; (2 - r) rounding table
52  ;===========================================================================  ;-----------------------------------------------------------------------------
53    
54  rounding2_mmx  rounding2_mmx:
55  times 4 dw 2  times 4 dw 2
56  times 4 dw 1  times 4 dw 1
57    
58  mmx_one  mmx_one:
59  times 8 db 1  times 8 db 1
60    
61  mmx_two  mmx_two:
62  times 8 db 2  times 8 db 2
63    
64  mmx_three  mmx_three:
65  times 8 db 3  times 8 db 3
66    
67  mmx_five  mmx_five:
68  times 4 dw 5  times 4 dw 5
69    
70  mmx_mask  mmx_mask:
71  times 8 db 254  times 8 db 254
72    
73  mmx_mask2  mmx_mask2:
74  times 8 db 252  times 8 db 252
75    
76  section .text  ;=============================================================================
77    ; Code
78    ;=============================================================================
79    
80    SECTION .rotext align=SECTION_ALIGN
81    
82    cglobal interpolate8x8_halfpel_h_mmx
83    cglobal interpolate8x8_halfpel_v_mmx
84    cglobal interpolate8x8_halfpel_hv_mmx
85    
86    cglobal interpolate8x4_halfpel_h_mmx
87    cglobal interpolate8x4_halfpel_v_mmx
88    cglobal interpolate8x4_halfpel_hv_mmx
89    
90    cglobal interpolate8x8_avg4_mmx
91    cglobal interpolate8x8_avg2_mmx
92    
93    cglobal interpolate8x8_6tap_lowpass_h_mmx
94    cglobal interpolate8x8_6tap_lowpass_v_mmx
95    
96    cglobal interpolate8x8_halfpel_add_mmx
97    cglobal interpolate8x8_halfpel_h_add_mmx
98    cglobal interpolate8x8_halfpel_v_add_mmx
99    cglobal interpolate8x8_halfpel_hv_add_mmx
100    
101  %macro  CALC_AVG 6  %macro  CALC_AVG 6
102          punpcklbw %3, %6          punpcklbw %3, %6
# Line 100  Line 109 
109    
110          psrlw %1, 1                     ; mm01 >>= 1          psrlw %1, 1                     ; mm01 >>= 1
111          psrlw %2, 1          psrlw %2, 1
   
112  %endmacro  %endmacro
113    
114    
115  ;===========================================================================  ;-----------------------------------------------------------------------------
116  ;  ;
117  ; void interpolate8x8_halfpel_h_mmx(uint8_t * const dst,  ; void interpolate8x8_halfpel_h_mmx(uint8_t * const dst,
118  ;                                               const uint8_t * const src,  ;                                               const uint8_t * const src,
119  ;                                               const uint32_t stride,  ;                                               const uint32_t stride,
120  ;                                               const uint32_t rounding);  ;                                               const uint32_t rounding);
121  ;  ;
122  ;===========================================================================  ;-----------------------------------------------------------------------------
123    
124  %macro COPY_H_MMX 0  %macro COPY_H_MMX 0
125                  movq mm0, [esi]    movq mm0, [TMP0]
126                  movq mm2, [esi + 1]    movq mm2, [TMP0 + 1]
127                  movq mm1, mm0                  movq mm1, mm0
128                  movq mm3, mm2                  movq mm3, mm2
129    
# Line 125  Line 133 
133                  CALC_AVG mm0, mm1, mm2, mm3, mm7, mm6                  CALC_AVG mm0, mm1, mm2, mm3, mm7, mm6
134    
135                  packuswb mm0, mm1                  packuswb mm0, mm1
136                  movq [edi], mm0                 ; [dst] = mm01    movq [_EAX], mm0           ; [dst] = mm01
137    
138                  add esi, edx            ; src += stride    add TMP0, TMP1              ; src += stride
139                  add edi, edx            ; dst += stride    add _EAX, TMP1              ; dst += stride
140  %endmacro  %endmacro
141    
142  align 16  ALIGN SECTION_ALIGN
143  cglobal interpolate8x8_halfpel_h_mmx  interpolate8x8_halfpel_h_mmx:
 interpolate8x8_halfpel_h_mmx  
   
                 push    esi  
                 push    edi  
   
                 mov     eax, [esp + 8 + 16]             ; rounding  
144    
145  interpolate8x8_halfpel_h_mmx.start    mov _EAX, prm4       ; rounding
146                  movq mm7, [rounding1_mmx + eax * 8]    lea TMP0, [rounding1_mmx]
147      movq mm7, [TMP0 + _EAX * 8]
148                  mov     edi, [esp + 8 + 4]              ; dst  
149                  mov     esi, [esp + 8 + 8]              ; src    mov _EAX, prm1        ; dst
150                  mov     edx, [esp + 8 + 12]     ; stride    mov TMP0, prm2        ; src
151      mov TMP1, prm3        ; stride
152    
153                  pxor    mm6, mm6                ; zero                  pxor    mm6, mm6                ; zero
154    
# Line 158  Line 161 
161                  COPY_H_MMX                  COPY_H_MMX
162                  COPY_H_MMX                  COPY_H_MMX
163    
                 pop edi  
                 pop esi  
   
164                  ret                  ret
165    ENDFUNC
166    
167    
168  ;===========================================================================  ;-----------------------------------------------------------------------------
169  ;  ;
170  ; void interpolate8x8_halfpel_v_mmx(uint8_t * const dst,  ; void interpolate8x8_halfpel_v_mmx(uint8_t * const dst,
171  ;                                               const uint8_t * const src,  ;                                               const uint8_t * const src,
172  ;                                               const uint32_t stride,  ;                                               const uint32_t stride,
173  ;                                               const uint32_t rounding);  ;                                               const uint32_t rounding);
174  ;  ;
175  ;===========================================================================  ;-----------------------------------------------------------------------------
176    
177  %macro COPY_V_MMX 0  %macro COPY_V_MMX 0
178                  movq mm0, [esi]    movq mm0, [TMP0]
179                  movq mm2, [esi + edx]    movq mm2, [TMP0 + TMP1]
180                  movq mm1, mm0                  movq mm1, mm0
181                  movq mm3, mm2                  movq mm3, mm2
182    
# Line 185  Line 186 
186                  CALC_AVG mm0, mm1, mm2, mm3, mm7, mm6                  CALC_AVG mm0, mm1, mm2, mm3, mm7, mm6
187    
188                  packuswb mm0, mm1                  packuswb mm0, mm1
189                  movq [edi], mm0                 ; [dst] = mm01    movq [_EAX], mm0      ; [dst] = mm01
190    
191                  add esi, edx            ; src += stride    add TMP0, TMP1        ; src += stride
192                  add edi, edx            ; dst += stride    add _EAX, TMP1        ; dst += stride
193  %endmacro  %endmacro
194    
195  align 16  ALIGN SECTION_ALIGN
196  cglobal interpolate8x8_halfpel_v_mmx  interpolate8x8_halfpel_v_mmx:
 interpolate8x8_halfpel_v_mmx  
197    
198                  push    esi    mov _EAX, prm4       ; rounding
199                  push    edi    lea TMP0, [rounding1_mmx]
200      movq mm7, [TMP0 + _EAX * 8]
201                  mov     eax, [esp + 8 + 16]             ; rounding  
202      mov _EAX, prm1       ; dst
203  interpolate8x8_halfpel_v_mmx.start    mov TMP0, prm2       ; src
204                  movq mm7, [rounding1_mmx + eax * 8]    mov TMP1, prm3       ; stride
   
                 mov     edi, [esp + 8 + 4]              ; dst  
                 mov     esi, [esp + 8 + 8]              ; src  
                 mov     edx, [esp + 8 + 12]     ; stride  
205    
206                  pxor    mm6, mm6                ; zero                  pxor    mm6, mm6                ; zero
207    
# Line 219  Line 215 
215                  COPY_V_MMX                  COPY_V_MMX
216                  COPY_V_MMX                  COPY_V_MMX
217    
                 pop edi  
                 pop esi  
   
218                  ret                  ret
219    ENDFUNC
220    
221    
222  ;===========================================================================  ;-----------------------------------------------------------------------------
223  ;  ;
224  ; void interpolate8x8_halfpel_hv_mmx(uint8_t * const dst,  ; void interpolate8x8_halfpel_hv_mmx(uint8_t * const dst,
225  ;                                               const uint8_t * const src,  ;                                               const uint8_t * const src,
# Line 233  Line 227 
227  ;                                               const uint32_t rounding);  ;                                               const uint32_t rounding);
228  ;  ;
229  ;  ;
230  ;===========================================================================  ;-----------------------------------------------------------------------------
231    
232  %macro COPY_HV_MMX 0  %macro COPY_HV_MMX 0
233                  ; current row                  ; current row
234      movq mm0, [TMP0]
235                  movq mm0, [esi]    movq mm2, [TMP0 + 1]
                 movq mm2, [esi + 1]  
236    
237                  movq mm1, mm0                  movq mm1, mm0
238                  movq mm3, mm2                  movq mm3, mm2
# Line 253  Line 246 
246                  paddusw mm1, mm3                  paddusw mm1, mm3
247    
248                  ; next row                  ; next row
249      movq mm4, [TMP0 + TMP1]
250                  movq mm4, [esi + edx]    movq mm2, [TMP0 + TMP1 + 1]
                 movq mm2, [esi + edx + 1]  
251    
252                  movq mm5, mm4                  movq mm5, mm4
253                  movq mm3, mm2                  movq mm3, mm2
# Line 269  Line 261 
261                  paddusw mm5, mm3                  paddusw mm5, mm3
262    
263                  ; add current + next row                  ; add current + next row
   
264                  paddusw mm0, mm4                ; mm01 += mm45                  paddusw mm0, mm4                ; mm01 += mm45
265                  paddusw mm1, mm5                  paddusw mm1, mm5
266                  paddusw mm0, mm7                ; mm01 += rounding2                  paddusw mm0, mm7                ; mm01 += rounding2
# Line 279  Line 270 
270                  psrlw mm1, 2                  psrlw mm1, 2
271    
272                  packuswb mm0, mm1                  packuswb mm0, mm1
273                  movq [edi], mm0                 ; [dst] = mm01    movq [_EAX], mm0           ; [dst] = mm01
274    
275                  add esi, edx            ; src += stride    add TMP0, TMP1             ; src += stride
276                  add edi, edx            ; dst += stride    add _EAX, TMP1             ; dst += stride
277  %endmacro  %endmacro
278    
279  align 16  ALIGN SECTION_ALIGN
280  cglobal interpolate8x8_halfpel_hv_mmx  interpolate8x8_halfpel_hv_mmx:
 interpolate8x8_halfpel_hv_mmx  
   
                 push    esi  
                 push    edi  
   
                 mov     eax, [esp + 8 + 16]             ; rounding  
 interpolate8x8_halfpel_hv_mmx.start  
281    
282                  movq mm7, [rounding2_mmx + eax * 8]    mov _EAX, prm4    ; rounding
283      lea TMP0, [rounding2_mmx]
284      movq mm7, [TMP0 + _EAX * 8]
285    
286                  mov     edi, [esp + 8 + 4]              ; dst    mov _EAX, prm1    ; dst
287                  mov     esi, [esp + 8 + 8]              ; src    mov TMP0, prm2    ; src
   
                 mov eax, 8  
288    
289                  pxor    mm6, mm6                ; zero                  pxor    mm6, mm6                ; zero
290    
291                  mov edx, [esp + 8 + 12] ; stride    mov TMP1, prm3    ; stride
292    
293                  COPY_HV_MMX                  COPY_HV_MMX
294                  COPY_HV_MMX                  COPY_HV_MMX
# Line 315  Line 299 
299                  COPY_HV_MMX                  COPY_HV_MMX
300                  COPY_HV_MMX                  COPY_HV_MMX
301    
302                  pop edi    ret
303                  pop esi  ENDFUNC
304    
305    ;-----------------------------------------------------------------------------
306    ;
307    ; void interpolate8x4_halfpel_h_mmx(uint8_t * const dst,
308    ;                       const uint8_t * const src,
309    ;                       const uint32_t stride,
310    ;                       const uint32_t rounding);
311    ;
312    ;-----------------------------------------------------------------------------
313    
314    ALIGN SECTION_ALIGN
315    interpolate8x4_halfpel_h_mmx:
316    
317      mov _EAX, prm4        ; rounding
318      lea TMP0, [rounding1_mmx]
319      movq mm7, [TMP0 + _EAX * 8]
320    
321      mov _EAX, prm1        ; dst
322      mov TMP0, prm2        ; src
323      mov TMP1, prm3        ; stride
324    
325      pxor mm6, mm6         ; zero
326    
327      COPY_H_MMX
328      COPY_H_MMX
329      COPY_H_MMX
330      COPY_H_MMX
331    
332                  ret                  ret
333    ENDFUNC
334    
335  ;===========================================================================  
336    ;-----------------------------------------------------------------------------
337    ;
338    ; void interpolate8x4_halfpel_v_mmx(uint8_t * const dst,
339    ;                       const uint8_t * const src,
340    ;                       const uint32_t stride,
341    ;                       const uint32_t rounding);
342    ;
343    ;-----------------------------------------------------------------------------
344    
345    ALIGN SECTION_ALIGN
346    interpolate8x4_halfpel_v_mmx:
347    
348      mov _EAX, prm4       ; rounding
349      lea TMP0, [rounding1_mmx]
350      movq mm7, [TMP0 + _EAX * 8]
351    
352      mov _EAX, prm1       ; dst
353      mov TMP0, prm2       ; src
354      mov TMP1, prm3       ; stride
355    
356      pxor mm6, mm6        ; zero
357    
358    
359      COPY_V_MMX
360      COPY_V_MMX
361      COPY_V_MMX
362      COPY_V_MMX
363    
364      ret
365    ENDFUNC
366    
367    
368    ;-----------------------------------------------------------------------------
369    ;
370    ; void interpolate8x4_halfpel_hv_mmx(uint8_t * const dst,
371    ;                       const uint8_t * const src,
372    ;                       const uint32_t stride,
373    ;                       const uint32_t rounding);
374    ;
375    ;
376    ;-----------------------------------------------------------------------------
377    
378    ALIGN SECTION_ALIGN
379    interpolate8x4_halfpel_hv_mmx:
380    
381      mov _EAX, prm4    ; rounding
382      lea TMP0, [rounding2_mmx]
383      movq mm7, [TMP0 + _EAX * 8]
384    
385      mov _EAX, prm1    ; dst
386      mov TMP0, prm2    ; src
387    
388      pxor mm6, mm6     ; zero
389    
390      mov TMP1, prm3    ; stride
391    
392      COPY_HV_MMX
393      COPY_HV_MMX
394      COPY_HV_MMX
395      COPY_HV_MMX
396    
397      ret
398    ENDFUNC
399    
400    ;-----------------------------------------------------------------------------
401  ;  ;
402  ; void interpolate8x8_avg2_mmx(uint8_t const *dst,  ; void interpolate8x8_avg2_mmx(uint8_t const *dst,
403  ;                                                          const uint8_t * const src1,  ;                                                          const uint8_t * const src1,
# Line 329  Line 406 
406  ;                                                          const uint32_t rounding,  ;                                                          const uint32_t rounding,
407  ;                                                          const uint32_t height);  ;                                                          const uint32_t height);
408  ;  ;
409  ;===========================================================================  ;-----------------------------------------------------------------------------
410    
411  %macro AVG2_MMX_RND0 0  %macro AVG2_MMX_RND0 0
412          movq    mm0, [eax]                      ; src1 -> mm0    movq mm0, [_EAX]           ; src1 -> mm0
413          movq    mm1, [ebx]                      ; src2 -> mm1    movq mm1, [_EBX]           ; src2 -> mm1
414    
415          movq    mm4, [eax+edx]    movq mm4, [_EAX+TMP1]
416          movq    mm5, [ebx+edx]    movq mm5, [_EBX+TMP1]
417    
418          movq    mm2, mm0                        ; src1 -> mm2          movq    mm2, mm0                        ; src1 -> mm2
419          movq    mm3, mm1                        ; src2 -> mm3          movq    mm3, mm1                        ; src2 -> mm3
# Line 371  Line 448 
448          paddb   mm4, mm5          paddb   mm4, mm5
449          paddb   mm4, mm3          paddb   mm4, mm3
450    
451          lea             eax,[eax+2*edx]    lea _EAX, [_EAX+2*TMP1]
452          lea             ebx,[ebx+2*edx]    lea _EBX, [_EBX+2*TMP1]
453    
454          movq    [ecx], mm0                      ; (src1 + src2 + 1) / 2 -> dst    movq [TMP0], mm0           ; (src1 + src2 + 1) / 2 -> dst
455          movq    [ecx+edx], mm4    movq [TMP0+TMP1], mm4
456  %endmacro  %endmacro
457    
458  %macro AVG2_MMX_RND1 0  %macro AVG2_MMX_RND1 0
459          movq    mm0, [eax]                      ; src1 -> mm0    movq mm0, [_EAX]           ; src1 -> mm0
460          movq    mm1, [ebx]                      ; src2 -> mm1    movq mm1, [_EBX]           ; src2 -> mm1
461    
462          movq    mm4, [eax+edx]    movq mm4, [_EAX+TMP1]
463          movq    mm5, [ebx+edx]    movq mm5, [_EBX+TMP1]
464    
465          movq    mm2, mm0                        ; src1 -> mm2          movq    mm2, mm0                        ; src1 -> mm2
466          movq    mm3, mm1                        ; src2 -> mm3          movq    mm3, mm1                        ; src2 -> mm3
# Line 418  Line 495 
495          paddb   mm4, mm5          paddb   mm4, mm5
496          paddb   mm4, mm3          paddb   mm4, mm3
497    
498          lea             eax,[eax+2*edx]    lea _EAX, [_EAX+2*TMP1]
499          lea             ebx,[ebx+2*edx]    lea _EBX, [_EBX+2*TMP1]
500    
501          movq    [ecx], mm0                      ; (src1 + src2 + 1) / 2 -> dst    movq [TMP0], mm0           ; (src1 + src2 + 1) / 2 -> dst
502          movq    [ecx+edx], mm4    movq [TMP0+TMP1], mm4
503  %endmacro  %endmacro
504    
505  align 16  ALIGN SECTION_ALIGN
506  cglobal interpolate8x8_avg2_mmx  interpolate8x8_avg2_mmx:
 interpolate8x8_avg2_mmx  
507    
508          push ebx    mov eax, prm5d   ; rounding
509      test _EAX, _EAX
         mov     eax, [esp + 4 + 20]             ; rounding  
         test eax, eax  
510    
511          jnz near .rounding1          jnz near .rounding1
512    
513          mov eax, [esp + 4 + 24]         ; height -> eax    mov eax, prm6d   ; height -> _EAX
514          sub eax, 8    sub _EAX, 8
515          test eax, eax  
516      mov TMP0, prm1   ; dst -> edi
517          mov ecx, [esp + 4 + 4]          ; dst -> edi    mov _EAX, prm2   ; src1 -> esi
518          mov eax, [esp + 4 + 8]          ; src1 -> esi    mov TMP1, prm4   ; stride -> TMP1
519          mov     ebx, [esp + 4 + 12]             ; src2 -> eax  
520          mov     edx, [esp + 4 + 16]             ; stride -> edx    push _EBX
521    %ifdef ARCH_IS_X86_64
522      mov _EBX, prm3
523    %else
524      mov _EBX, [esp + 4 + 12]   ; src2 -> eax
525    %endif
526    
527          movq mm7, [mmx_one]          movq mm7, [mmx_one]
528    
529          jz near .start0          jz near .start0
530    
531          AVG2_MMX_RND0          AVG2_MMX_RND0
532          lea ecx, [ecx+2*edx]    lea TMP0, [TMP0+2*TMP1]
533    
534  .start0  .start0:
535    
536          AVG2_MMX_RND0          AVG2_MMX_RND0
537          lea ecx, [ecx+2*edx]    lea TMP0, [TMP0+2*TMP1]
538          AVG2_MMX_RND0          AVG2_MMX_RND0
539          lea ecx, [ecx+2*edx]    lea TMP0, [TMP0+2*TMP1]
540          AVG2_MMX_RND0          AVG2_MMX_RND0
541          lea ecx, [ecx+2*edx]    lea TMP0, [TMP0+2*TMP1]
542          AVG2_MMX_RND0          AVG2_MMX_RND0
543    
544          pop     ebx    pop _EBX
545          ret          ret
546    
547  .rounding1  .rounding1:
548          mov eax, [esp + 4 + 24]         ; height -> eax    mov eax, prm6d        ; height -> _EAX
549          sub eax, 8    sub _EAX, 8
550          test eax, eax  
551      mov TMP0, prm1        ; dst -> edi
552          mov ecx, [esp + 4 + 4]          ; dst -> edi    mov _EAX, prm2        ; src1 -> esi
553          mov eax, [esp + 4 + 8]          ; src1 -> esi    mov TMP1, prm4        ; stride -> TMP1
554          mov     ebx, [esp + 4 + 12]             ; src2 -> eax  
555          mov     edx, [esp + 4 + 16]             ; stride -> edx    push _EBX
556    %ifdef ARCH_IS_X86_64
557      mov _EBX, prm3
558    %else
559      mov _EBX, [esp + 4 + 12]   ; src2 -> eax
560    %endif
561    
562          movq mm7, [mmx_one]          movq mm7, [mmx_one]
563    
564          jz near .start1          jz near .start1
565    
566          AVG2_MMX_RND1          AVG2_MMX_RND1
567          lea ecx, [ecx+2*edx]    lea TMP0, [TMP0+2*TMP1]
568    
569  .start1  .start1:
570    
571          AVG2_MMX_RND1          AVG2_MMX_RND1
572          lea ecx, [ecx+2*edx]    lea TMP0, [TMP0+2*TMP1]
573          AVG2_MMX_RND1          AVG2_MMX_RND1
574          lea ecx, [ecx+2*edx]    lea TMP0, [TMP0+2*TMP1]
575          AVG2_MMX_RND1          AVG2_MMX_RND1
576          lea ecx, [ecx+2*edx]    lea TMP0, [TMP0+2*TMP1]
577          AVG2_MMX_RND1          AVG2_MMX_RND1
578    
579          pop ebx    pop _EBX
580          ret          ret
581    ENDFUNC
582    
583    
584  ;===========================================================================  ;-----------------------------------------------------------------------------
585  ;  ;
586  ; void interpolate8x8_avg4_mmx(uint8_t const *dst,  ; void interpolate8x8_avg4_mmx(uint8_t const *dst,
587  ;                                                          const uint8_t * const src1,  ;                                                          const uint8_t * const src1,
# Line 506  Line 591 
591  ;                                                          const uint32_t stride,  ;                                                          const uint32_t stride,
592  ;                                                          const uint32_t rounding);  ;                                                          const uint32_t rounding);
593  ;  ;
594  ;===========================================================================  ;-----------------------------------------------------------------------------
595    
596  %macro AVG4_MMX_RND0 0  %macro AVG4_MMX_RND0 0
597          movq    mm0, [eax]                      ; src1 -> mm0    movq mm0, [_EAX]           ; src1 -> mm0
598          movq    mm1, [ebx]                      ; src2 -> mm1    movq mm1, [_EBX]           ; src2 -> mm1
599    
600          movq    mm2, mm0          movq    mm2, mm0
601          movq    mm3, mm1          movq    mm3, mm1
# Line 524  Line 609 
609          psrlq   mm0, 2          psrlq   mm0, 2
610          psrlq   mm1, 2          psrlq   mm1, 2
611    
612          lea             eax, [eax+edx]    lea _EAX, [_EAX+TMP1]
613          lea             ebx, [ebx+edx]    lea _EBX, [_EBX+TMP1]
614    
615          paddb   mm0, mm1          paddb   mm0, mm1
616          paddb   mm2, mm3          paddb   mm2, mm3
617    
618          movq    mm4, [esi]                      ; src3 -> mm0    movq mm4, [_ESI]           ; src3 -> mm0
619          movq    mm5, [edi]                      ; src4 -> mm1    movq mm5, [_EDI]           ; src4 -> mm1
620    
621          movq    mm1, mm4          movq    mm1, mm4
622          movq    mm3, mm5          movq    mm3, mm5
# Line 557  Line 642 
642          psrlq   mm2, 2          psrlq   mm2, 2
643          paddb   mm0, mm2          paddb   mm0, mm2
644    
645          lea             esi, [esi+edx]    lea _ESI, [_ESI+TMP1]
646          lea             edi, [edi+edx]    lea _EDI, [_EDI+TMP1]
647    
648          movq    [ecx], mm0                      ; (src1 + src2 + src3 + src4 + 2) / 4 -> dst    movq [TMP0], mm0           ; (src1 + src2 + src3 + src4 + 2) / 4 -> dst
649  %endmacro  %endmacro
650    
651  %macro AVG4_MMX_RND1 0  %macro AVG4_MMX_RND1 0
652          movq    mm0, [eax]                      ; src1 -> mm0    movq mm0, [_EAX]           ; src1 -> mm0
653          movq    mm1, [ebx]                      ; src2 -> mm1    movq mm1, [_EBX]           ; src2 -> mm1
654    
655          movq    mm2, mm0          movq    mm2, mm0
656          movq    mm3, mm1          movq    mm3, mm1
# Line 579  Line 664 
664          psrlq   mm0, 2          psrlq   mm0, 2
665          psrlq   mm1, 2          psrlq   mm1, 2
666    
667          lea             eax,[eax+edx]    lea _EAX,[_EAX+TMP1]
668          lea             ebx,[ebx+edx]    lea _EBX,[_EBX+TMP1]
669    
670          paddb   mm0, mm1          paddb   mm0, mm1
671          paddb   mm2, mm3          paddb   mm2, mm3
672    
673          movq    mm4, [esi]                      ; src3 -> mm0    movq mm4, [_ESI]           ; src3 -> mm0
674          movq    mm5, [edi]                      ; src4 -> mm1    movq mm5, [_EDI]           ; src4 -> mm1
675    
676          movq    mm1, mm4          movq    mm1, mm4
677          movq    mm3, mm5          movq    mm3, mm5
# Line 612  Line 697 
697          psrlq   mm2, 2          psrlq   mm2, 2
698          paddb   mm0, mm2          paddb   mm0, mm2
699    
700          lea             esi,[esi+edx]    lea _ESI,[_ESI+TMP1]
701          lea             edi,[edi+edx]    lea _EDI,[_EDI+TMP1]
702    
703          movq    [ecx], mm0                      ; (src1 + src2 + src3 + src4 + 2) / 4 -> dst    movq [TMP0], mm0           ; (src1 + src2 + src3 + src4 + 2) / 4 -> dst
704  %endmacro  %endmacro
705    
706  align 16  ALIGN SECTION_ALIGN
707  cglobal interpolate8x8_avg4_mmx  interpolate8x8_avg4_mmx:
708  interpolate8x8_avg4_mmx  
709      mov eax, prm7d      ; rounding
710      test _EAX, _EAX
711    
712      mov TMP0, prm1      ; dst -> edi
713      mov _EAX, prm5      ; src4 -> edi
714      mov TMP1d, prm6d    ; stride -> TMP1
715    
716    
717      push _EBX
718      push _EDI
719      push _ESI
720    
721          push ebx    mov _EDI, _EAX
722          push edi  
723          push esi  %ifdef ARCH_IS_X86_64
724      mov _EAX, prm2
725          mov     eax, [esp + 12 + 28]            ; rounding    mov _EBX, prm3
726      mov _ESI, prm4
727          test eax, eax  %else
728      mov _EAX, [esp + 12 +  8]      ; src1 -> esi
729          mov ecx, [esp + 12 + 4]                 ; dst -> edi    mov _EBX, [esp + 12 + 12]      ; src2 -> _EAX
730          mov eax, [esp + 12 + 8]                 ; src1 -> esi    mov _ESI, [esp + 12 + 16]      ; src3 -> esi
731          mov     ebx, [esp + 12 + 12]            ; src2 -> eax  %endif
         mov     esi, [esp + 12 + 16]            ; src3 -> esi  
         mov     edi, [esp + 12 + 20]            ; src4 -> edi  
         mov     edx, [esp + 12 + 24]            ; stride -> edx  
732    
733          movq mm7, [mmx_one]          movq mm7, [mmx_one]
734    
735          jnz near .rounding1          jnz near .rounding1
736    
737          AVG4_MMX_RND0          AVG4_MMX_RND0
738          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
739          AVG4_MMX_RND0          AVG4_MMX_RND0
740          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
741          AVG4_MMX_RND0          AVG4_MMX_RND0
742          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
743          AVG4_MMX_RND0          AVG4_MMX_RND0
744          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
745          AVG4_MMX_RND0          AVG4_MMX_RND0
746          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
747          AVG4_MMX_RND0          AVG4_MMX_RND0
748          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
749          AVG4_MMX_RND0          AVG4_MMX_RND0
750          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
751          AVG4_MMX_RND0          AVG4_MMX_RND0
752    
753          pop esi    pop _ESI
754          pop edi    pop _EDI
755          pop     ebx    pop _EBX
756          ret          ret
757    
758  .rounding1  .rounding1:
759          AVG4_MMX_RND1          AVG4_MMX_RND1
760          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
761          AVG4_MMX_RND1          AVG4_MMX_RND1
762          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
763          AVG4_MMX_RND1          AVG4_MMX_RND1
764          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
765          AVG4_MMX_RND1          AVG4_MMX_RND1
766          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
767          AVG4_MMX_RND1          AVG4_MMX_RND1
768          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
769          AVG4_MMX_RND1          AVG4_MMX_RND1
770          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
771          AVG4_MMX_RND1          AVG4_MMX_RND1
772          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
773          AVG4_MMX_RND1          AVG4_MMX_RND1
774    
775          pop esi    pop _ESI
776          pop edi    pop _EDI
777          pop ebx    pop _EBX
778          ret          ret
779    ENDFUNC
780    
781    
782  ;===========================================================================  ;-----------------------------------------------------------------------------
783  ;  ;
784  ; void interpolate8x8_6tap_lowpass_h_mmx(uint8_t const *dst,  ; void interpolate8x8_6tap_lowpass_h_mmx(uint8_t const *dst,
785  ;                                                                            const uint8_t * const src,  ;                                                                            const uint8_t * const src,
786  ;                                                                            const uint32_t stride,  ;                                                                            const uint32_t stride,
787  ;                                                                            const uint32_t rounding);  ;                                                                            const uint32_t rounding);
788  ;  ;
789  ;===========================================================================  ;-----------------------------------------------------------------------------
790    
791  %macro LOWPASS_6TAP_H_MMX 0  %macro LOWPASS_6TAP_H_MMX 0
792          movq    mm0, [eax]    movq mm0, [_EAX]
793          movq    mm2, [eax+1]    movq mm2, [_EAX+1]
794    
795          movq    mm1, mm0          movq    mm1, mm0
796          movq    mm3, mm2          movq    mm3, mm2
# Line 713  Line 807 
807          psllw   mm0, 2          psllw   mm0, 2
808          psllw   mm1, 2          psllw   mm1, 2
809    
810          movq    mm2, [eax-1]    movq mm2, [_EAX-1]
811          movq    mm4, [eax+2]    movq mm4, [_EAX+2]
812    
813          movq    mm3, mm2          movq    mm3, mm2
814          movq    mm5, mm4          movq    mm5, mm4
# Line 734  Line 828 
828          pmullw  mm0, [mmx_five]          pmullw  mm0, [mmx_five]
829          pmullw  mm1, [mmx_five]          pmullw  mm1, [mmx_five]
830    
831          movq    mm2, [eax-2]    movq mm2, [_EAX-2]
832          movq    mm4, [eax+3]    movq mm4, [_EAX+3]
833    
834          movq    mm3, mm2          movq    mm3, mm2
835          movq    mm5, mm4          movq    mm5, mm4
# Line 758  Line 852 
852          psraw   mm0, 5          psraw   mm0, 5
853          psraw   mm1, 5          psraw   mm1, 5
854    
855          lea             eax, [eax+edx]    lea _EAX, [_EAX+TMP1]
856          packuswb mm0, mm1          packuswb mm0, mm1
857          movq    [ecx], mm0    movq [TMP0], mm0
858  %endmacro  %endmacro
859    
860  align 16  ALIGN SECTION_ALIGN
861  cglobal interpolate8x8_6tap_lowpass_h_mmx  interpolate8x8_6tap_lowpass_h_mmx:
 interpolate8x8_6tap_lowpass_h_mmx  
862    
863          mov     eax, [esp + 16]                 ; rounding    mov _EAX, prm4           ; rounding
864    
865          movq mm6, [rounding_lowpass_mmx + eax * 8]    lea TMP0, [rounding_lowpass_mmx]
866      movq mm6, [TMP0 + _EAX * 8]
867    
868          mov ecx, [esp + 4]                      ; dst -> edi    mov TMP0, prm1           ; dst -> edi
869          mov eax, [esp + 8]                      ; src -> esi    mov _EAX, prm2           ; src -> esi
870          mov     edx, [esp + 12]                 ; stride -> edx    mov TMP1, prm3           ; stride -> edx
871    
872          pxor mm7, mm7          pxor mm7, mm7
873    
874          LOWPASS_6TAP_H_MMX          LOWPASS_6TAP_H_MMX
875          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
876          LOWPASS_6TAP_H_MMX          LOWPASS_6TAP_H_MMX
877          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
878          LOWPASS_6TAP_H_MMX          LOWPASS_6TAP_H_MMX
879          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
880          LOWPASS_6TAP_H_MMX          LOWPASS_6TAP_H_MMX
881          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
882          LOWPASS_6TAP_H_MMX          LOWPASS_6TAP_H_MMX
883          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
884          LOWPASS_6TAP_H_MMX          LOWPASS_6TAP_H_MMX
885          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
886          LOWPASS_6TAP_H_MMX          LOWPASS_6TAP_H_MMX
887          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
888          LOWPASS_6TAP_H_MMX          LOWPASS_6TAP_H_MMX
889    
890          ret          ret
891    ENDFUNC
892    
893  ;===========================================================================  ;-----------------------------------------------------------------------------
894  ;  ;
895  ; void interpolate8x8_6tap_lowpass_v_mmx(uint8_t const *dst,  ; void interpolate8x8_6tap_lowpass_v_mmx(uint8_t const *dst,
896  ;                                                                                const uint8_t * const src,  ;                                                                                const uint8_t * const src,
897  ;                                                                                const uint32_t stride,  ;                                                                                const uint32_t stride,
898  ;                                                                            const uint32_t rounding);  ;                                                                            const uint32_t rounding);
899  ;  ;
900  ;===========================================================================  ;-----------------------------------------------------------------------------
901    
902  %macro LOWPASS_6TAP_V_MMX 0  %macro LOWPASS_6TAP_V_MMX 0
903          movq    mm0, [eax]    movq mm0, [_EAX]
904          movq    mm2, [eax+edx]    movq mm2, [_EAX+TMP1]
905    
906          movq    mm1, mm0          movq    mm1, mm0
907          movq    mm3, mm2          movq    mm3, mm2
# Line 823  Line 918 
918          psllw   mm0, 2          psllw   mm0, 2
919          psllw   mm1, 2          psllw   mm1, 2
920    
921          movq    mm4, [eax+2*edx]    movq mm4, [_EAX+2*TMP1]
922          sub             eax, ebx    sub _EAX, _EBX
923          movq    mm2, [eax+2*edx]    movq mm2, [_EAX+2*TMP1]
924    
925          movq    mm3, mm2          movq    mm3, mm2
926          movq    mm5, mm4          movq    mm5, mm4
# Line 845  Line 940 
940          pmullw  mm0, [mmx_five]          pmullw  mm0, [mmx_five]
941          pmullw  mm1, [mmx_five]          pmullw  mm1, [mmx_five]
942    
943          movq    mm2, [eax+edx]    movq mm2, [_EAX+TMP1]
944          movq    mm4, [eax+2*ebx]    movq mm4, [_EAX+2*_EBX]
945    
946          movq    mm3, mm2          movq    mm3, mm2
947          movq    mm5, mm4          movq    mm5, mm4
# Line 869  Line 964 
964          psraw   mm0, 5          psraw   mm0, 5
965          psraw   mm1, 5          psraw   mm1, 5
966    
967          lea             eax, [eax+4*edx]    lea _EAX, [_EAX+4*TMP1]
968          packuswb mm0, mm1          packuswb mm0, mm1
969          movq    [ecx], mm0    movq [TMP0], mm0
970  %endmacro  %endmacro
971    
972  align 16  ALIGN SECTION_ALIGN
973  cglobal interpolate8x8_6tap_lowpass_v_mmx  interpolate8x8_6tap_lowpass_v_mmx:
 interpolate8x8_6tap_lowpass_v_mmx  
   
         push ebx  
974    
975          mov     eax, [esp + 4 + 16]                     ; rounding    mov _EAX, prm4           ; rounding
976    
977          movq mm6, [rounding_lowpass_mmx + eax * 8]    lea TMP0, [rounding_lowpass_mmx]
978      movq mm6, [TMP0 + _EAX * 8]
979    
980          mov ecx, [esp + 4 + 4]                  ; dst -> edi    mov TMP0, prm1           ; dst -> edi
981          mov eax, [esp + 4 + 8]                  ; src -> esi    mov _EAX, prm2           ; src -> esi
982          mov     edx, [esp + 4 + 12]                     ; stride -> edx    mov TMP1, prm3           ; stride -> edx
983    
984          mov ebx, edx    push _EBX
985          shl     ebx, 1    lea _EBX, [TMP1+TMP1*2]
         add ebx, edx  
986    
987          pxor mm7, mm7          pxor mm7, mm7
988    
989          LOWPASS_6TAP_V_MMX          LOWPASS_6TAP_V_MMX
990          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
991          LOWPASS_6TAP_V_MMX          LOWPASS_6TAP_V_MMX
992          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
993          LOWPASS_6TAP_V_MMX          LOWPASS_6TAP_V_MMX
994          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
995          LOWPASS_6TAP_V_MMX          LOWPASS_6TAP_V_MMX
996          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
997          LOWPASS_6TAP_V_MMX          LOWPASS_6TAP_V_MMX
998          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
999          LOWPASS_6TAP_V_MMX          LOWPASS_6TAP_V_MMX
1000          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
1001          LOWPASS_6TAP_V_MMX          LOWPASS_6TAP_V_MMX
1002          lea ecx, [ecx+edx]    lea TMP0, [TMP0+TMP1]
1003          LOWPASS_6TAP_V_MMX          LOWPASS_6TAP_V_MMX
1004    
1005          pop ebx    pop _EBX
1006          ret          ret
1007    ENDFUNC
1008    
1009    ;===========================================================================
1010    ;
1011    ; The next functions combine both source halfpel interpolation step and the
1012    ; averaging (with rouding) step to avoid wasting memory bandwidth computing
1013    ; intermediate halfpel images and then averaging them.
1014    ;
1015    ;===========================================================================
1016    
1017    %macro PROLOG0 0
1018      mov TMP0, prm1 ; Dst
1019      mov _EAX, prm2 ; Src
1020      mov TMP1, prm3 ; BpS
1021    %endmacro
1022    
1023    %macro PROLOG 2   ; %1: Rounder, %2 load Dst-Rounder
1024      pxor mm6, mm6
1025      movq mm7, [%1]    ; TODO: dangerous! (eax isn't checked)
1026    %if %2
1027      movq mm5, [rounding1_mmx]
1028    %endif
1029    
1030      PROLOG0
1031    %endmacro
1032    
1033      ; performs: mm0 == (mm0+mm2)  mm1 == (mm1+mm3)
1034    %macro MIX 0
1035      punpcklbw mm0, mm6
1036      punpcklbw mm2, mm6
1037      punpckhbw mm1, mm6
1038      punpckhbw mm3, mm6
1039      paddusw mm0, mm2
1040      paddusw mm1, mm3
1041    %endmacro
1042    
1043    %macro MIX_DST 0
1044      movq mm3, mm2
1045      paddusw mm0, mm7  ; rounder
1046      paddusw mm1, mm7  ; rounder
1047      punpcklbw mm2, mm6
1048      punpckhbw mm3, mm6
1049      psrlw mm0, 1
1050      psrlw mm1, 1
1051    
1052      paddusw mm0, mm2  ; mix Src(mm0/mm1) with Dst(mm2/mm3)
1053      paddusw mm1, mm3
1054      paddusw mm0, mm5
1055      paddusw mm1, mm5
1056      psrlw mm0, 1
1057      psrlw mm1, 1
1058    
1059      packuswb mm0, mm1
1060    %endmacro
1061    
1062    %macro MIX2 0
1063      punpcklbw mm0, mm6
1064      punpcklbw mm2, mm6
1065      paddusw mm0, mm2
1066      paddusw mm0, mm7
1067      punpckhbw mm1, mm6
1068      punpckhbw mm3, mm6
1069      paddusw mm1, mm7
1070      paddusw mm1, mm3
1071      psrlw mm0, 1
1072      psrlw mm1, 1
1073    
1074      packuswb mm0, mm1
1075    %endmacro
1076    
1077    ;===========================================================================
1078    ;
1079    ; void interpolate8x8_halfpel_add_mmx(uint8_t * const dst,
1080    ;                       const uint8_t * const src,
1081    ;                       const uint32_t stride,
1082    ;                       const uint32_t rounding);
1083    ;
1084    ;
1085    ;===========================================================================
1086    
1087    %macro ADD_FF_MMX 1
1088      movq mm0, [_EAX]
1089      movq mm2, [TMP0]
1090      movq mm1, mm0
1091      movq mm3, mm2
1092    %if (%1!=0)
1093      lea _EAX,[_EAX+%1*TMP1]
1094    %endif
1095      MIX
1096      paddusw mm0, mm5  ; rounder
1097      paddusw mm1, mm5  ; rounder
1098      psrlw mm0, 1
1099      psrlw mm1, 1
1100    
1101      packuswb mm0, mm1
1102      movq [TMP0], mm0
1103    %if (%1!=0)
1104      lea TMP0,[TMP0+%1*TMP1]
1105    %endif
1106    %endmacro
1107    
1108    ALIGN SECTION_ALIGN
1109    interpolate8x8_halfpel_add_mmx:
1110      PROLOG rounding1_mmx, 1
1111      ADD_FF_MMX 1
1112      ADD_FF_MMX 1
1113      ADD_FF_MMX 1
1114      ADD_FF_MMX 1
1115      ADD_FF_MMX 1
1116      ADD_FF_MMX 1
1117      ADD_FF_MMX 1
1118      ADD_FF_MMX 0
1119      ret
1120    ENDFUNC
1121    
1122    ;===========================================================================
1123    ;
1124    ; void interpolate8x8_halfpel_h_add_mmx(uint8_t * const dst,
1125    ;                       const uint8_t * const src,
1126    ;                       const uint32_t stride,
1127    ;                       const uint32_t rounding);
1128    ;
1129    ;
1130    ;===========================================================================
1131    
1132    %macro ADD_FH_MMX 0
1133      movq mm0, [_EAX]
1134      movq mm2, [_EAX+1]
1135      movq mm1, mm0
1136      movq mm3, mm2
1137    
1138      lea _EAX,[_EAX+TMP1]
1139    
1140      MIX
1141      movq mm2, [TMP0]   ; prepare mix with Dst[0]
1142      MIX_DST
1143      movq [TMP0], mm0
1144    %endmacro
1145    
1146    ALIGN SECTION_ALIGN
1147    interpolate8x8_halfpel_h_add_mmx:
1148      PROLOG rounding1_mmx, 1
1149    
1150      ADD_FH_MMX
1151      lea TMP0,[TMP0+TMP1]
1152      ADD_FH_MMX
1153      lea TMP0,[TMP0+TMP1]
1154      ADD_FH_MMX
1155      lea TMP0,[TMP0+TMP1]
1156      ADD_FH_MMX
1157      lea TMP0,[TMP0+TMP1]
1158      ADD_FH_MMX
1159      lea TMP0,[TMP0+TMP1]
1160      ADD_FH_MMX
1161      lea TMP0,[TMP0+TMP1]
1162      ADD_FH_MMX
1163      lea TMP0,[TMP0+TMP1]
1164      ADD_FH_MMX
1165      ret
1166    ENDFUNC
1167    
1168    ;===========================================================================
1169    ;
1170    ; void interpolate8x8_halfpel_v_add_mmx(uint8_t * const dst,
1171    ;                       const uint8_t * const src,
1172    ;                       const uint32_t stride,
1173    ;                       const uint32_t rounding);
1174    ;
1175    ;
1176    ;===========================================================================
1177    
1178    %macro ADD_HF_MMX 0
1179      movq mm0, [_EAX]
1180      movq mm2, [_EAX+TMP1]
1181      movq mm1, mm0
1182      movq mm3, mm2
1183    
1184      lea _EAX,[_EAX+TMP1]
1185    
1186      MIX
1187      movq mm2, [TMP0]   ; prepare mix with Dst[0]
1188      MIX_DST
1189      movq [TMP0], mm0
1190    
1191    %endmacro
1192    
1193    ALIGN SECTION_ALIGN
1194    interpolate8x8_halfpel_v_add_mmx:
1195      PROLOG rounding1_mmx, 1
1196    
1197      ADD_HF_MMX
1198      lea TMP0,[TMP0+TMP1]
1199      ADD_HF_MMX
1200      lea TMP0,[TMP0+TMP1]
1201      ADD_HF_MMX
1202      lea TMP0,[TMP0+TMP1]
1203      ADD_HF_MMX
1204      lea TMP0,[TMP0+TMP1]
1205      ADD_HF_MMX
1206      lea TMP0,[TMP0+TMP1]
1207      ADD_HF_MMX
1208      lea TMP0,[TMP0+TMP1]
1209      ADD_HF_MMX
1210      lea TMP0,[TMP0+TMP1]
1211      ADD_HF_MMX
1212      ret
1213    ENDFUNC
1214    
1215    ; The trick is to correct the result of 'pavgb' with some combination of the
1216    ; lsb's of the 4 input values i,j,k,l, and their intermediate 'pavgb' (s and t).
1217    ; The boolean relations are:
1218    ;   (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
1219    ;   (i+j+k+l+2)/4 = (s+t+1)/2 - (ij|kl)&st
1220    ;   (i+j+k+l+1)/4 = (s+t+1)/2 - (ij&kl)|st
1221    ;   (i+j+k+l+0)/4 = (s+t+1)/2 - (ij|kl)|st
1222    ; with  s=(i+j+1)/2, t=(k+l+1)/2, ij = i^j, kl = k^l, st = s^t.
1223    
1224    ; Moreover, we process 2 lines at a times, for better overlapping (~15% faster).
1225    
1226    ;===========================================================================
1227    ;
1228    ; void interpolate8x8_halfpel_hv_add_mmx(uint8_t * const dst,
1229    ;                       const uint8_t * const src,
1230    ;                       const uint32_t stride,
1231    ;                       const uint32_t rounding);
1232    ;
1233    ;
1234    ;===========================================================================
1235    
1236    %macro ADD_HH_MMX 0
1237      lea _EAX,[_EAX+TMP1]
1238    
1239        ; transfert prev line to mm0/mm1
1240      movq mm0, mm2
1241      movq mm1, mm3
1242    
1243        ; load new line in mm2/mm3
1244      movq mm2, [_EAX]
1245      movq mm4, [_EAX+1]
1246      movq mm3, mm2
1247      movq mm5, mm4
1248    
1249      punpcklbw mm2, mm6
1250      punpcklbw mm4, mm6
1251      paddusw mm2, mm4
1252      punpckhbw mm3, mm6
1253      punpckhbw mm5, mm6
1254      paddusw mm3, mm5
1255    
1256        ; mix current line (mm2/mm3) with previous (mm0,mm1);
1257        ; we'll preserve mm2/mm3 for next line...
1258    
1259      paddusw mm0, mm2
1260      paddusw mm1, mm3
1261    
1262      movq mm4, [TMP0]   ; prepare mix with Dst[0]
1263      movq mm5, mm4
1264    
1265      paddusw mm0, mm7  ; finish mixing current line
1266      paddusw mm1, mm7
1267    
1268      punpcklbw mm4, mm6
1269      punpckhbw mm5, mm6
1270    
1271      psrlw mm0, 2
1272      psrlw mm1, 2
1273    
1274      paddusw mm0, mm4  ; mix Src(mm0/mm1) with Dst(mm2/mm3)
1275      paddusw mm1, mm5
1276    
1277      paddusw mm0, [rounding1_mmx]
1278      paddusw mm1, [rounding1_mmx]
1279    
1280      psrlw mm0, 1
1281      psrlw mm1, 1
1282    
1283      packuswb mm0, mm1
1284    
1285      movq [TMP0], mm0
1286    %endmacro
1287    
1288    ALIGN SECTION_ALIGN
1289    interpolate8x8_halfpel_hv_add_mmx:
1290      PROLOG rounding2_mmx, 0    ; mm5 is busy. Don't load dst-rounder
1291    
1292        ; preprocess first line
1293      movq mm0, [_EAX]
1294      movq mm2, [_EAX+1]
1295      movq mm1, mm0
1296      movq mm3, mm2
1297    
1298      punpcklbw mm0, mm6
1299      punpcklbw mm2, mm6
1300      punpckhbw mm1, mm6
1301      punpckhbw mm3, mm6
1302      paddusw mm2, mm0
1303      paddusw mm3, mm1
1304    
1305       ; Input: mm2/mm3 contains the value (Src[0]+Src[1]) of previous line
1306    
1307      ADD_HH_MMX
1308      lea TMP0,[TMP0+TMP1]
1309      ADD_HH_MMX
1310      lea TMP0,[TMP0+TMP1]
1311      ADD_HH_MMX
1312      lea TMP0,[TMP0+TMP1]
1313      ADD_HH_MMX
1314      lea TMP0,[TMP0+TMP1]
1315      ADD_HH_MMX
1316      lea TMP0,[TMP0+TMP1]
1317      ADD_HH_MMX
1318      lea TMP0,[TMP0+TMP1]
1319      ADD_HH_MMX
1320      lea TMP0,[TMP0+TMP1]
1321      ADD_HH_MMX
1322    
1323      ret
1324    ENDFUNC
1325    
1326    
1327    %ifidn __OUTPUT_FORMAT__,elf
1328    section ".note.GNU-stack" noalloc noexec nowrite progbits
1329    %endif
1330    

Legend:
Removed from v.851  
changed lines
  Added in v.1834

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