[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.2.2.1, Sat Jul 24 11:38:12 2004 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  
                 global _%1  
                 %define %1 _%1  
         %else  
                 global %1  
         %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 64  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 106  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 120  Line 98 
98          times 4 dw 0          times 4 dw 0
99    
100  ;=============================================================================  ;=============================================================================
101    ; rounding
102    ;=============================================================================
103    
104    ALIGN SECTION_ALIGN
105    
106    mmx_rounding:
107            dd (1<<13)
108            dd (1<<13)
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
118  cglobal dequant_mpeg_intra_mmx  cglobal dequant_mpeg_intra_mmx
119  cglobal dequant_mpeg_inter_mmx  cglobal dequant_mpeg_inter_mmx
120    
121    
122    %macro QUANT_MMX        1
123            movq    mm0, [_EAX + 16*(%1)]                   ; data
124            movq    mm2, [TMP0 + 16*(%1) + 128]             ; intra_matrix_rec
125            movq    mm4, [_EAX + 16*(%1) + 8]               ; data
126            movq    mm6, [TMP0 + 16*(%1) + 128 + 8] ; intra_matrix_rec
127    
128            movq    mm1, mm0
129            movq    mm5, mm4
130    
131            pmullw  mm0, mm2                                        ; low results
132            pmulhw  mm1, mm2                                        ; high results
133            pmullw  mm4, mm6                                        ; low results
134            pmulhw  mm5, mm6                                        ; high results
135    
136            movq    mm2, mm0
137            movq    mm6, mm4
138    
139            punpckhwd mm0, mm1
140            punpcklwd mm2, mm1
141            punpckhwd mm4, mm5
142            punpcklwd mm6, mm5
143    
144            paddd   mm2, mm7
145            paddd   mm0, mm7
146            paddd   mm6, mm7
147            paddd   mm4, mm7
148    
149            psrad   mm2, 14
150            psrad   mm0, 14
151            psrad   mm6, 14
152            psrad   mm4, 14
153    
154            packssdw mm2, mm0
155            packssdw mm6, mm4
156    
157            movq    [TMP1 + 16*(%1)], mm2
158            movq    [TMP1 + 16*(%1)+8], mm6
159    %endmacro
160    
161  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
162  ;  ;
163  ; uint32_t quant_mpeg_intra_mmx(int16_t * coeff,  ; uint32_t quant_mpeg_intra_mmx(int16_t * coeff,
# Line 140  Line 168 
168  ;  ;
169  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
170    
171  ALIGN 16  ALIGN SECTION_ALIGN
172  quant_mpeg_intra_mmx:  quant_mpeg_intra_mmx:
173    
174    push ecx    mov _EAX, prm2                ; data
175    push esi    mov TMP0, prm5                ; mpeg_quant_matrices
176    push edi    mov TMP1, prm1                ; coeff
177    push ebx  
178      movq mm7, [mmx_rounding]
179    mov edi, [esp + 16 + 4]       ; coeff  
180    mov esi, [esp + 16 + 8]       ; data    QUANT_MMX(0)
181    mov eax, [esp + 16 + 12]      ; quant    QUANT_MMX(1)
182    mov ebx, [esp + 16 + 20]              ; mpeg_quant_matrices    QUANT_MMX(2)
183      QUANT_MMX(3)
184      QUANT_MMX(4)
185      QUANT_MMX(5)
186      QUANT_MMX(6)
187      QUANT_MMX(7)
188    
189      ; calculate DC
190      movsx _EAX, word [_EAX]  ; data[0]
191      mov TMP0, prm4           ; dcscalar
192      mov _EDX, _EAX
193      shr TMP0, 1              ; TMP0 = dcscalar/2
194      sar _EDX, 31             ; TMP1 = sign extend of _EAX (ready for division too)
195    
196      xor TMP0, _EDX           ; adjust TMP0 according to the sign of data[0]
197      sub TMP0, _EDX
198      add _EAX, TMP0
199    
200    movq mm5, [quantd + eax * 8 - 8] ; quantd -> mm5    mov TMP0, prm4            ; dcscalar
201      idiv TMP0                 ; _EAX = _EDX:_EAX / dcscalar
202    
203    xor ecx, ecx    mov _EDX, prm1            ; coeff again
204    cmp al, 1    mov word [_EDX], ax       ; coeff[0] = ax
   jz near .q1loop  
205    
206    cmp al, 2    xor _EAX, _EAX            ; return(0);
   jz near .q2loop  
   
   movq mm7, [mmx_div + eax * 8 - 8] ; multipliers[quant] -> mm7  
   
 ALIGN 16  
 .loop  
   movq mm0, [esi + 8*ecx]       ; mm0 = [1st]  
   movq mm3, [esi + 8*ecx + 8]   ;  
   pxor mm1, mm1                 ; mm1 = 0  
   pxor mm4, mm4  
   pcmpgtw mm1, mm0              ; mm1 = (0 > mm0)  
   pcmpgtw mm4, mm3  
   pxor mm0, mm1                 ; mm0 = |mm0|  
   pxor mm3, mm4                 ;  
   psubw mm0, mm1                ; displace  
   psubw mm3, mm4                ;  
   psllw mm0, 4                  ; level << 4  
   psllw mm3, 4  
   movq mm2, [ebx + 8*ecx]  
   psrlw mm2, 1                  ; intra_matrix[i]>>1  
   paddw mm0, mm2  
   movq mm2, [ebx + 256 + ecx*8]  
   pmulhw mm0, mm2                       ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]  
   movq mm2, [ebx + 8*ecx + 8]  
   psrlw mm2, 1  
   paddw mm3, mm2  
   movq mm2, [ebx + 256 + ecx*8 + 8]  
   pmulhw mm3, mm2  
   paddw mm0, mm5                ; + quantd  
   paddw mm3, mm5  
   pmulhw mm0, mm7               ; mm0 = (mm0 / 2Q) >> 16  
   pmulhw mm3, mm7               ;  
   psrlw mm0, 1                  ; additional shift by 1 => 16 + 1 = 17  
   psrlw mm3, 1  
   pxor mm0, mm1                 ; mm0 *= sign(mm0)  
   pxor mm3, mm4                 ;  
   psubw mm0, mm1                ; undisplace  
   psubw mm3, mm4                ;  
   
   movq [edi + 8*ecx], mm0  
   movq [edi + 8*ecx + 8], mm3  
   
   add ecx,2  
   cmp ecx,16  
   jnz near .loop  
   
 .done  
   ; caclulate  data[0] // (int32_t)dcscalar)  
   mov ecx, [esp + 16 + 16]  ; dcscalar  
   mov edx, ecx  
   movsx eax, word [esi]     ; data[0]  
   shr edx, 1                ; edx = dcscalar /2  
   cmp eax, 0  
   jg .gtzero  
   
   sub eax, edx  
   jmp short .mul  
 .gtzero  
   add eax, edx  
 .mul  
   cdq                       ; expand eax -> edx:eax  
   idiv ecx                  ; eax = edx:eax / dcscalar  
   
   mov [edi], ax             ; coeff[0] = ax  
   
   pop ebx  
   pop edi  
   pop esi  
   pop ecx  
   
   xor eax, eax              ; return(0);  
207    ret    ret
208    ENDFUNC
 ALIGN 16  
 .q1loop  
   movq mm0, [esi + 8*ecx]       ; mm0 = [1st]  
   movq mm3, [esi + 8*ecx + 8]   ;  
   pxor mm1, mm1                 ; mm1 = 0  
   pxor mm4, mm4                 ;  
   pcmpgtw mm1, mm0              ; mm1 = (0 > mm0)  
   pcmpgtw mm4, mm3              ;  
   pxor mm0, mm1                 ; mm0 = |mm0|  
   pxor mm3, mm4                 ;  
   psubw mm0, mm1                ; displace  
   psubw mm3, mm4                ;  
   psllw mm0, 4  
   psllw mm3, 4  
   movq mm2, [ebx + 8*ecx]  
   psrlw mm2, 1  
   paddw mm0, mm2  
   movq mm2, [ebx + 256 + ecx*8]  
   pmulhw mm0, mm2                       ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]  
   movq mm2, [ebx + 8*ecx + 8]  
   psrlw mm2, 1  
   paddw mm3, mm2  
   movq mm2, [ebx + 256 + ecx*8 + 8]  
   pmulhw mm3, mm2  
   paddw mm0, mm5  
   paddw mm3, mm5  
   psrlw mm0, 1              ; mm0 >>= 1   (/2)  
   psrlw mm3, 1              ;  
   pxor mm0, mm1             ; mm0 *= sign(mm0)  
   pxor mm3, mm4             ;  
   psubw mm0, mm1            ; undisplace  
   psubw mm3, mm4            ;  
   movq [edi + 8*ecx], mm0  
   movq [edi + 8*ecx + 8], mm3  
   
   add ecx, 2  
   cmp ecx, 16  
   jnz near .q1loop  
   jmp near .done  
   
   
 ALIGN 16  
 .q2loop  
   movq mm0, [esi + 8*ecx]       ; mm0 = [1st]  
   movq mm3, [esi + 8*ecx + 8]   ;  
   pxor mm1, mm1                 ; mm1 = 0  
   pxor mm4, mm4                 ;  
   pcmpgtw mm1, mm0              ; mm1 = (0 > mm0)  
   pcmpgtw mm4, mm3              ;  
   pxor mm0, mm1                 ; mm0 = |mm0|  
   pxor mm3, mm4                 ;  
   psubw mm0, mm1                ; displace  
   psubw mm3, mm4                ;  
   psllw mm0, 4  
   psllw mm3, 4  
   movq mm2, [ebx + 8*ecx]  
   psrlw mm2, 1  
   paddw mm0, mm2  
   movq mm2, [ebx + 256 + ecx*8]  
   pmulhw mm0, mm2                       ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]  
   movq mm2, [ebx + 8*ecx + 8]  
   psrlw mm2, 1  
   paddw mm3, mm2  
   movq mm2, [ebx + 256 + ecx*8 + 8]  
   pmulhw mm3, mm2  
   paddw mm0, mm5  
   paddw mm3, mm5  
   psrlw mm0, 2                  ; mm0 >>= 1   (/4)  
   psrlw mm3, 2                  ;  
   pxor mm0, mm1                 ; mm0 *= sign(mm0)  
   pxor mm3, mm4                 ;  
   psubw mm0, mm1                ; undisplace  
   psubw mm3, mm4            ;  
   movq [edi + 8*ecx], mm0  
   movq [edi + 8*ecx + 8], mm3  
   
   add ecx,2  
   cmp ecx,16  
   jnz near .q2loop  
   jmp near .done  
209    
210    
211  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
# Line 324  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 347  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 363  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 383  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:
294    pmaddwd mm5, [mmx_one]    pmaddwd mm5, [mmx_one]
295    movq mm0, mm5    movq mm0, mm5
296    psrlq mm5, 32    psrlq mm5, 32
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 418  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 436  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 SECTION_ALIGN
347  ALIGN 16  .q2loop:
348  .q2loop    movq mm0, [_ESI + 8*_EBX]       ; mm0 = [1st]
349    movq mm0, [esi + 8*ecx]       ; mm0 = [1st]    movq mm3, [_ESI + 8*_EBX+ 8]
   movq mm3, [esi + 8*ecx+ 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 460  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 478  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
386    ENDFUNC
387    
388    
389  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
# Line 510  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 531  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 578  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 603  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 618  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
   
   xor eax, eax  
534    
535    pop ebx    xor _EAX, _EAX
536    
537    ret    ret
538    ENDFUNC
539    
540  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
541  ;  ;
# Line 640  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 684  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 711  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 729  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
660    
661    NON_EXEC_STACK

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

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