[cvs] / xvidcore / src / quant / x86_asm / quantize_mpeg_mmx.asm Repository:
ViewVC logotype

Diff of /xvidcore/src/quant/x86_asm/quantize_mpeg_mmx.asm

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

revision 1.10, Tue Nov 11 20:46:24 2008 UTC revision 1.16, Wed Sep 16 17:07:58 2009 UTC
# Line 4  Line 4 
4  ; *  - 3dne Quantization/Dequantization -  ; *  - 3dne Quantization/Dequantization -
5  ; *  ; *
6  ; *  Copyright (C) 2002-2003 Peter Ross <pross@xvid.org>  ; *  Copyright (C) 2002-2003 Peter Ross <pross@xvid.org>
7  ; *                2002-2003 Michael Militzer <isibaar@xvid.org>  ; *                2002-2008 Michael Militzer <michael@xvid.org>
8  ; *                2002-2003 Pascal Massimino <skal@planet-d.net>  ; *                2002-2003 Pascal Massimino <skal@planet-d.net>
9  ; *  ; *
10  ; *  This program is free software ; you can redistribute it and/or modify  ; *  This program is free software ; you can redistribute it and/or modify
# Line 27  Line 27 
27    
28  %define SATURATE  %define SATURATE
29    
30  BITS 32  %include "nasm.inc"
   
 %macro cglobal 1  
         %ifdef PREFIX  
                 %ifdef MARK_FUNCS  
                         global _%1:function %1.endfunc-%1  
                         %define %1 _%1:function %1.endfunc-%1  
                         %define ENDFUNC .endfunc  
                 %else  
                         global _%1  
                         %define %1 _%1  
                         %define ENDFUNC  
                 %endif  
         %else  
                 %ifdef MARK_FUNCS  
                         global %1:function %1.endfunc-%1  
                         %define ENDFUNC .endfunc  
                 %else  
                         global %1  
                         %define ENDFUNC  
                 %endif  
         %endif  
 %endmacro  
   
 %macro cextern 1  
         %ifdef PREFIX  
                 extern _%1  
                 %define %1 _%1  
         %else  
                 extern %1  
         %endif  
 %endmacro  
31    
32  ;=============================================================================  ;=============================================================================
33  ; Local data (Read Only)  ; Local data (Read Only)
34  ;=============================================================================  ;=============================================================================
35    
36  %ifdef FORMAT_COFF  DATA
 SECTION .rodata  
 %else  
 SECTION .rodata align=16  
 %endif  
37    
38  mmx_one:  mmx_one:
39          times 4 dw       1          times 4 dw       1
# Line 77  Line 42 
42  ; divide by 2Q table  ; divide by 2Q table
43  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
44    
45  ALIGN 16  ALIGN SECTION_ALIGN
46  mmx_div:  mmx_div:
47          times 4 dw 65535 ; the div by 2 formula will overflow for the case          times 4 dw 65535 ; the div by 2 formula will overflow for the case
48                           ; quant=1 but we don't care much because quant=1                           ; quant=1 but we don't care much because quant=1
# Line 119  Line 84 
84  ; saturation limits  ; saturation limits
85  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
86    
87  ALIGN 16  ALIGN SECTION_ALIGN
88    
89  mmx_32767_minus_2047:  mmx_32767_minus_2047:
90          times 4 dw (32767-2047)          times 4 dw (32767-2047)
# Line 136  Line 101 
101  ; rounding  ; rounding
102  ;=============================================================================  ;=============================================================================
103    
104    ALIGN SECTION_ALIGN
105    
106  mmx_rounding:  mmx_rounding:
107          dw (1<<13)          dd (1<<13)
108          dw 0          dd (1<<13)
         dw (1<<13)  
         dw 0  
109    
110  ;=============================================================================  ;=============================================================================
111  ; Code  ; Code
112  ;=============================================================================  ;=============================================================================
113    
114  SECTION .text  TEXT
115    
116  cglobal quant_mpeg_intra_mmx  cglobal quant_mpeg_intra_mmx
117  cglobal quant_mpeg_inter_mmx  cglobal quant_mpeg_inter_mmx
# Line 155  Line 120 
120    
121    
122  %macro QUANT_MMX        1  %macro QUANT_MMX        1
123          movq    mm0, [eax + 16*(%1)]                    ; data          movq    mm0, [_EAX + 16*(%1)]                   ; data
124          movq    mm2, [ecx + 16*(%1) + 128]              ; intra_matrix_rec          movq    mm2, [TMP0 + 16*(%1) + 128]             ; intra_matrix_rec
125          movq    mm4, [eax + 16*(%1) + 8]                ; data          movq    mm4, [_EAX + 16*(%1) + 8]               ; data
126          movq    mm6, [ecx + 16*(%1) + 128 + 8]  ; intra_matrix_rec          movq    mm6, [TMP0 + 16*(%1) + 128 + 8] ; intra_matrix_rec
127    
128          movq    mm1, mm0          movq    mm1, mm0
129          movq    mm5, mm4          movq    mm5, mm4
# Line 189  Line 154 
154          packssdw mm2, mm0          packssdw mm2, mm0
155          packssdw mm6, mm4          packssdw mm6, mm4
156    
157          movq    [edi + 16*(%1)], mm2          movq    [TMP1 + 16*(%1)], mm2
158          movq    [edi + 16*(%1)+8], mm6          movq    [TMP1 + 16*(%1)+8], mm6
159  %endmacro  %endmacro
160    
161  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
# Line 203  Line 168 
168  ;  ;
169  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
170    
171  ALIGN 16  ALIGN SECTION_ALIGN
172  quant_mpeg_intra_mmx:  quant_mpeg_intra_mmx:
173    
174    push edi    mov _EAX, prm2                ; data
175    movq mm7, [mmx_rounding]    mov TMP0, prm5                ; mpeg_quant_matrices
176      mov TMP1, prm1                ; coeff
177    
178    mov eax, [esp + 4 + 8]                ; data    movq mm7, [mmx_rounding]
   mov ecx, [esp + 4 + 20]               ; mpeg_quant_matrices  
   mov edi, [esp + 4 + 4]                ; coeff  
179    
180    QUANT_MMX(0)    QUANT_MMX(0)
181    QUANT_MMX(1)    QUANT_MMX(1)
# Line 223  Line 187 
187    QUANT_MMX(7)    QUANT_MMX(7)
188    
189    ; calculate DC    ; calculate DC
190    movsx eax, word [eax]     ; data[0]    movsx _EAX, word [_EAX]  ; data[0]
191    mov ecx, [esp + 4 + 16]   ; dcscalar    mov TMP0, prm4           ; dcscalar
192    mov edx, eax    mov _EDX, _EAX
193    mov edi, ecx    shr TMP0, 1              ; TMP0 = dcscalar/2
194    shr ecx, 1                ; ecx = dcscalar/2    sar _EDX, 31             ; TMP1 = sign extend of _EAX (ready for division too)
195    sar edx, 31               ; edx = sign extend of eax (ready for division too)  
196    xor ecx, edx              ; adjust ecx according to the sign of data[0]    xor TMP0, _EDX           ; adjust TMP0 according to the sign of data[0]
197    sub ecx, edx    sub TMP0, _EDX
198    add eax, ecx    add _EAX, TMP0
   
   mov ecx, [esp + 4 + 4]        ; coeff again  
   idiv edi                  ; eax = edx:eax / dcscalar  
   mov [ecx], ax             ; coeff[0] = ax  
199    
200    pop edi    mov TMP0, prm4            ; dcscalar
201      idiv TMP0                 ; _EAX = _EDX:_EAX / dcscalar
202    
203    xor eax, eax              ; return(0);    mov _EDX, prm1            ; coeff again
204      mov word [_EDX], ax       ; coeff[0] = ax
205    
206      xor _EAX, _EAX            ; return(0);
207    ret    ret
208  ENDFUNC  ENDFUNC
209    
# Line 253  Line 217 
217  ;  ;
218  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
219    
220  ALIGN 16  ALIGN SECTION_ALIGN
221  quant_mpeg_inter_mmx:  quant_mpeg_inter_mmx:
222    
223    push ecx    mov TMP1, prm1           ; coeff
224    push esi    mov _EAX, prm3           ; quant
225    push edi    mov TMP0, prm4           ; mpeg_quant_matrices
226    push ebx  
227      push _ESI
228    mov edi, [esp + 16 + 4]       ; coeff  %ifdef ARCH_IS_X86_64
229    mov esi, [esp + 16 + 8]       ; data    mov _ESI, prm2           ; data
230    mov eax, [esp + 16 + 12]  ; quant  %else
231    mov ebx, [esp + 16 + 16]              ; mpeg_quant_matrices    mov _ESI, [_ESP + 4 + 8] ; data
232    %endif
233    
234    xor ecx, ecx    push _EBX
235      xor _EBX, _EBX
236    
237    pxor mm5, mm5                 ; sum    pxor mm5, mm5                 ; sum
238    
# Line 276  Line 242 
242    cmp al, 2    cmp al, 2
243    jz near .q2loop    jz near .q2loop
244    
245    movq mm7, [mmx_div + eax * 8 - 8] ; divider  %ifdef ARCH_IS_X86_64
246      lea r9, [mmx_div]
247      movq mm7, [r9 + _EAX * 8 - 8]
248    %else
249      movq mm7, [mmx_div + _EAX * 8 - 8] ; divider
250    %endif
251    
252  ALIGN 16  ALIGN SECTION_ALIGN
253  .loop:  .loop:
254    movq mm0, [esi + 8*ecx]       ; mm0 = [1st]    movq mm0, [_ESI + 8*_EBX]       ; mm0 = [1st]
255    movq mm3, [esi + 8*ecx + 8]   ;    movq mm3, [_ESI + 8*_EBX + 8]   ;
256    pxor mm1, mm1                 ; mm1 = 0    pxor mm1, mm1                 ; mm1 = 0
257    pxor mm4, mm4                 ;    pxor mm4, mm4                 ;
258    pcmpgtw mm1, mm0              ; mm1 = (0 > mm0)    pcmpgtw mm1, mm0              ; mm1 = (0 > mm0)
# Line 292  Line 263 
263    psubw mm3, mm4                ;    psubw mm3, mm4                ;
264    psllw mm0, 4    psllw mm0, 4
265    psllw mm3, 4    psllw mm3, 4
266    movq mm2, [ebx + 512 + 8*ecx]    movq mm2, [TMP0 + 512 + 8*_EBX]
267    psrlw mm2, 1    psrlw mm2, 1
268    paddw mm0, mm2    paddw mm0, mm2
269    movq mm2, [ebx + 768 + ecx*8]    movq mm2, [TMP0 + 768 + _EBX*8]
270    pmulhw mm0, mm2               ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]    pmulhw mm0, mm2               ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
271    movq mm2, [ebx + 512 + 8*ecx + 8]    movq mm2, [TMP0 + 512 + 8*_EBX + 8]
272    psrlw mm2, 1    psrlw mm2, 1
273    paddw mm3, mm2    paddw mm3, mm2
274    movq mm2, [ebx + 768 + ecx*8 + 8]    movq mm2, [TMP0 + 768 + _EBX*8 + 8]
275    pmulhw mm3, mm2    pmulhw mm3, mm2
276    pmulhw mm0, mm7               ; mm0 = (mm0 / 2Q) >> 16    pmulhw mm0, mm7               ; mm0 = (mm0 / 2Q) >> 16
277    pmulhw mm3, mm7               ;    pmulhw mm3, mm7               ;
# Line 312  Line 283 
283    pxor mm3, mm4                 ;    pxor mm3, mm4                 ;
284    psubw mm0, mm1                ; undisplace    psubw mm0, mm1                ; undisplace
285    psubw mm3, mm4    psubw mm3, mm4
286    movq [edi + 8*ecx], mm0    movq [TMP1 + 8*_EBX], mm0
287    movq [edi + 8*ecx + 8], mm3    movq [TMP1 + 8*_EBX + 8], mm3
288    
289    add ecx, 2    add _EBX, 2
290    cmp ecx, 16    cmp _EBX, 16
291    jnz near .loop    jnz near .loop
292    
293  .done:  .done:
# Line 326  Line 297 
297    paddd mm0, mm5    paddd mm0, mm5
298    movd eax, mm0                 ; return sum    movd eax, mm0                 ; return sum
299    
300    pop ebx    pop _EBX
301    pop edi    pop _ESI
   pop esi  
   pop ecx  
302    
303    ret    ret
304    
305  ALIGN 16  ALIGN SECTION_ALIGN
306  .q1loop:  .q1loop:
307    movq mm0, [esi + 8*ecx]       ; mm0 = [1st]    movq mm0, [_ESI + 8*_EBX]       ; mm0 = [1st]
308    movq mm3, [esi + 8*ecx+ 8]    movq mm3, [_ESI + 8*_EBX+ 8]
309    pxor mm1, mm1                 ; mm1 = 0    pxor mm1, mm1                 ; mm1 = 0
310    pxor mm4, mm4                 ;    pxor mm4, mm4                 ;
311    pcmpgtw mm1, mm0              ; mm1 = (0 > mm0)    pcmpgtw mm1, mm0              ; mm1 = (0 > mm0)
# Line 347  Line 316 
316    psubw mm3, mm4                ;    psubw mm3, mm4                ;
317    psllw mm0, 4    psllw mm0, 4
318    psllw mm3, 4    psllw mm3, 4
319    movq mm2, [ebx + 512 + 8*ecx]    movq mm2, [TMP0 + 512 + 8*_EBX]
320    psrlw mm2, 1    psrlw mm2, 1
321    paddw mm0, mm2    paddw mm0, mm2
322    movq mm2, [ebx + 768 + ecx*8]    movq mm2, [TMP0 + 768 + _EBX*8]
323    pmulhw mm0, mm2               ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]    pmulhw mm0, mm2               ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
324    movq mm2, [ebx + 512 + 8*ecx + 8]    movq mm2, [TMP0 + 512 + 8*_EBX + 8]
325    psrlw mm2, 1    psrlw mm2, 1
326    paddw mm3, mm2    paddw mm3, mm2
327    movq mm2, [ebx + 768 + ecx*8 + 8]    movq mm2, [TMP0 + 768 + _EBX*8 + 8]
328    pmulhw mm3, mm2    pmulhw mm3, mm2
329    psrlw mm0, 1                  ; mm0 >>= 1   (/2)    psrlw mm0, 1                  ; mm0 >>= 1   (/2)
330    psrlw mm3, 1                  ;    psrlw mm3, 1                  ;
# Line 365  Line 334 
334    pxor mm3, mm4                 ;    pxor mm3, mm4                 ;
335    psubw mm0, mm1                ; undisplace    psubw mm0, mm1                ; undisplace
336    psubw mm3, mm4    psubw mm3, mm4
337    movq [edi + 8*ecx], mm0    movq [TMP1 + 8*_EBX], mm0
338    movq [edi + 8*ecx + 8], mm3    movq [TMP1 + 8*_EBX + 8], mm3
339    
340    add ecx, 2    add _EBX, 2
341    cmp ecx, 16    cmp _EBX, 16
342    jnz near .q1loop    jnz near .q1loop
343    
344    jmp .done    jmp .done
345    
346  ALIGN 16  ALIGN SECTION_ALIGN
347  .q2loop:  .q2loop:
348    movq mm0, [esi + 8*ecx]       ; mm0 = [1st]    movq mm0, [_ESI + 8*_EBX]       ; mm0 = [1st]
349    movq mm3, [esi + 8*ecx+ 8]    movq mm3, [_ESI + 8*_EBX+ 8]
350    pxor mm1, mm1                 ; mm1 = 0    pxor mm1, mm1                 ; mm1 = 0
351    pxor mm4, mm4                 ;    pxor mm4, mm4                 ;
352    pcmpgtw mm1, mm0              ; mm1 = (0 > mm0)    pcmpgtw mm1, mm0              ; mm1 = (0 > mm0)
# Line 388  Line 357 
357    psubw mm3, mm4                ;    psubw mm3, mm4                ;
358    psllw mm0, 4    psllw mm0, 4
359    psllw mm3, 4    psllw mm3, 4
360    movq mm2, [ebx + 512 + 8*ecx]    movq mm2, [TMP0 + 512 + 8*_EBX]
361    psrlw mm2, 1    psrlw mm2, 1
362    paddw mm0, mm2    paddw mm0, mm2
363    movq mm2, [ebx + 768 + ecx*8]    movq mm2, [TMP0 + 768 + _EBX*8]
364    pmulhw mm0, mm2               ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]    pmulhw mm0, mm2               ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
365    movq mm2, [ebx + 512 + 8*ecx + 8]    movq mm2, [TMP0 + 512 + 8*_EBX + 8]
366    psrlw mm2, 1    psrlw mm2, 1
367    paddw mm3, mm2    paddw mm3, mm2
368    movq mm2, [ebx + 768 + ecx*8 + 8]    movq mm2, [TMP0 + 768 + _EBX*8 + 8]
369    pmulhw mm3, mm2    pmulhw mm3, mm2
370    psrlw mm0, 2                  ; mm0 >>= 1   (/2)    psrlw mm0, 2                  ; mm0 >>= 1   (/2)
371    psrlw mm3, 2                  ;    psrlw mm3, 2                  ;
# Line 406  Line 375 
375    pxor mm3, mm4                 ;    pxor mm3, mm4                 ;
376    psubw mm0, mm1                ; undisplace    psubw mm0, mm1                ; undisplace
377    psubw mm3, mm4    psubw mm3, mm4
378    movq [edi + 8*ecx], mm0    movq [TMP1 + 8*_EBX], mm0
379    movq [edi + 8*ecx + 8], mm3    movq [TMP1 + 8*_EBX + 8], mm3
380    
381    add ecx, 2    add _EBX, 2
382    cmp ecx, 16    cmp _EBX, 16
383    jnz near .q2loop    jnz near .q2loop
384    
385    jmp .done    jmp .done
# Line 439  Line 408 
408    ; The original loop is:    ; The original loop is:
409    ;    ;
410  %if 0  %if 0
411    movq mm0, [ecx+8*eax + 8*16]   ; mm0 = coeff[i]    movq mm0, [TMP0+8*_EAX + 8*16]   ; mm0 = coeff[i]
412    pxor mm1, mm1    pxor mm1, mm1
413    pcmpgtw mm1, mm0    pcmpgtw mm1, mm0
414    pxor mm0, mm1     ; change sign if negative    pxor mm0, mm1     ; change sign if negative
415    psubw mm0, mm1    ; -> mm0 = abs(coeff[i]), mm1 = sign of coeff[i]    psubw mm0, mm1    ; -> mm0 = abs(coeff[i]), mm1 = sign of coeff[i]
416    
417    movq mm2, mm7     ; mm2 = quant    movq mm2, mm7     ; mm2 = quant
418    pmullw mm2, [ebx + 8*eax + 8*16 ]  ; matrix[i]*quant.    pmullw mm2, [_EBX + 8*_EAX + 8*16 ]  ; matrix[i]*quant.
419    
420    movq mm6, mm2    movq mm6, mm2
421    pmulhw mm2, mm0   ; high of coeff*(matrix*quant)  (should be 0 if no overflow)    pmulhw mm2, mm0   ; high of coeff*(matrix*quant)  (should be 0 if no overflow)
# Line 460  Line 429 
429    por mm0, mm2      ; saturate to 2047 if needed    por mm0, mm2      ; saturate to 2047 if needed
430    pxor mm0, mm1     ; finish negating back    pxor mm0, mm1     ; finish negating back
431    
432    movq [edx + 8*eax + 8*16], mm0   ; data[i]    movq [TMP1 + 8*_EAX + 8*16], mm0   ; data[i]
433    add eax, 1    add _EAX, 1
434  %endif  %endif
435    
436    ;********************************************************************    ;********************************************************************
437    
438  ALIGN 16  ALIGN SECTION_ALIGN
439  dequant_mpeg_intra_mmx:  dequant_mpeg_intra_mmx:
440    
441    push ebx    mov TMP1, prm1  ; data
442      mov TMP0, prm2  ; coeff
443    mov edx, [esp + 4 + 4]  ; data    mov _EAX, prm5  ; mpeg_quant_matrices
444    mov ecx, [esp + 4 + 8]  ; coeff  
445    mov eax, [esp + 4 + 12] ; quant    push _EBX
446    mov ebx, [esp + 4 + 20] ; mpeg_quant_matrices    mov _EBX, _EAX
447    %ifdef ARCH_IS_X86_64
448      mov _EAX, prm3
449      lea prm1, [mmx_mul_quant]
450      movq mm7, [prm1 + _EAX*8 - 8]
451    %else
452      mov _EAX, [_ESP + 4 + 12] ; quant
453      movq mm7, [mmx_mul_quant  + _EAX*8 - 8]
454    %endif
455    
456    movq mm7, [mmx_mul_quant  + eax*8 - 8]    mov _EAX, -16      ; to keep ALIGNed, we regularly process coeff[0]
   mov eax, -16      ; to keep ALIGNed, we regularly process coeff[0]  
457    psllw mm7, 2      ; << 2. See comment.    psllw mm7, 2      ; << 2. See comment.
458    pxor mm6, mm6     ; this is a NOP    pxor mm6, mm6     ; this is a NOP
459    
460  ALIGN 16  ALIGN SECTION_ALIGN
461  .loop:  .loop:
462    movq mm0, [ecx+8*eax + 8*16]   ; mm0 = c  = coeff[i]    movq mm0, [TMP0+8*_EAX + 8*16]   ; mm0 = c  = coeff[i]
463    movq mm3, [ecx+8*eax + 8*16 +8]; mm3 = c' = coeff[i+1]    movq mm3, [TMP0+8*_EAX + 8*16 +8]; mm3 = c' = coeff[i+1]
464    pxor mm1, mm1    pxor mm1, mm1
465    pxor mm4, mm4    pxor mm4, mm4
466    pcmpgtw mm1, mm0  ; mm1 = sgn(c)    pcmpgtw mm1, mm0  ; mm1 = sgn(c)
467    movq mm2, mm7     ; mm2 = quant    movq mm2, mm7     ; mm2 = quant
468    
469    pcmpgtw mm4, mm3  ; mm4 = sgn(c')    pcmpgtw mm4, mm3  ; mm4 = sgn(c')
470    pmullw mm2,  [ebx + 8*eax + 8*16 ]  ; matrix[i]*quant    pmullw mm2,  [_EBX + 8*_EAX + 8*16 ]  ; matrix[i]*quant
471    
472    pxor mm0, mm1     ; negate if negative    pxor mm0, mm1     ; negate if negative
473    pxor mm3, mm4     ; negate if negative    pxor mm3, mm4     ; negate if negative
# Line 507  Line 483 
483    pmulhw mm0, mm5   ; high of coeff*(matrix*quant)    pmulhw mm0, mm5   ; high of coeff*(matrix*quant)
484    movq mm5, mm7     ; mm2 = quant    movq mm5, mm7     ; mm2 = quant
485    
486    pmullw mm5,  [ebx + 8*eax + 8*16 +8]  ; matrix[i+1]*quant    pmullw mm5,  [_EBX + 8*_EAX + 8*16 +8]  ; matrix[i+1]*quant
487    
488    movq mm6, mm5    movq mm6, mm5
489    add eax,2   ; z-flag will be tested later    add _EAX,2   ; z-flag will be tested later
490    
491    pmullw mm6, mm3   ; low  of coeff*(matrix*quant)    pmullw mm6, mm3   ; low  of coeff*(matrix*quant)
492    pmulhw mm3, mm5   ; high of coeff*(matrix*quant)    pmulhw mm3, mm5   ; high of coeff*(matrix*quant)
# Line 532  Line 508 
508    psubw mm2, mm1 ; finish negating back    psubw mm2, mm1 ; finish negating back
509    psubw mm6, mm4 ; finish negating back    psubw mm6, mm4 ; finish negating back
510    
511    movq [edx + 8*eax + 8*16   -2*8   ], mm2   ; data[i]    movq [TMP1 + 8*_EAX + 8*16   -2*8   ], mm2   ; data[i]
512    movq [edx + 8*eax + 8*16   -2*8 +8], mm6   ; data[i+1]    movq [TMP1 + 8*_EAX + 8*16   -2*8 +8], mm6   ; data[i+1]
513    
514   jnz        near .loop   jnz        near .loop
515    
516      pop _EBX
517    
518      ; deal with DC      ; deal with DC
519    movd mm0, [ecx]    movd mm0, [TMP0]
520    pmullw mm0, [esp + 4 + 16]  ; dcscalar  %ifdef ARCH_IS_X86_64
521      movq mm6, prm4
522      pmullw mm0, mm6
523    %else
524      pmullw mm0, prm4  ; dcscalar
525    %endif
526    movq mm2, [mmx_32767_minus_2047]    movq mm2, [mmx_32767_minus_2047]
527    paddsw mm0, mm2    paddsw mm0, mm2
528    psubsw mm0, mm2    psubsw mm0, mm2
# Line 547  Line 530 
530    psubsw mm0, mm2    psubsw mm0, mm2
531    paddsw mm0, mm2    paddsw mm0, mm2
532    movd eax, mm0    movd eax, mm0
533    mov [edx], ax    mov [TMP1], ax
534    
535    xor eax, eax    xor _EAX, _EAX
   
   pop ebx  
536    
537    ret    ret
538  ENDFUNC  ENDFUNC
# Line 570  Line 551 
551      ; sgn(x) is the result of 'pcmpgtw 0,x':  0 if x>=0, -1 if x<0.      ; sgn(x) is the result of 'pcmpgtw 0,x':  0 if x>=0, -1 if x<0.
552      ; It's mixed with the extraction of the absolute value.      ; It's mixed with the extraction of the absolute value.
553    
554  ALIGN 16  ALIGN SECTION_ALIGN
555  dequant_mpeg_inter_mmx:  dequant_mpeg_inter_mmx:
556    
   push ebx  
557    
558    mov edx, [esp + 4 + 4]        ; data    mov TMP1, prm1        ; data
559    mov ecx, [esp + 4 + 8]        ; coeff    mov TMP0, prm2        ; coeff
560    mov eax, [esp + 4 + 12]        ; quant    mov _EAX, prm3        ; quant
561    mov ebx, [esp + 4 + 16]                  ; mpeg_quant_matrices  
562      push _EBX
563    %ifdef ARCH_IS_X86_64
564      mov _EBX, prm4
565      lea r9, [mmx_mul_quant]
566      movq mm7, [r9 + _EAX*8 - 8]
567    %else
568      mov _EBX, [_ESP + 4 + 16]     ; mpeg_quant_matrices
569      movq mm7, [mmx_mul_quant  + _EAX*8 - 8]
570    %endif
571    
572    movq mm7, [mmx_mul_quant  + eax*8 - 8]    mov _EAX, -16
   mov eax, -16  
573    paddw mm7, mm7    ; << 1    paddw mm7, mm7    ; << 1
574    pxor mm6, mm6     ; mismatch sum    pxor mm6, mm6     ; mismatch sum
575    
576  ALIGN 16  ALIGN SECTION_ALIGN
577  .loop:  .loop:
578    movq mm0, [ecx+8*eax + 8*16   ]   ; mm0 = coeff[i]    movq mm0, [TMP0+8*_EAX + 8*16   ]   ; mm0 = coeff[i]
579    movq mm2, [ecx+8*eax + 8*16 +8]   ; mm2 = coeff[i+1]    movq mm2, [TMP0+8*_EAX + 8*16 +8]   ; mm2 = coeff[i+1]
580    add eax, 2    add _EAX, 2
581    
582    pxor mm1, mm1    pxor mm1, mm1
583    pxor mm3, mm3    pxor mm3, mm3
# Line 614  Line 602 
602      ; we're short on register, here. Poor pairing...      ; we're short on register, here. Poor pairing...
603    
604    movq mm4, mm7     ; (matrix*quant)    movq mm4, mm7     ; (matrix*quant)
605    pmullw mm4,  [ebx + 512 + 8*eax + 8*16 -2*8]    pmullw mm4,  [_EBX + 512 + 8*_EAX + 8*16 -2*8]
606    movq mm5, mm4    movq mm5, mm4
607    pmulhw mm5, mm0   ; high of c*(matrix*quant)    pmulhw mm5, mm0   ; high of c*(matrix*quant)
608    pmullw mm0, mm4   ; low  of c*(matrix*quant)    pmullw mm0, mm4   ; low  of c*(matrix*quant)
609    
610    movq mm4, mm7     ; (matrix*quant)    movq mm4, mm7     ; (matrix*quant)
611    pmullw mm4,  [ebx + 512 + 8*eax + 8*16 -2*8 + 8]    pmullw mm4,  [_EBX + 512 + 8*_EAX + 8*16 -2*8 + 8]
612    
613    pcmpgtw mm5, [zero]    pcmpgtw mm5, [zero]
614    paddusw mm0, mm5    paddusw mm0, mm5
# Line 641  Line 629 
629    psubw mm2, mm3    ; finish restoring sign    psubw mm2, mm3    ; finish restoring sign
630    
631    pxor mm6, mm0     ; mismatch control    pxor mm6, mm0     ; mismatch control
632    movq [edx + 8*eax + 8*16 -2*8   ], mm0   ; data[i]    movq [TMP1 + 8*_EAX + 8*16 -2*8   ], mm0   ; data[i]
633    pxor mm6, mm2     ; mismatch control    pxor mm6, mm2     ; mismatch control
634    movq [edx + 8*eax + 8*16 -2*8 +8], mm2   ; data[i+1]    movq [TMP1 + 8*_EAX + 8*16 -2*8 +8], mm2   ; data[i+1]
635    
636    jnz near .loop    jnz near .loop
637    
# Line 659  Line 647 
647    pxor mm6, mm1    pxor mm6, mm1
648    pxor mm6, mm2    pxor mm6, mm2
649    movd eax, mm6    movd eax, mm6
650    and eax, 1    and _EAX, 1
651    xor eax, 1    xor _EAX, 1
652    xor word [edx + 2*63], ax    xor word [TMP1 + 2*63], ax
653    
654    xor eax, eax    xor _EAX, _EAX
655    
656    pop ebx    pop _EBX
657    
658    ret    ret
659  ENDFUNC  ENDFUNC
660    
661    NON_EXEC_STACK
 %ifidn __OUTPUT_FORMAT__,elf  
 section ".note.GNU-stack" noalloc noexec nowrite progbits  
 %endif  
   

Legend:
Removed from v.1.10  
changed lines
  Added in v.1.16

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