[svn] / branches / dev-api-4 / xvidcore / src / quant / x86_asm / quantize_mpeg_xmm.asm Repository:
ViewVC logotype

Diff of /branches/dev-api-4/xvidcore/src/quant/x86_asm/quantize_mpeg_xmm.asm

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

revision 1174, Tue Oct 7 13:02:35 2003 UTC revision 1230, Sun Nov 30 16:13:16 2003 UTC
# Line 1  Line 1 
1  ;/**************************************************************************  ;/****************************************************************************
2  ; *  ; *
3  ; *  XVID MPEG-4 VIDEO CODEC  ; *  XVID MPEG-4 VIDEO CODEC
4  ; *  - mmx quantization/dequantization -  ; *  - 3dne Quantization/Dequantization -
5  ; *  ; *
6  ; *  Copyright(C) 2001-2003 XviD Team <xvid-devel@xvid.org>  ; *  Copyright (C) 2002-2003 Peter Ross <pross@xvid.org>
7    ; *                2002      Jaan Kalda
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 19  Line 20 
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA  ; *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
22  ; *  ; *
23  ; * $Id: quantize_mpeg_xmm.asm,v 1.1.2.1 2003-10-07 13:02:35 edgomez Exp $  ; * $Id: quantize_mpeg_xmm.asm,v 1.1.2.5 2003-11-30 16:13:16 edgomez Exp $
24  ; *  ; *
25  ; *************************************************************************/  ; ***************************************************************************/
26  ;/**************************************************************************  
 ; *   quant4 bugs have been fixed: (a) overflow bug for matrix elements  
 ; *   equal to 1 or 2 is fixed by substituting pmulhw with pmulhuw (iSSE)  
 ; *   and using multiplier 0ffffh instead of 10001h (for matrix element = 1;  
 ; *   in that case, 1 is added before multiplying, that additional 1 comes  
 ; *   from intra_matrix1; (b) rounding error for large coefficients and matrix  
 ; *   elements is fixed by two-step approach: first approximation (rounded  
 ; *   down) is found as usual; the result is multiplied by the matrix element  
 ; *   and mismatch is used to calculate the correction.  
 ; *************************************************************************/  
27  ; _3dne functions are compatible with iSSE, but are optimized specifically  ; _3dne functions are compatible with iSSE, but are optimized specifically
28  ; for K7 pipelines  ; for K7 pipelines
 ;  
 ;---------------------------------------------------------------------------  
 ; 09.12.2002  Athlon optimizations contributed by Jaan Kalda  
 ;---------------------------------------------------------------------------  
   
29    
 ; data/text alignment  
 %define ALIGN 8  
30  %define SATURATE  %define SATURATE
31    
32  bits 32  BITS 32
   
 %ifdef FORMAT_COFF  
 SECTION .data data  
 %else  
 SECTION .data data align=8  
 %endif  
33    
34  %macro cglobal 1  %macro cglobal 1
35          %ifdef PREFIX          %ifdef PREFIX
# Line 69  Line 48 
48                  extern %1                  extern %1
49          %endif          %endif
50  %endmacro  %endmacro
 align 8  
 mmzero dd 0,0  
51    
52  mmx_one times 4 dw       1  ;=============================================================================
53    ; Local data
54    ;=============================================================================
55    
56  ;===========================================================================  %ifdef FORMAT_COFF
57  ;  SECTION .rodata data
58    %else
59    SECTION .rodata data align=16
60    %endif
61    
62    ALIGN 8
63    mmzero:
64            dd 0,0
65    mmx_one:
66            times 4 dw 1
67    
68    ;-----------------------------------------------------------------------------
69  ; divide by 2Q table  ; divide by 2Q table
70  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
71    
72  align ALIGN  ALIGN 16
73  mmx_divs            ;i>2  mmx_divs:               ;i>2
74  %assign i 1  %assign i 1
75  %rep 31  %rep 31
76          times 4 dw  ((1 << 15) / i + 1)          times 4 dw  ((1 << 15) / i + 1)
77          %assign i i+1          %assign i i+1
78  %endrep  %endrep
79    
80  align ALIGN  ALIGN 16
81  mmx_div            ;i>2  mmx_div:                ;quant>2
82  %assign i 1          times 4 dw 65535 ; the div by 2 formula will overflow for the case
83                             ; quant=1 but we don't care much because quant=1
84                             ; is handled by a different piece of code that
85                             ; doesn't use this table.
86    %assign quant 2
87  %rep 31  %rep 31
88          times 4 dw  ((1 << 16) / i + 1)          times 4 dw  ((1 << 16) / quant + 1)
89          %assign i i+1          %assign quant quant+1
90  %endrep  %endrep
91    
   
 ;===========================================================================  
 ;  
 ; intra matrix  
 ;  
 ;===========================================================================  
   
92  %macro FIXX 1  %macro FIXX 1
93  dw (1 << 16) / (%1) + 1  dw (1 << 16) / (%1) + 1
94  %endmacro  %endmacro
95    
 cextern intra_matrix_fixl  
 cextern intra_matrix_fix  
 cextern intra_matrix1  
 cextern intra_matrix  
   
 ;===========================================================================  
 ;  
 ; inter matrix  
 ;  
 ;===========================================================================  
   
 cextern inter_matrix1  
 cextern inter_matrix  
 cextern inter_matrix_fix  
 cextern inter_matrix_fixl  
   
   
 %define VM18P   3  
 %define VM18Q   4  
96  %define nop4    db      08Dh,074h,026h,0  %define nop4    db      08Dh,074h,026h,0
97  %define nop3    add     esp,byte 0  %define nop3    add     esp,byte 0
98  %define nop2    mov     esp,esp  %define nop2    mov     esp,esp
99  %define nop7    db      08dh,02ch,02dh,0,0,0,0  %define nop7    db      08dh,02ch,02dh,0,0,0,0
100  %define nop6    add     ebp,dword 0  %define nop6    add     ebp,dword 0
101    
102  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
103  ; quantd table  ; quantd table
104  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
105    
106    %define VM18P   3
107    %define VM18Q   4
108    
109  quantd  ALIGN 16
110    quantd:
111  %assign i 1  %assign i 1
112  %rep 31  %rep 31
113          times 4 dw  (((VM18P*i) + (VM18Q/2)) / VM18Q)          times 4 dw  (((VM18P*i) + (VM18Q/2)) / VM18Q)
114          %assign i i+1          %assign i i+1
115  %endrep  %endrep
116    
117  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
118  ; multiple by 2Q table  ; multiple by 2Q table
119  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
120    
121    ALIGN 16
122  mmx_mul_quant  mmx_mul_quant:
123  %assign i 1  %assign i 1
124  %rep 31  %rep 31
125          times 4 dw  i          times 4 dw  i
126          %assign i i+1          %assign i i+1
127  %endrep  %endrep
128    
129  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
130  ; saturation limits  ; saturation limits
131  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
   
 align 16  
132    
133  mmx_32767_minus_2047            times 4 dw (32767-2047)  ALIGN 16
134  mmx_32768_minus_2048            times 4 dw (32768-2048)  mmx_32767_minus_2047:
135  mmx_2047                        times 4 dw 2047          times 4 dw (32767-2047)
136  mmx_minus_2048                  times 4 dw (-2048)  mmx_32768_minus_2048:
137  zero                            times 4 dw 0          times 4 dw (32768-2048)
138    mmx_2047:
139            times 4 dw 2047
140    mmx_minus_2048:
141            times 4 dw (-2048)
142    zero:
143            times 4 dw 0
144    
145  int_div  int_div:
146  dd 0  dd 0
147  %assign i 1  %assign i 1
148  %rep 255  %rep 255
# Line 182  Line 150 
150          %assign i i+1          %assign i i+1
151  %endrep  %endrep
152    
153  section .text  ;=============================================================================
154    ; Code
155    ;=============================================================================
156    
157    SECTION .text
158    
159  ;===========================================================================  cglobal quant_mpeg_intra_xmm
160    cglobal quant_mpeg_inter_xmm
161    cglobal dequant_mpeg_intra_3dne
162    cglobal dequant_mpeg_inter_3dne
163    
164    ;-----------------------------------------------------------------------------
165  ;  ;
166  ; void quant4_intra_xmm(int16_t * coeff,  ; uint32_t quant_mpeg_intra_xmm(int16_t * coeff,
167  ;                                       const int16_t const * data,  ;                                       const int16_t const * data,
168  ;                                       const uint32_t quant,  ;                                       const uint32_t quant,
169  ;                                       const uint32_t dcscalar);  ;                               const uint32_t dcscalar,
170    ;                               const uint16_t *mpeg_matrices);
171  ;  ;
172  ;===========================================================================  ;-----------------------------------------------------------------------------
173    
174  align ALIGN  ALIGN 16
 cglobal quant_mpeg_intra_xmm  
175  quant_mpeg_intra_xmm:  quant_mpeg_intra_xmm:
176          mov     eax, [esp  + 8]         ; data          mov     eax, [esp  + 8]         ; data
177          mov     ecx, [esp  + 12]        ; quant          mov     ecx, [esp  + 12]        ; quant
# Line 203  Line 180 
180          push    edi          push    edi
181          push    ebx          push    ebx
182          nop          nop
183          mov     edi,mmzero    mov edi, [esp + 12 + 20]              ; mpeg_quant_matrices
184          mov     esi,-14          mov     esi,-14
185          pxor    mm0,mm0          pxor    mm0,mm0
186          pxor    mm3,mm3          pxor    mm3,mm3
# Line 213  Line 190 
190          jg      near .lloop          jg      near .lloop
191          nop6          nop6
192    
193    ALIGN 16
 align ALIGN  
194  .loop  .loop
195          movq    mm1, [eax + 8*esi+112]          ; mm0 = [1st]          movq    mm1, [eax + 8*esi+112]          ; mm0 = [1st]
196          psubw   mm0, mm1                        ;-mm1          psubw   mm0, mm1                        ;-mm1
# Line 227  Line 203 
203          psraw   mm4, 15          psraw   mm4, 15
204          psllw   mm0, 4  ;level << 4 ;          psllw   mm0, 4  ;level << 4 ;
205          psllw   mm3, 4          psllw   mm3, 4
206          paddw   mm0, [intra_matrix1 + 8*esi+112]    paddw mm0, [edi + 128 + 8*esi+112]
207          paddw   mm3, [intra_matrix1 + 8*esi+120]    paddw mm3, [edi + 128 + 8*esi+120]
208          movq    mm5, [intra_matrix_fixl + 8*esi+112]    movq mm5, [edi + 384 + 8*esi+112]
209          movq    mm7, [intra_matrix_fixl + 8*esi+120]    movq mm7, [edi + 384 + 8*esi+120]
210          pmulhuw mm5, mm0          pmulhuw mm5, mm0
211          pmulhuw mm7, mm3          pmulhuw mm7, mm3
212          mov     esp, esp          mov     esp, esp
213          movq    mm2, [intra_matrix + 8*esi+112]    movq mm2, [edi + 8*esi+112]
214          movq    mm6, [intra_matrix + 8*esi+120]    movq mm6, [edi + 8*esi+120]
215          pmullw  mm2, mm5          pmullw  mm2, mm5
216          pmullw  mm6, mm7          pmullw  mm6, mm7
217          psubw   mm0, mm2          psubw   mm0, mm2
# Line 246  Line 222 
222          paddw   mm5, mm2          paddw   mm5, mm2
223          paddw   mm7, mm2          paddw   mm7, mm2
224          mov     esp, esp          mov     esp, esp
225          pmulhuw mm0, [intra_matrix_fix + 8*esi+112]    pmulhuw mm0, [edi + 256 + 8*esi+112]
226          pmulhuw mm3, [intra_matrix_fix + 8*esi+120]    pmulhuw mm3, [edi + 256 + 8*esi+120]
227          paddw   mm5, mm0          paddw   mm5, mm0
228          paddw   mm7, mm3          paddw   mm7, mm3
229          movq    mm0, [edi]    pxor mm0, mm0
230          movq    mm3, [edi]    pxor mm3, mm3
231          pmulhuw mm5, mm6                ; mm0 = (mm0 / 2Q) >> 16          pmulhuw mm5, mm6                ; mm0 = (mm0 / 2Q) >> 16
232          pmulhuw mm7, mm6                ;  (level + quantd) / quant (0<quant<32)          pmulhuw mm7, mm6                ;  (level + quantd) / quant (0<quant<32)
233          pxor    mm5, mm1                ; mm0 *= sign(mm0)          pxor    mm5, mm1                ; mm0 *= sign(mm0)
# Line 288  Line 264 
264          add     esp, byte 12          add     esp, byte 12
265          mov     [edx], cx               ; coeff[0] = ax          mov     [edx], cx               ; coeff[0] = ax
266    
267      xor eax, eax
268          ret          ret
269    
270  align ALIGN  ALIGN 16
271  .q1loop  .q1loop
272          movq    mm1, [eax + 8*esi+112]                  ; mm0 = [1st]          movq    mm1, [eax + 8*esi+112]                  ; mm0 = [1st]
273          psubw   mm0, mm1                                ;-mm1          psubw   mm0, mm1                                ;-mm1
# Line 303  Line 280 
280          psraw   mm4, 15          psraw   mm4, 15
281          psllw   mm0, 4                                  ; level << 4          psllw   mm0, 4                                  ; level << 4
282          psllw   mm3, 4          psllw   mm3, 4
283          paddw   mm0, [intra_matrix1 + 8*esi+112]        ;mm0 is to be divided    paddw mm0, [edi + 128 + 8*esi+112]    ;mm0 is to be divided
284          paddw   mm3, [intra_matrix1 + 8*esi+120]        ;intra1 contains fix for division by 1    paddw mm3, [edi + 128 + 8*esi+120]    ;intra1 contains fix for division by 1
285          movq    mm5, [intra_matrix_fixl + 8*esi+112]    ;with rounding down    movq mm5, [edi + 384 + 8*esi+112] ;with rounding down
286          movq    mm7, [intra_matrix_fixl + 8*esi+120]    movq mm7, [edi + 384 + 8*esi+120]
287          pmulhuw mm5, mm0          pmulhuw mm5, mm0
288          pmulhuw mm7, mm3                                ;mm7: first approx of division          pmulhuw mm7, mm3                                ;mm7: first approx of division
289          mov     esp, esp          mov     esp, esp
290          movq    mm2, [intra_matrix + 8*esi+112]    movq mm2, [edi + 8*esi+112]
291          movq    mm6, [intra_matrix + 8*esi+120]         ; divs for q<=16    movq mm6, [edi + 8*esi+120]      ; divs for q<=16
292          pmullw  mm2, mm5                                ;test value <= original          pmullw  mm2, mm5                                ;test value <= original
293          pmullw  mm6, mm7          pmullw  mm6, mm7
294          psubw   mm0, mm2                                ;mismatch          psubw   mm0, mm2                                ;mismatch
# Line 321  Line 298 
298          paddw   mm5, mm2                                ;first approx with quantd          paddw   mm5, mm2                                ;first approx with quantd
299          paddw   mm7, mm2          paddw   mm7, mm2
300          mov     esp, esp          mov     esp, esp
301          pmulhuw mm0, [intra_matrix_fix + 8*esi+112]     ;correction    pmulhuw mm0, [edi + 256 + 8*esi+112]   ;correction
302          pmulhuw mm3, [intra_matrix_fix + 8*esi+120]    pmulhuw mm3, [edi + 256 + 8*esi+120]
303          paddw   mm5, mm0                                ;final result with quantd          paddw   mm5, mm0                                ;final result with quantd
304          paddw   mm7, mm3          paddw   mm7, mm3
305          movq    mm0, [edi]    pxor mm0, mm0
306          movq    mm3, [edi]    pxor mm3, mm3
307          mov     esp, esp          mov     esp, esp
308          psrlw   mm5, 1                  ;  (level + quantd) /2  (quant = 1)          psrlw   mm5, 1                  ;  (level + quantd) /2  (quant = 1)
309          psrlw   mm7, 1          psrlw   mm7, 1
# Line 340  Line 317 
317          jng     near .q1loop          jng     near .q1loop
318          jmp     near .done          jmp     near .done
319    
320  align 8  ALIGN 8
321  .lloop  .lloop
322          movq    mm1, [eax + 8*esi+112]          ; mm0 = [1st]          movq    mm1, [eax + 8*esi+112]          ; mm0 = [1st]
323          psubw   mm0, mm1 ;-mm1          psubw   mm0, mm1 ;-mm1
324          movq    mm4, [eax + 8*esi+120]  ;    movq mm4, [eax + 8*esi+120]
325          psubw   mm3, mm4 ;-mm4          psubw   mm3, mm4 ;-mm4
326          pmaxsw  mm0, mm1 ;|src|          pmaxsw  mm0, mm1 ;|src|
327          pmaxsw  mm3, mm4          pmaxsw  mm3, mm4
# Line 353  Line 330 
330          psraw   mm4, 15          psraw   mm4, 15
331          psllw   mm0, 4                  ; level << 4          psllw   mm0, 4                  ; level << 4
332          psllw   mm3, 4                  ;          psllw   mm3, 4                  ;
333          paddw   mm0, [intra_matrix1 + 8*esi+112] ;mm0 is to be divided intra1 contains fix for division by 1    paddw mm0, [edi + 128 + 8*esi+112] ;mm0 is to be divided intra1 contains fix for division by 1
334          paddw   mm3, [intra_matrix1 + 8*esi+120]    paddw mm3, [edi + 128 + 8*esi+120]
335          movq    mm5, [intra_matrix_fixl + 8*esi+112]    movq mm5, [edi + 384 + 8*esi+112]
336          movq    mm7, [intra_matrix_fixl + 8*esi+120]    movq mm7, [edi + 384 + 8*esi+120]
337          pmulhuw mm5, mm0          pmulhuw mm5, mm0
338          pmulhuw mm7, mm3  ;mm7: first approx of division          pmulhuw mm7, mm3  ;mm7: first approx of division
339          mov     esp, esp          mov     esp, esp
340          movq    mm2, [intra_matrix + 8*esi+112]    movq mm2, [edi + 8*esi+112]
341          movq    mm6, [intra_matrix + 8*esi+120]    movq mm6, [edi + 8*esi+120]
342          pmullw  mm2, mm5 ;test value <= original          pmullw  mm2, mm5 ;test value <= original
343          pmullw  mm6, mm7          pmullw  mm6, mm7
344          psubw   mm0, mm2 ;mismatch          psubw   mm0, mm2 ;mismatch
# Line 372  Line 349 
349          paddw   mm5, mm2 ;first approx with quantd          paddw   mm5, mm2 ;first approx with quantd
350          paddw   mm7, mm2          paddw   mm7, mm2
351          mov     esp, esp          mov     esp, esp
352          pmulhuw mm0, [intra_matrix_fix + 8*esi+112] ;correction    pmulhuw mm0, [edi + 256 + 8*esi+112] ;correction
353          pmulhuw mm3, [intra_matrix_fix + 8*esi+120]    pmulhuw mm3, [edi + 256 + 8*esi+120]
354          paddw   mm5, mm0 ;final result with quantd          paddw   mm5, mm0 ;final result with quantd
355          paddw   mm7, mm3          paddw   mm7, mm3
356          movq    mm0, [edi]    pxor mm0, mm0
357          movq    mm3, [edi]    pxor mm3, mm3
358          mov     esp, esp          mov     esp, esp
359          pmulhuw mm5, mm6                ; mm0 = (mm0 / 2Q) >> 16          pmulhuw mm5, mm6                ; mm0 = (mm0 / 2Q) >> 16
360          pmulhuw mm7, mm6                ;  (level + quantd) / quant (0<quant<32)          pmulhuw mm7, mm6                ;  (level + quantd) / quant (0<quant<32)
# Line 393  Line 370 
370          jng     near .lloop          jng     near .lloop
371          jmp     near .done          jmp     near .done
372    
373  ;===========================================================================  ;-----------------------------------------------------------------------------
374  ;  ;
375  ; uint32_t quant4_inter_xmm(int16_t * coeff,  ; uint32_t quant_mpeg_inter_xmm(int16_t * coeff,
376  ;                                       const int16_t const * data,  ;                                       const int16_t const * data,
377  ;                                       const uint32_t quant);  ;                               const uint32_t quant,
378    ;                               const uint16_t *mpeg_matrices);
379  ;  ;
380  ;===========================================================================  ;-----------------------------------------------------------------------------
381    
382  align ALIGN  ALIGN 16
 cglobal quant_mpeg_inter_xmm  
383  quant_mpeg_inter_xmm:  quant_mpeg_inter_xmm:
384          mov     eax, [esp  + 8]         ; data          mov     eax, [esp  + 8]         ; data
385          mov     ecx, [esp  + 12]        ; quant          mov     ecx, [esp  + 12]        ; quant
# Line 411  Line 388 
388          push    edi          push    edi
389          push    ebx          push    ebx
390          nop          nop
391          mov edi,mmzero    mov edi, [esp + 12 + 16]
392          mov esi,-14          mov esi,-14
393          mov ebx,esp          mov ebx,esp
394          sub esp,byte 24          sub esp,byte 24
395          lea ebx,[esp+8]          lea ebx,[esp+8]
396          and ebx,byte -8 ;align 8    and ebx, byte -8 ;ALIGN 8
397          pxor mm0,mm0          pxor mm0,mm0
398          pxor mm3,mm3          pxor mm3,mm3
399          movq [byte ebx],mm0          movq [byte ebx],mm0
# Line 427  Line 404 
404          jg near .lloop          jg near .lloop
405          nop          nop
406    
407  align ALIGN  ALIGN 16
408  .loop  .loop
409          movq    mm1, [eax + 8*esi+112]          ; mm0 = [1st]          movq    mm1, [eax + 8*esi+112]          ; mm0 = [1st]
410          psubw   mm0,mm1 ;-mm1          psubw   mm0,mm1 ;-mm1
# Line 440  Line 417 
417          psraw   mm4,15          psraw   mm4,15
418          psllw   mm0, 4                  ; level << 4          psllw   mm0, 4                  ; level << 4
419          psllw   mm3, 4                  ;          psllw   mm3, 4                  ;
420          paddw   mm0, [inter_matrix1 + 8*esi+112]    paddw mm0, [edi + 640 + 8*esi+112]
421          paddw   mm3, [inter_matrix1 + 8*esi+120]    paddw mm3, [edi + 640 + 8*esi+120]
422          movq    mm5,[inter_matrix_fixl + 8*esi+112]    movq mm5, [edi + 896 + 8*esi+112]
423          movq    mm7,[inter_matrix_fixl + 8*esi+120]    movq mm7, [edi + 896 + 8*esi+120]
424          pmulhuw mm5,mm0          pmulhuw mm5,mm0
425          pmulhuw mm7,mm3          pmulhuw mm7,mm3
426          mov esp,esp          mov esp,esp
427          movq   mm2,[inter_matrix + 8*esi+112]    movq mm2, [edi + 512 + 8*esi+112]
428          movq   mm6,[inter_matrix + 8*esi+120]    movq mm6, [edi + 512 + 8*esi+120]
429          pmullw mm2,mm5          pmullw mm2,mm5
430          pmullw mm6,mm7          pmullw mm6,mm7
431          psubw mm0,mm2          psubw mm0,mm2
432          psubw mm3,mm6          psubw mm3,mm6
433          movq mm2,[byte ebx]          movq mm2,[byte ebx]
434          movq mm6,[mmx_divs + ecx * 8 - 8]          movq mm6,[mmx_divs + ecx * 8 - 8]
435          pmulhuw mm0,[inter_matrix_fix + 8*esi+112]    pmulhuw mm0, [edi + 768 + 8*esi+112]
436          pmulhuw mm3,[inter_matrix_fix + 8*esi+120]    pmulhuw mm3, [edi + 768 + 8*esi+120]
437          paddw mm2,[ebx+8]   ;sum          paddw mm2,[ebx+8]   ;sum
438          paddw mm5,mm0          paddw mm5,mm0
439          paddw mm7,mm3          paddw mm7,mm3
440          movq mm0,[edi]    pxor mm0, mm0
441          movq mm3,[edi]    pxor mm3, mm3
442          pmulhuw mm5, mm6                ; mm0 = (mm0 / 2Q) >> 16          pmulhuw mm5, mm6                ; mm0 = (mm0 / 2Q) >> 16
443          pmulhuw mm7, mm6                ;  (level ) / quant (0<quant<32)          pmulhuw mm7, mm6                ;  (level ) / quant (0<quant<32)
444          add esi,byte 2          add esi,byte 2
# Line 491  Line 468 
468    
469          ret          ret
470    
471  align ALIGN  ALIGN 16
472  .q1loop  .q1loop
473          movq    mm1, [eax + 8*esi+112]          ; mm0 = [1st]          movq    mm1, [eax + 8*esi+112]          ; mm0 = [1st]
474          psubw   mm0,mm1 ;-mm1          psubw   mm0,mm1 ;-mm1
475          movq    mm4, [eax + 8*esi+120]  ;    movq mm4, [eax + 8*esi+120]
476          psubw   mm3,mm4 ;-mm4          psubw   mm3,mm4 ;-mm4
477          pmaxsw  mm0,mm1 ;|src|          pmaxsw  mm0,mm1 ;|src|
478          pmaxsw  mm3,mm4          pmaxsw  mm3,mm4
# Line 504  Line 481 
481          psraw   mm4,15          psraw   mm4,15
482          psllw   mm0, 4                                                          ; level << 4          psllw   mm0, 4                                                          ; level << 4
483          psllw   mm3, 4          psllw   mm3, 4
484          paddw   mm0, [inter_matrix1 + 8*esi+112]        ;mm0 is to be divided    paddw mm0, [edi + 640 + 8*esi+112]    ;mm0 is to be divided
485          paddw   mm3, [inter_matrix1 + 8*esi+120]        ; inter1 contains fix for division by 1    paddw mm3, [edi + 640 + 8*esi+120]    ; inter1 contains fix for division by 1
486          movq    mm5,[inter_matrix_fixl + 8*esi+112] ;with rounding down    movq mm5, [edi + 896 + 8*esi+112] ;with rounding down
487          movq    mm7,[inter_matrix_fixl + 8*esi+120]    movq mm7, [edi + 896 + 8*esi+120]
488          pmulhuw mm5,mm0          pmulhuw mm5,mm0
489          pmulhuw mm7,mm3                                                         ;mm7: first approx of division          pmulhuw mm7,mm3                                                         ;mm7: first approx of division
490          mov esp,esp          mov esp,esp
491          movq   mm2,[inter_matrix + 8*esi+112]    movq mm2, [edi + 512 + 8*esi+112]
492          movq   mm6,[inter_matrix + 8*esi+120]           ; divs for q<=16    movq mm6, [edi + 512 + 8*esi+120]      ; divs for q<=16
493          pmullw mm2,mm5                                                          ;test value <= original          pmullw mm2,mm5                                                          ;test value <= original
494          pmullw mm6,mm7          pmullw mm6,mm7
495          psubw mm0,mm2                                                           ;mismatch          psubw mm0,mm2                                                           ;mismatch
496          psubw mm3,mm6          psubw mm3,mm6
497          movq mm2,[byte ebx]          movq mm2,[byte ebx]
498          pmulhuw mm0,[inter_matrix_fix + 8*esi+112]  ;correction    pmulhuw mm0, [edi + 768 + 8*esi+112]  ;correction
499          pmulhuw mm3,[inter_matrix_fix + 8*esi+120]    pmulhuw mm3, [edi + 768 + 8*esi+120]
500          paddw mm2,[ebx+8]   ;sum          paddw mm2,[ebx+8]   ;sum
501          paddw mm5,mm0                                                           ;final result          paddw mm5,mm0                                                           ;final result
502          paddw mm7,mm3          paddw mm7,mm3
503          movq mm0,[edi]    pxor mm0, mm0
504          movq mm3,[edi]    pxor mm3, mm3
505          psrlw   mm5, 1                  ;  (level ) /2  (quant = 1)          psrlw   mm5, 1                  ;  (level ) /2  (quant = 1)
506          psrlw   mm7, 1          psrlw   mm7, 1
507          add esi,byte 2          add esi,byte 2
# Line 540  Line 517 
517          jng     near .q1loop          jng     near .q1loop
518          jmp     near .done          jmp     near .done
519    
520  align 8  ALIGN 8
521  .lloop  .lloop
522          movq    mm1, [eax + 8*esi+112]          ; mm0 = [1st]          movq    mm1, [eax + 8*esi+112]          ; mm0 = [1st]
523          psubw   mm0,mm1 ;-mm1          psubw   mm0,mm1 ;-mm1
524          movq    mm4, [eax + 8*esi+120]  ;    movq mm4, [eax + 8*esi+120]
525          psubw   mm3,mm4 ;-mm4          psubw   mm3,mm4 ;-mm4
526          pmaxsw  mm0,mm1 ;|src|          pmaxsw  mm0,mm1 ;|src|
527          pmaxsw  mm3,mm4          pmaxsw  mm3,mm4
# Line 553  Line 530 
530          psraw   mm4,15          psraw   mm4,15
531          psllw   mm0, 4                  ; level << 4          psllw   mm0, 4                  ; level << 4
532          psllw   mm3, 4                  ;          psllw   mm3, 4                  ;
533          paddw   mm0, [inter_matrix1 + 8*esi+112] ;mm0 is to be divided inter1 contains fix for division by 1    paddw mm0, [edi + 640 + 8*esi+112] ;mm0 is to be divided inter1 contains fix for division by 1
534          paddw   mm3, [inter_matrix1 + 8*esi+120]    paddw mm3, [edi + 640 + 8*esi+120]
535          movq    mm5,[inter_matrix_fixl + 8*esi+112]    movq mm5,[edi + 896 + 8*esi+112]
536          movq    mm7,[inter_matrix_fixl + 8*esi+120]    movq mm7,[edi + 896 + 8*esi+120]
537          pmulhuw mm5,mm0          pmulhuw mm5,mm0
538          pmulhuw mm7,mm3  ;mm7: first approx of division          pmulhuw mm7,mm3  ;mm7: first approx of division
539          mov esp,esp          mov esp,esp
540          movq   mm2,[inter_matrix + 8*esi+112]    movq mm2,[edi + 512 + 8*esi+112]
541          movq   mm6,[inter_matrix + 8*esi+120]    movq mm6,[edi + 512 + 8*esi+120]
542          pmullw mm2,mm5 ;test value <= original          pmullw mm2,mm5 ;test value <= original
543          pmullw mm6,mm7          pmullw mm6,mm7
544          psubw mm0,mm2 ;mismatch          psubw mm0,mm2 ;mismatch
545          psubw mm3,mm6          psubw mm3,mm6
546          movq mm2,[byte ebx]          movq mm2,[byte ebx]
547          movq mm6,[mmx_div + ecx * 8 - 8] ; divs for q<=16          movq mm6,[mmx_div + ecx * 8 - 8] ; divs for q<=16
548          pmulhuw mm0,[inter_matrix_fix + 8*esi+112] ;correction    pmulhuw mm0,[edi + 768 + 8*esi+112] ;correction
549          pmulhuw mm3,[inter_matrix_fix + 8*esi+120]    pmulhuw mm3,[edi + 768 + 8*esi+120]
550          paddw mm2,[ebx+8]   ;sum          paddw mm2,[ebx+8]   ;sum
551          paddw mm5,mm0 ;final result          paddw mm5,mm0 ;final result
552          paddw mm7,mm3          paddw mm7,mm3
553          movq mm0,[edi]    pxor mm0,mm0
554          movq mm3,[edi]    pxor mm3,mm3
555          pmulhuw mm5, mm6                ; mm0 = (mm0 / 2Q) >> 16          pmulhuw mm5, mm6                ; mm0 = (mm0 / 2Q) >> 16
556          pmulhuw mm7, mm6                ;  (level ) / quant (0<quant<32)          pmulhuw mm7, mm6                ;  (level ) / quant (0<quant<32)
557          add esi,byte 2          add esi,byte 2
# Line 593  Line 570 
570          jmp     near .done          jmp     near .done
571    
572    
573  ;===========================================================================  ;-----------------------------------------------------------------------------
574  ;  ;
575  ; void dequant4_intra_mmx(int16_t *data,  ; uint32_t dequant_mpeg_intra_3dne(int16_t *data,
576  ;                    const int16_t const *coeff,  ;                    const int16_t const *coeff,
577  ;                    const uint32_t quant,  ;                    const uint32_t quant,
578  ;                    const uint32_t dcscalar);  ;                                  const uint32_t dcscalar,
579    ;                                  const uint16_t *mpeg_matrices);
580  ;  ;
581  ;===========================================================================  ;-----------------------------------------------------------------------------
582    
583    ;   Note: in order to saturate 'easily', we pre-shift the quantifier    ;   Note: in order to saturate 'easily', we pre-shift the quantifier
584    ; by 4. Then, the high-word of (coeff[]*matrix[i]*quant) are used to    ; by 4. Then, the high-word of (coeff[]*matrix[i]*quant) are used to
# Line 611  Line 589 
589    ; checked. Input ranges are: coeff in [-127,127], inter_matrix in [1..255],a    ; checked. Input ranges are: coeff in [-127,127], inter_matrix in [1..255],a
590    ; and quant in [1..31].    ; and quant in [1..31].
591    ;    ;
592    ;********************************************************************  
593  %macro DEQUANT4INTRAMMX 1  %macro DEQUANT4INTRAMMX 1
594          movq mm1, [byte ecx+ 16 * %1]   ; mm0 = c  = coeff[i]          movq mm1, [byte ecx+ 16 * %1]   ; mm0 = c  = coeff[i]
595          movq mm4, [ecx+ 16 * %1 +8]; mm3 = c' = coeff[i+1]          movq mm4, [ecx+ 16 * %1 +8]; mm3 = c' = coeff[i+1]
# Line 625  Line 603 
603          movq mm2,[eax+8]   ;preshifted quant          movq mm2,[eax+8]   ;preshifted quant
604          movq mm7,[eax+8]          movq mm7,[eax+8]
605  %endif  %endif
606          pmullw mm2,  [intra_matrix + 16 * %1 ]  ; matrix[i]*quant    pmullw mm2, [edi + 16 * %1 ]     ; matrix[i]*quant
607          pmullw mm7,  [intra_matrix + 16 * %1 +8]  ; matrix[i+1]*quant    pmullw mm7, [edi + 16 * %1 +8]   ; matrix[i+1]*quant
608          movq mm5,mm0          movq mm5,mm0
609          movq mm6,mm3          movq mm6,mm3
610          pmulhw mm0, mm2   ; high of coeff*(matrix*quant)          pmulhw mm0, mm2   ; high of coeff*(matrix*quant)
# Line 651  Line 629 
629          movq [edx + 16 * %1  +8], mm7   ; data[i+1]          movq [edx + 16 * %1  +8], mm7   ; data[i+1]
630  %endmacro  %endmacro
631    
632  align 16  ALIGN 16
 cglobal dequant_mpeg_intra_3dne  
633  dequant_mpeg_intra_3dne:  dequant_mpeg_intra_3dne:
634          mov eax, [esp+12] ; quant          mov eax, [esp+12] ; quant
635          mov ecx, [esp+8]  ; coeff          mov ecx, [esp+8]  ; coeff
# Line 666  Line 643 
643          push esi          push esi
644          lea eax,[esp-28]          lea eax,[esp-28]
645          sub esp,byte 32          sub esp,byte 32
646          and eax,byte -8 ;points to qword aligned space on stack    and eax, byte -8  ;points to qword ALIGNed space on stack
647          movq [eax],mm0          movq [eax],mm0
648          movq [eax+8],mm7          movq [eax+8],mm7
649          imul ebx,[esp+16+8+32]    ; dcscalar          imul ebx,[esp+16+8+32]    ; dcscalar
650          movq mm2,mm7          movq mm2,mm7
651      push edi
652      mov edi, [esp + 32 + 12 + 20] ; mpeg_quant_matrices
653  align 4  ALIGN 4
654    
655          DEQUANT4INTRAMMX 0          DEQUANT4INTRAMMX 0
656    
# Line 695  Line 672 
672    
673          DEQUANT4INTRAMMX 3          DEQUANT4INTRAMMX 3
674    
675          mov esi, [esp+32]    mov esi, [esp+36]
676          mov [byte edx], bx          mov [byte edx], bx
677          mov ebx, [esp+32+4]    mov ebx, [esp+36+4]
678    
679          DEQUANT4INTRAMMX 4          DEQUANT4INTRAMMX 4
680          DEQUANT4INTRAMMX 5          DEQUANT4INTRAMMX 5
681          DEQUANT4INTRAMMX 6          DEQUANT4INTRAMMX 6
682          DEQUANT4INTRAMMX 7          DEQUANT4INTRAMMX 7
683    
684      pop edi
685    
686          add esp, byte 32+8          add esp, byte 32+8
687    
688      xor eax, eax
689   ret   ret
690    
691  ;===========================================================================  ;-----------------------------------------------------------------------------
692  ;  ;
693  ; void dequant4_inter_3dne(int16_t * data,  ; uint32_t dequant_mpeg_inter_3dne(int16_t * data,
694  ;                    const int16_t * const coeff,  ;                    const int16_t * const coeff,
695  ;                    const uint32_t quant);  ;                                  const uint32_t quant,
696    ;                                  const uint16_t *mpeg_matrices);
697  ;  ;
698  ;===========================================================================  ;-----------------------------------------------------------------------------
699    
700      ; Note:  We use (2*c + sgn(c) - sgn(-c)) as multiplier      ; Note:  We use (2*c + sgn(c) - sgn(-c)) as multiplier
701      ; so we handle the 3 cases: c<0, c==0, and c>0 in one shot.      ; so we handle the 3 cases: c<0, c==0, and c>0 in one shot.
702      ; 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.
703      ; It's mixed with the extraction of the absolute value.      ; It's mixed with the extraction of the absolute value.
704    
705  align 16  ALIGN 16
 cglobal dequant_mpeg_inter_3dne  
706  dequant_mpeg_inter_3dne:  dequant_mpeg_inter_3dne:
707          mov    edx, [esp+ 4]        ; data          mov    edx, [esp+ 4]        ; data
708          mov    ecx, [esp+ 8]        ; coeff          mov    ecx, [esp+ 8]        ; coeff
# Line 732  Line 712 
712          paddw mm7, mm7    ; << 1          paddw mm7, mm7    ; << 1
713          pxor mm6, mm6 ; mismatch sum          pxor mm6, mm6 ; mismatch sum
714          push esi          push esi
715      push edi
716          mov esi,mmzero          mov esi,mmzero
717          pxor mm1,mm1          pxor mm1,mm1
718          pxor mm3,mm3          pxor mm3,mm3
719      mov edi, [esp + 8 + 16] ; mpeg_quant_matrices
720          nop          nop
721          nop4          nop4
722    
723  align 16  ALIGN 16
724  .loop  .loop
725          movq mm0, [ecx+8*eax + 7*16   ]   ; mm0 = coeff[i]          movq mm0, [ecx+8*eax + 7*16   ]   ; mm0 = coeff[i]
726          pcmpgtw mm1, mm0  ; mm1 = sgn(c)    (preserved)          pcmpgtw mm1, mm0  ; mm1 = sgn(c)    (preserved)
# Line 765  Line 747 
747    
748          movq mm4, mm7     ; (matrix*quant)          movq mm4, mm7     ; (matrix*quant)
749          nop          nop
750          pmullw mm4,  [inter_matrix + 8*eax + 7*16]    pmullw mm4, [edi + 512 + 8*eax + 7*16]
751          movq mm5, mm4          movq mm5, mm4
752          pmulhw mm5, mm0   ; high of c*(matrix*quant)          pmulhw mm5, mm0   ; high of c*(matrix*quant)
753          pmullw mm0, mm4   ; low  of c*(matrix*quant)          pmullw mm0, mm4   ; low  of c*(matrix*quant)
754    
755          movq mm4, mm7     ; (matrix*quant)          movq mm4, mm7     ; (matrix*quant)
756          pmullw mm4,  [inter_matrix + 8*eax + 7*16 + 8]    pmullw mm4, [edi + 512 + 8*eax + 7*16 + 8]
757          add eax,byte 2          add eax,byte 2
758    
759          pcmpgtw mm5, [esi]          pcmpgtw mm5, [esi]
# Line 810  Line 792 
792          pxor mm1, mm2          pxor mm1, mm2
793          pxor mm6, mm1          pxor mm6, mm1
794          movd eax, mm6          movd eax, mm6
795      pop edi
796          and eax,byte 1          and eax,byte 1
797          xor eax,byte 1          xor eax,byte 1
798          mov esi,[esp]          mov esi,[esp]
799          add esp,byte 4          add esp,byte 4
800          xor word [edx + 2*63], ax          xor word [edx + 2*63], ax
801    
802      xor eax, eax
803          ret          ret

Legend:
Removed from v.1174  
changed lines
  Added in v.1230

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