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

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

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

revision 1382, Mon Mar 22 22:36:25 2004 UTC revision 1798, Wed Nov 26 02:21:02 2008 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 21  Line 21 
21  ; *  along with this program ; if not, write to the Free Software  ; *  along with this program ; if not, write to the Free Software
22  ; *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA  ; *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23  ; *  ; *
24  ; * $Id: quantize_mpeg_mmx.asm,v 1.2 2004-03-22 22:36:24 edgomez Exp $  ; * $Id: quantize_mpeg_mmx.asm,v 1.12 2008-11-26 02:21:02 Isibaar Exp $
25  ; *  ; *
26  ; *************************************************************************/  ; *************************************************************************/
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 data  
 %else  
 SECTION .rodata data 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  SECTION .rotext align=SECTION_ALIGN
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    movq mm5, [quantd + eax * 8 - 8] ; quantd -> mm5    QUANT_MMX(4)
185      QUANT_MMX(5)
186    xor ecx, ecx    QUANT_MMX(6)
187    cmp al, 1    QUANT_MMX(7)
188    jz near .q1loop  
189      ; calculate DC
190    cmp al, 2    movsx _EAX, word [_EAX]   ; data[0]
191    jz near .q2loop    mov TMP0, prm4            ; dcscalar
192      mov _EDX, _EAX
193    movq mm7, [mmx_div + eax * 8 - 8] ; multipliers[quant] -> mm7    shr TMP0, 1               ; TMP0 = dcscalar/2
194      sar _EDX, 31              ; TMP1 = sign extend of _EAX (ready for division too)
195  ALIGN 16    xor TMP0, _EDX            ; adjust TMP0 according to the sign of data[0]
196  .loop    sub TMP0, _EDX
197    movq mm0, [esi + 8*ecx]       ; mm0 = [1st]    add _EAX, TMP0
   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  
198    
199    add ecx,2    mov TMP0, prm4            ; dcscalar
200    cmp ecx,16    idiv TMP0                 ; _EAX = _EDX:_EAX / dcscalar
   jnz near .loop  
201    
202  .done    mov _EDX, prm1            ; coeff again
203    ; caclulate  data[0] // (int32_t)dcscalar)    mov word [_EDX], ax       ; coeff[0] = ax
   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  
204    
205    xor eax, eax              ; return(0);    xor _EAX, _EAX            ; return(0);
206    ret    ret
207    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  
208    
209    
210  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
# Line 324  Line 216 
216  ;  ;
217  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
218    
219  ALIGN 16  ALIGN SECTION_ALIGN
220  quant_mpeg_inter_mmx:  quant_mpeg_inter_mmx:
221    
222    push ecx    mov TMP1, prm1           ; coeff
223    push esi    mov _EAX, prm3           ; quant
224    push edi    mov TMP0, prm4           ; mpeg_quant_matrices
225    push ebx  
226      push _ESI
227    mov edi, [esp + 16 + 4]       ; coeff  %ifdef ARCH_IS_X86_64
228    mov esi, [esp + 16 + 8]       ; data    mov _ESI, prm2           ; data
229    mov eax, [esp + 16 + 12]  ; quant  %else
230    mov ebx, [esp + 16 + 16]              ; mpeg_quant_matrices    mov _ESI, [_ESP + 4 + 8] ; data
231    %endif
232    
233    xor ecx, ecx    push _EBX
234      xor _EBX, _EBX
235    
236    pxor mm5, mm5                 ; sum    pxor mm5, mm5                 ; sum
237    
# Line 347  Line 241 
241    cmp al, 2    cmp al, 2
242    jz near .q2loop    jz near .q2loop
243    
244    movq mm7, [mmx_div + eax * 8 - 8] ; divider  %ifdef ARCH_IS_X86_64
245      lea r9, [mmx_div]
246      movq mm7, [r9 + _EAX * 8 - 8]
247    %else
248      movq mm7, [mmx_div + _EAX * 8 - 8] ; divider
249    %endif
250    
251  ALIGN 16  ALIGN SECTION_ALIGN
252  .loop  .loop:
253    movq mm0, [esi + 8*ecx]       ; mm0 = [1st]    movq mm0, [_ESI + 8*_EBX]       ; mm0 = [1st]
254    movq mm3, [esi + 8*ecx + 8]   ;    movq mm3, [_ESI + 8*_EBX + 8]   ;
255    pxor mm1, mm1                 ; mm1 = 0    pxor mm1, mm1                 ; mm1 = 0
256    pxor mm4, mm4                 ;    pxor mm4, mm4                 ;
257    pcmpgtw mm1, mm0              ; mm1 = (0 > mm0)    pcmpgtw mm1, mm0              ; mm1 = (0 > mm0)
# Line 363  Line 262 
262    psubw mm3, mm4                ;    psubw mm3, mm4                ;
263    psllw mm0, 4    psllw mm0, 4
264    psllw mm3, 4    psllw mm3, 4
265    movq mm2, [ebx + 512 + 8*ecx]    movq mm2, [TMP0 + 512 + 8*_EBX]
266    psrlw mm2, 1    psrlw mm2, 1
267    paddw mm0, mm2    paddw mm0, mm2
268    movq mm2, [ebx + 768 + ecx*8]    movq mm2, [TMP0 + 768 + _EBX*8]
269    pmulhw mm0, mm2               ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]    pmulhw mm0, mm2               ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
270    movq mm2, [ebx + 512 + 8*ecx + 8]    movq mm2, [TMP0 + 512 + 8*_EBX + 8]
271    psrlw mm2, 1    psrlw mm2, 1
272    paddw mm3, mm2    paddw mm3, mm2
273    movq mm2, [ebx + 768 + ecx*8 + 8]    movq mm2, [TMP0 + 768 + _EBX*8 + 8]
274    pmulhw mm3, mm2    pmulhw mm3, mm2
275    pmulhw mm0, mm7               ; mm0 = (mm0 / 2Q) >> 16    pmulhw mm0, mm7               ; mm0 = (mm0 / 2Q) >> 16
276    pmulhw mm3, mm7               ;    pmulhw mm3, mm7               ;
# Line 383  Line 282 
282    pxor mm3, mm4                 ;    pxor mm3, mm4                 ;
283    psubw mm0, mm1                ; undisplace    psubw mm0, mm1                ; undisplace
284    psubw mm3, mm4    psubw mm3, mm4
285    movq [edi + 8*ecx], mm0    movq [TMP1 + 8*_EBX], mm0
286    movq [edi + 8*ecx + 8], mm3    movq [TMP1 + 8*_EBX + 8], mm3
287    
288    add ecx, 2    add _EBX, 2
289    cmp ecx, 16    cmp _EBX, 16
290    jnz near .loop    jnz near .loop
291    
292  .done  .done:
293    pmaddwd mm5, [mmx_one]    pmaddwd mm5, [mmx_one]
294    movq mm0, mm5    movq mm0, mm5
295    psrlq mm5, 32    psrlq mm5, 32
296    paddd mm0, mm5    paddd mm0, mm5
297    movd eax, mm0                 ; return sum    movd eax, mm0                 ; return sum
298    
299    pop ebx    pop _EBX
300    pop edi    pop _ESI
   pop esi  
   pop ecx  
301    
302    ret    ret
303    
304  ALIGN 16  ALIGN SECTION_ALIGN
305  .q1loop  .q1loop:
306    movq mm0, [esi + 8*ecx]       ; mm0 = [1st]    movq mm0, [_ESI + 8*_EBX]       ; mm0 = [1st]
307    movq mm3, [esi + 8*ecx+ 8]    movq mm3, [_ESI + 8*_EBX+ 8]
308    pxor mm1, mm1                 ; mm1 = 0    pxor mm1, mm1                 ; mm1 = 0
309    pxor mm4, mm4                 ;    pxor mm4, mm4                 ;
310    pcmpgtw mm1, mm0              ; mm1 = (0 > mm0)    pcmpgtw mm1, mm0              ; mm1 = (0 > mm0)
# Line 418  Line 315 
315    psubw mm3, mm4                ;    psubw mm3, mm4                ;
316    psllw mm0, 4    psllw mm0, 4
317    psllw mm3, 4    psllw mm3, 4
318    movq mm2, [ebx + 512 + 8*ecx]    movq mm2, [TMP0 + 512 + 8*_EBX]
319    psrlw mm2, 1    psrlw mm2, 1
320    paddw mm0, mm2    paddw mm0, mm2
321    movq mm2, [ebx + 768 + ecx*8]    movq mm2, [TMP0 + 768 + _EBX*8]
322    pmulhw mm0, mm2               ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]    pmulhw mm0, mm2               ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
323    movq mm2, [ebx + 512 + 8*ecx + 8]    movq mm2, [TMP0 + 512 + 8*_EBX + 8]
324    psrlw mm2, 1    psrlw mm2, 1
325    paddw mm3, mm2    paddw mm3, mm2
326    movq mm2, [ebx + 768 + ecx*8 + 8]    movq mm2, [TMP0 + 768 + _EBX*8 + 8]
327    pmulhw mm3, mm2    pmulhw mm3, mm2
328    psrlw mm0, 1                  ; mm0 >>= 1   (/2)    psrlw mm0, 1                  ; mm0 >>= 1   (/2)
329    psrlw mm3, 1                  ;    psrlw mm3, 1                  ;
# Line 436  Line 333 
333    pxor mm3, mm4                 ;    pxor mm3, mm4                 ;
334    psubw mm0, mm1                ; undisplace    psubw mm0, mm1                ; undisplace
335    psubw mm3, mm4    psubw mm3, mm4
336    movq [edi + 8*ecx], mm0    movq [TMP1 + 8*_EBX], mm0
337    movq [edi + 8*ecx + 8], mm3    movq [TMP1 + 8*_EBX + 8], mm3
338    
339    add ecx, 2    add _EBX, 2
340    cmp ecx, 16    cmp _EBX, 16
341    jnz near .q1loop    jnz near .q1loop
342    
343    jmp .done    jmp .done
344    
345    ALIGN SECTION_ALIGN
346  ALIGN 16  .q2loop:
347  .q2loop    movq mm0, [_ESI + 8*_EBX]       ; mm0 = [1st]
348    movq mm0, [esi + 8*ecx]       ; mm0 = [1st]    movq mm3, [_ESI + 8*_EBX+ 8]
   movq mm3, [esi + 8*ecx+ 8]  
349    pxor mm1, mm1                 ; mm1 = 0    pxor mm1, mm1                 ; mm1 = 0
350    pxor mm4, mm4                 ;    pxor mm4, mm4                 ;
351    pcmpgtw mm1, mm0              ; mm1 = (0 > mm0)    pcmpgtw mm1, mm0              ; mm1 = (0 > mm0)
# Line 460  Line 356 
356    psubw mm3, mm4                ;    psubw mm3, mm4                ;
357    psllw mm0, 4    psllw mm0, 4
358    psllw mm3, 4    psllw mm3, 4
359    movq mm2, [ebx + 512 + 8*ecx]    movq mm2, [TMP0 + 512 + 8*_EBX]
360    psrlw mm2, 1    psrlw mm2, 1
361    paddw mm0, mm2    paddw mm0, mm2
362    movq mm2, [ebx + 768 + ecx*8]    movq mm2, [TMP0 + 768 + _EBX*8]
363    pmulhw mm0, mm2               ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]    pmulhw mm0, mm2               ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
364    movq mm2, [ebx + 512 + 8*ecx + 8]    movq mm2, [TMP0 + 512 + 8*_EBX + 8]
365    psrlw mm2, 1    psrlw mm2, 1
366    paddw mm3, mm2    paddw mm3, mm2
367    movq mm2, [ebx + 768 + ecx*8 + 8]    movq mm2, [TMP0 + 768 + _EBX*8 + 8]
368    pmulhw mm3, mm2    pmulhw mm3, mm2
369    psrlw mm0, 2                  ; mm0 >>= 1   (/2)    psrlw mm0, 2                  ; mm0 >>= 1   (/2)
370    psrlw mm3, 2                  ;    psrlw mm3, 2                  ;
# Line 478  Line 374 
374    pxor mm3, mm4                 ;    pxor mm3, mm4                 ;
375    psubw mm0, mm1                ; undisplace    psubw mm0, mm1                ; undisplace
376    psubw mm3, mm4    psubw mm3, mm4
377    movq [edi + 8*ecx], mm0    movq [TMP1 + 8*_EBX], mm0
378    movq [edi + 8*ecx + 8], mm3    movq [TMP1 + 8*_EBX + 8], mm3
379    
380    add ecx, 2    add _EBX, 2
381    cmp ecx, 16    cmp _EBX, 16
382    jnz near .q2loop    jnz near .q2loop
383    
384    jmp .done    jmp .done
385    ENDFUNC
386    
387    
388  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
# Line 510  Line 407 
407    ; The original loop is:    ; The original loop is:
408    ;    ;
409  %if 0  %if 0
410    movq mm0, [ecx+8*eax + 8*16]   ; mm0 = coeff[i]    movq mm0, [TMP0+8*_EAX + 8*16]   ; mm0 = coeff[i]
411    pxor mm1, mm1    pxor mm1, mm1
412    pcmpgtw mm1, mm0    pcmpgtw mm1, mm0
413    pxor mm0, mm1     ; change sign if negative    pxor mm0, mm1     ; change sign if negative
414    psubw mm0, mm1    ; -> mm0 = abs(coeff[i]), mm1 = sign of coeff[i]    psubw mm0, mm1    ; -> mm0 = abs(coeff[i]), mm1 = sign of coeff[i]
415    
416    movq mm2, mm7     ; mm2 = quant    movq mm2, mm7     ; mm2 = quant
417    pmullw mm2, [ebx + 8*eax + 8*16 ]  ; matrix[i]*quant.    pmullw mm2, [_EBX + 8*_EAX + 8*16 ]  ; matrix[i]*quant.
418    
419    movq mm6, mm2    movq mm6, mm2
420    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 428 
428    por mm0, mm2      ; saturate to 2047 if needed    por mm0, mm2      ; saturate to 2047 if needed
429    pxor mm0, mm1     ; finish negating back    pxor mm0, mm1     ; finish negating back
430    
431    movq [edx + 8*eax + 8*16], mm0   ; data[i]    movq [TMP1 + 8*_EAX + 8*16], mm0   ; data[i]
432    add eax, 1    add _EAX, 1
433  %endif  %endif
434    
435    ;********************************************************************    ;********************************************************************
436    
437  ALIGN 16  ALIGN SECTION_ALIGN
438  dequant_mpeg_intra_mmx:  dequant_mpeg_intra_mmx:
439    
440    push ebx    mov TMP1, prm1  ; data
441      mov TMP0, prm2  ; coeff
442    mov edx, [esp + 4 + 4]  ; data    mov _EAX, prm5  ; mpeg_quant_matrices
443    mov ecx, [esp + 4 + 8]  ; coeff  
444    mov eax, [esp + 4 + 12] ; quant    push _EBX
445    mov ebx, [esp + 4 + 20] ; mpeg_quant_matrices    mov _EBX, _EAX
446    %ifdef ARCH_IS_X86_64
447      mov _EAX, prm3
448      lea r9, [mmx_mul_quant]
449      movq mm7, [r9 + _EAX*8 - 8]
450    %else
451      mov _EAX, [_ESP + 4 + 12] ; quant
452      movq mm7, [mmx_mul_quant  + _EAX*8 - 8]
453    %endif
454    
455    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]  
456    psllw mm7, 2      ; << 2. See comment.    psllw mm7, 2      ; << 2. See comment.
457    pxor mm6, mm6     ; this is a NOP    pxor mm6, mm6     ; this is a NOP
458    
459  ALIGN 16  ALIGN SECTION_ALIGN
460  .loop  .loop:
461    movq mm0, [ecx+8*eax + 8*16]   ; mm0 = c  = coeff[i]    movq mm0, [TMP0+8*_EAX + 8*16]   ; mm0 = c  = coeff[i]
462    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]
463    pxor mm1, mm1    pxor mm1, mm1
464    pxor mm4, mm4    pxor mm4, mm4
465    pcmpgtw mm1, mm0  ; mm1 = sgn(c)    pcmpgtw mm1, mm0  ; mm1 = sgn(c)
466    movq mm2, mm7     ; mm2 = quant    movq mm2, mm7     ; mm2 = quant
467    
468    pcmpgtw mm4, mm3  ; mm4 = sgn(c')    pcmpgtw mm4, mm3  ; mm4 = sgn(c')
469    pmullw mm2,  [ebx + 8*eax + 8*16 ]  ; matrix[i]*quant    pmullw mm2,  [_EBX + 8*_EAX + 8*16 ]  ; matrix[i]*quant
470    
471    pxor mm0, mm1     ; negate if negative    pxor mm0, mm1     ; negate if negative
472    pxor mm3, mm4     ; negate if negative    pxor mm3, mm4     ; negate if negative
# Line 578  Line 482 
482    pmulhw mm0, mm5   ; high of coeff*(matrix*quant)    pmulhw mm0, mm5   ; high of coeff*(matrix*quant)
483    movq mm5, mm7     ; mm2 = quant    movq mm5, mm7     ; mm2 = quant
484    
485    pmullw mm5,  [ebx + 8*eax + 8*16 +8]  ; matrix[i+1]*quant    pmullw mm5,  [_EBX + 8*_EAX + 8*16 +8]  ; matrix[i+1]*quant
486    
487    movq mm6, mm5    movq mm6, mm5
488    add eax,2   ; z-flag will be tested later    add _EAX,2   ; z-flag will be tested later
489    
490    pmullw mm6, mm3   ; low  of coeff*(matrix*quant)    pmullw mm6, mm3   ; low  of coeff*(matrix*quant)
491    pmulhw mm3, mm5   ; high of coeff*(matrix*quant)    pmulhw mm3, mm5   ; high of coeff*(matrix*quant)
# Line 603  Line 507 
507    psubw mm2, mm1 ; finish negating back    psubw mm2, mm1 ; finish negating back
508    psubw mm6, mm4 ; finish negating back    psubw mm6, mm4 ; finish negating back
509    
510    movq [edx + 8*eax + 8*16   -2*8   ], mm2   ; data[i]    movq [TMP1 + 8*_EAX + 8*16   -2*8   ], mm2   ; data[i]
511    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]
512    
513   jnz        near .loop   jnz        near .loop
514    
515      pop _EBX
516    
517      ; deal with DC      ; deal with DC
518    movd mm0, [ecx]    movd mm0, [TMP0]
519    pmullw mm0, [esp + 4 + 16]  ; dcscalar  %ifdef ARCH_IS_X86_64
520      movq mm6, prm4
521      pmullw mm0, mm6
522    %else
523      pmullw mm0, prm4  ; dcscalar
524    %endif
525    movq mm2, [mmx_32767_minus_2047]    movq mm2, [mmx_32767_minus_2047]
526    paddsw mm0, mm2    paddsw mm0, mm2
527    psubsw mm0, mm2    psubsw mm0, mm2
# Line 618  Line 529 
529    psubsw mm0, mm2    psubsw mm0, mm2
530    paddsw mm0, mm2    paddsw mm0, mm2
531    movd eax, mm0    movd eax, mm0
532    mov [edx], ax    mov [TMP1], ax
533    
534    xor eax, eax    xor _EAX, _EAX
   
   pop ebx  
535    
536    ret    ret
537    ENDFUNC
538    
539  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
540  ;  ;
# Line 640  Line 550 
550      ; 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.
551      ; It's mixed with the extraction of the absolute value.      ; It's mixed with the extraction of the absolute value.
552    
553  ALIGN 16  ALIGN SECTION_ALIGN
554  dequant_mpeg_inter_mmx:  dequant_mpeg_inter_mmx:
555    
   push ebx  
556    
557    mov edx, [esp + 4 + 4]        ; data    mov TMP1, prm1        ; data
558    mov ecx, [esp + 4 + 8]        ; coeff    mov TMP0, prm2        ; coeff
559    mov eax, [esp + 4 + 12]        ; quant    mov _EAX, prm3        ; quant
560    mov ebx, [esp + 4 + 16]                  ; mpeg_quant_matrices  
561      push _EBX
562    %ifdef ARCH_IS_X86_64
563      mov _EBX, prm4
564      lea r9, [mmx_mul_quant]
565      movq mm7, [r9 + _EAX*8 - 8]
566    %else
567      mov _EBX, [_ESP + 4 + 16]     ; mpeg_quant_matrices
568      movq mm7, [mmx_mul_quant  + _EAX*8 - 8]
569    %endif
570    
571    movq mm7, [mmx_mul_quant  + eax*8 - 8]    mov _EAX, -16
   mov eax, -16  
572    paddw mm7, mm7    ; << 1    paddw mm7, mm7    ; << 1
573    pxor mm6, mm6     ; mismatch sum    pxor mm6, mm6     ; mismatch sum
574    
575  ALIGN 16  ALIGN SECTION_ALIGN
576  .loop  .loop:
577    movq mm0, [ecx+8*eax + 8*16   ]   ; mm0 = coeff[i]    movq mm0, [TMP0+8*_EAX + 8*16   ]   ; mm0 = coeff[i]
578    movq mm2, [ecx+8*eax + 8*16 +8]   ; mm2 = coeff[i+1]    movq mm2, [TMP0+8*_EAX + 8*16 +8]   ; mm2 = coeff[i+1]
579    add eax, 2    add _EAX, 2
580    
581    pxor mm1, mm1    pxor mm1, mm1
582    pxor mm3, mm3    pxor mm3, mm3
# Line 684  Line 601 
601      ; we're short on register, here. Poor pairing...      ; we're short on register, here. Poor pairing...
602    
603    movq mm4, mm7     ; (matrix*quant)    movq mm4, mm7     ; (matrix*quant)
604    pmullw mm4,  [ebx + 512 + 8*eax + 8*16 -2*8]    pmullw mm4,  [_EBX + 512 + 8*_EAX + 8*16 -2*8]
605    movq mm5, mm4    movq mm5, mm4
606    pmulhw mm5, mm0   ; high of c*(matrix*quant)    pmulhw mm5, mm0   ; high of c*(matrix*quant)
607    pmullw mm0, mm4   ; low  of c*(matrix*quant)    pmullw mm0, mm4   ; low  of c*(matrix*quant)
608    
609    movq mm4, mm7     ; (matrix*quant)    movq mm4, mm7     ; (matrix*quant)
610    pmullw mm4,  [ebx + 512 + 8*eax + 8*16 -2*8 + 8]    pmullw mm4,  [_EBX + 512 + 8*_EAX + 8*16 -2*8 + 8]
611    
612    pcmpgtw mm5, [zero]    pcmpgtw mm5, [zero]
613    paddusw mm0, mm5    paddusw mm0, mm5
# Line 711  Line 628 
628    psubw mm2, mm3    ; finish restoring sign    psubw mm2, mm3    ; finish restoring sign
629    
630    pxor mm6, mm0     ; mismatch control    pxor mm6, mm0     ; mismatch control
631    movq [edx + 8*eax + 8*16 -2*8   ], mm0   ; data[i]    movq [TMP1 + 8*_EAX + 8*16 -2*8   ], mm0   ; data[i]
632    pxor mm6, mm2     ; mismatch control    pxor mm6, mm2     ; mismatch control
633    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]
634    
635    jnz near .loop    jnz near .loop
636    
# Line 729  Line 646 
646    pxor mm6, mm1    pxor mm6, mm1
647    pxor mm6, mm2    pxor mm6, mm2
648    movd eax, mm6    movd eax, mm6
649    and eax, 1    and _EAX, 1
650    xor eax, 1    xor _EAX, 1
651    xor word [edx + 2*63], ax    xor word [TMP1 + 2*63], ax
652    
653    xor eax, eax    xor _EAX, _EAX
654    
655    pop ebx    pop _EBX
656    
657    ret    ret
658    ENDFUNC
659    
660    
661    %ifidn __OUTPUT_FORMAT__,elf
662    section ".note.GNU-stack" noalloc noexec nowrite progbits
663    %endif
664    

Legend:
Removed from v.1382  
changed lines
  Added in v.1798

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