[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.1.2.2, Thu Oct 9 18:50:22 2003 UTC revision 1.5, Sun Aug 29 10:02:38 2004 UTC
# Line 25  Line 25 
25  ; *  ; *
26  ; *************************************************************************/  ; *************************************************************************/
27    
 ; data/text alignment  
 %define ALIGN 8  
   
28  %define SATURATE  %define SATURATE
29    
30  bits 32  BITS 32
31    
32  %macro cglobal 1  %macro cglobal 1
33          %ifdef PREFIX          %ifdef PREFIX
34                    %ifdef MARK_FUNCS
35                            global _%1:function %1.endfunc-%1
36                            %define %1 _%1:function %1.endfunc-%1
37                    %else
38                  global _%1                  global _%1
39                  %define %1 _%1                  %define %1 _%1
40                    %endif
41            %else
42                    %ifdef MARK_FUNCS
43                            global %1:function %1.endfunc-%1
44          %else          %else
45                  global %1                  global %1
46          %endif          %endif
47            %endif
48  %endmacro  %endmacro
49    
50  %macro cextern 1  %macro cextern 1
# Line 50  Line 56 
56          %endif          %endif
57  %endmacro  %endmacro
58    
59  ;***************************************************************************  ;=============================================================================
60  ; Local data  ; Local data (Read Only)
61  ;***************************************************************************  ;=============================================================================
62    
63  %ifdef FORMAT_COFF  %ifdef FORMAT_COFF
64  SECTION .data data  SECTION .rodata
65  %else  %else
66  SECTION .data data align=8  SECTION .rodata align=16
67  %endif  %endif
68    
69  mmx_one:  mmx_one:
70          times 4 dw       1          times 4 dw       1
71    
72  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
73  ; divide by 2Q table  ; divide by 2Q table
74  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
75    
76  align 16  ALIGN 16
77  mmx_div:  mmx_div:
78  %assign quant 1          times 4 dw 65535 ; the div by 2 formula will overflow for the case
79  %rep 31                           ; quant=1 but we don't care much because quant=1
80                             ; is handled by a different piece of code that
81                             ; doesn't use this table.
82    %assign quant 2
83    %rep 30
84          times 4 dw  (1<<17) / (quant*2) + 1          times 4 dw  (1<<17) / (quant*2) + 1
85          %assign quant quant+1          %assign quant quant+1
86  %endrep  %endrep
87    
 ;===========================================================================  
 ;  
 ; intra matrix  
 ;  
 ;===========================================================================  
   
 cextern intra_matrix  
 cextern intra_matrix_fix  
   
 ;===========================================================================  
 ;  
 ; inter matrix  
 ;  
 ;===========================================================================  
   
 cextern inter_matrix  
 cextern inter_matrix_fix  
   
   
88  %define VM18P 3  %define VM18P 3
89  %define VM18Q 4  %define VM18Q 4
90    
91    
92  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
93  ; quantd table  ; quantd table
94  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
95    
96  quantd:  quantd:
97  %assign quant 1  %assign quant 1
# Line 113  Line 100 
100          %assign quant quant+1          %assign quant quant+1
101  %endrep  %endrep
102    
103  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
104  ; multiple by 2Q table  ; multiple by 2Q table
105  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
106    
107  mmx_mul_quant:  mmx_mul_quant:
108  %assign quant 1  %assign quant 1
# Line 126  Line 111 
111          %assign quant quant+1          %assign quant quant+1
112  %endrep  %endrep
113    
114  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
115  ; saturation limits  ; saturation limits
116  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
117    
118  align 16  ALIGN 16
119    
120  mmx_32767_minus_2047:  mmx_32767_minus_2047:
121          times 4 dw (32767-2047)          times 4 dw (32767-2047)
# Line 145  Line 128 
128  zero:  zero:
129          times 4 dw 0          times 4 dw 0
130    
131  ;***************************************************************************  ;=============================================================================
132  ; Local data  ; Code
133  ;***************************************************************************  ;=============================================================================
134    
135    SECTION .text
136    
137  section .text  cglobal quant_mpeg_intra_mmx
138    cglobal quant_mpeg_inter_mmx
139    cglobal dequant_mpeg_intra_mmx
140    cglobal dequant_mpeg_inter_mmx
141    
142  ;===========================================================================  ;-----------------------------------------------------------------------------
143  ;  ;
144  ; uint32_t quant_mpeg_intra_mmx(int16_t * coeff,  ; uint32_t quant_mpeg_intra_mmx(int16_t * coeff,
145  ;                               const int16_t const * data,  ;                               const int16_t const * data,
146  ;                               const uint32_t quant,  ;                               const uint32_t quant,
147  ;                               const uint32_t dcscalar);  ;                               const uint32_t dcscalar,
148    ;                               const uint16_t *mpeg_matrices);
149  ;  ;
150  ;===========================================================================  ;-----------------------------------------------------------------------------
151    
152  align ALIGN  ALIGN 16
 cglobal quant_mpeg_intra_mmx  
153  quant_mpeg_intra_mmx:  quant_mpeg_intra_mmx:
154    
155          push    ecx          push    ecx
156          push    esi          push    esi
157          push    edi          push    edi
158      push ebx
159    
160          mov             edi, [esp + 12 + 4]             ; coeff    mov edi, [esp + 16 + 4]       ; coeff
161          mov             esi, [esp + 12 + 8]             ; data    mov esi, [esp + 16 + 8]       ; data
162          mov             eax, [esp + 12 + 12]    ; quant    mov eax, [esp + 16 + 12]      ; quant
163      mov ebx, [esp + 16 + 20]              ; mpeg_quant_matrices
164    
165          movq    mm5, [quantd + eax * 8 - 8] ; quantd -> mm5          movq    mm5, [quantd + eax * 8 - 8] ; quantd -> mm5
166    
# Line 183  Line 173 
173    
174          movq    mm7, [mmx_div + eax * 8 - 8] ; multipliers[quant] -> mm7          movq    mm7, [mmx_div + eax * 8 - 8] ; multipliers[quant] -> mm7
175    
176  align ALIGN  ALIGN 16
177  .loop  .loop
178          movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]          movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
179          movq    mm3, [esi + 8*ecx + 8]  ;          movq    mm3, [esi + 8*ecx + 8]  ;
   
180          pxor    mm1, mm1                ; mm1 = 0          pxor    mm1, mm1                ; mm1 = 0
181          pxor    mm4, mm4          pxor    mm4, mm4
   
182          pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)          pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
183          pcmpgtw mm4, mm3          pcmpgtw mm4, mm3
   
184          pxor    mm0, mm1                ; mm0 = |mm0|          pxor    mm0, mm1                ; mm0 = |mm0|
185          pxor    mm3, mm4                ;          pxor    mm3, mm4                ;
186          psubw   mm0, mm1                ; displace          psubw   mm0, mm1                ; displace
187          psubw   mm3, mm4                ;          psubw   mm3, mm4                ;
   
188          psllw   mm0, 4                  ; level << 4          psllw   mm0, 4                  ; level << 4
189          psllw   mm3, 4                  ;    psllw mm3, 4
190      movq mm2, [ebx + 8*ecx]
         movq    mm2, [intra_matrix + 8*ecx]  
191          psrlw   mm2, 1                  ; intra_matrix[i]>>1          psrlw   mm2, 1                  ; intra_matrix[i]>>1
192          paddw   mm0, mm2          paddw   mm0, mm2
193      movq mm2, [ebx + 256 + ecx*8]
         movq    mm2, [intra_matrix_fix + ecx*8]  
194          pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]          pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
195      movq mm2, [ebx + 8*ecx + 8]
         movq    mm2, [intra_matrix + 8*ecx + 8]  
196          psrlw   mm2, 1          psrlw   mm2, 1
197          paddw   mm3, mm2          paddw   mm3, mm2
198      movq mm2, [ebx + 256 + ecx*8 + 8]
         movq    mm2, [intra_matrix_fix + ecx*8 + 8]  
199          pmulhw  mm3, mm2          pmulhw  mm3, mm2
   
200          paddw   mm0, mm5                ; + quantd          paddw   mm0, mm5                ; + quantd
201          paddw   mm3, mm5          paddw   mm3, mm5
202          pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16          pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16
203          pmulhw  mm3, mm7                ;          pmulhw  mm3, mm7                ;
204          psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17          psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17
205          psrlw   mm3, 1          psrlw   mm3, 1
   
206          pxor    mm0, mm1                ; mm0 *= sign(mm0)          pxor    mm0, mm1                ; mm0 *= sign(mm0)
207          pxor    mm3, mm4                ;          pxor    mm3, mm4                ;
208          psubw   mm0, mm1                ; undisplace          psubw   mm0, mm1                ; undisplace
# Line 237  Line 217 
217    
218  .done  .done
219                  ; caclulate  data[0] // (int32_t)dcscalar)                  ; caclulate  data[0] // (int32_t)dcscalar)
220      mov ecx, [esp + 16 + 16]  ; dcscalar
         mov     ecx, [esp + 12 + 16]    ; dcscalar  
221          mov     edx, ecx          mov     edx, ecx
222          movsx   eax, word [esi] ; data[0]          movsx   eax, word [esi] ; data[0]
223          shr     edx, 1                  ; edx = dcscalar /2          shr     edx, 1                  ; edx = dcscalar /2
# Line 255  Line 234 
234    
235          mov     [edi], ax               ; coeff[0] = ax          mov     [edi], ax               ; coeff[0] = ax
236    
237      pop ebx
238          pop     edi          pop     edi
239          pop     esi          pop     esi
240          pop     ecx          pop     ecx
# Line 262  Line 242 
242          xor eax, eax                            ; return(0);          xor eax, eax                            ; return(0);
243          ret          ret
244    
245  align ALIGN  ALIGN 16
246  .q1loop  .q1loop
247          movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]          movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
248          movq    mm3, [esi + 8*ecx + 8]  ;          movq    mm3, [esi + 8*ecx + 8]  ;
   
249          pxor    mm1, mm1                ; mm1 = 0          pxor    mm1, mm1                ; mm1 = 0
250          pxor    mm4, mm4                ;          pxor    mm4, mm4                ;
   
251          pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)          pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
252          pcmpgtw mm4, mm3                ;          pcmpgtw mm4, mm3                ;
   
253          pxor    mm0, mm1                ; mm0 = |mm0|          pxor    mm0, mm1                ; mm0 = |mm0|
254          pxor    mm3, mm4                ;          pxor    mm3, mm4                ;
255          psubw   mm0, mm1                ; displace          psubw   mm0, mm1                ; displace
256          psubw   mm3, mm4                ;          psubw   mm3, mm4                ;
   
257          psllw   mm0, 4          psllw   mm0, 4
258          psllw   mm3, 4          psllw   mm3, 4
259      movq mm2, [ebx + 8*ecx]
         movq    mm2, [intra_matrix + 8*ecx]  
260          psrlw   mm2, 1          psrlw   mm2, 1
261          paddw   mm0, mm2          paddw   mm0, mm2
262      movq mm2, [ebx + 256 + ecx*8]
         movq    mm2, [intra_matrix_fix + ecx*8]  
263          pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]          pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
264      movq mm2, [ebx + 8*ecx + 8]
         movq    mm2, [intra_matrix + 8*ecx + 8]  
265          psrlw   mm2, 1          psrlw   mm2, 1
266          paddw   mm3, mm2          paddw   mm3, mm2
267      movq mm2, [ebx + 256 + ecx*8 + 8]
         movq    mm2, [intra_matrix_fix + ecx*8 + 8]  
268          pmulhw  mm3, mm2          pmulhw  mm3, mm2
   
269          paddw   mm0, mm5          paddw   mm0, mm5
270          paddw   mm3, mm5          paddw   mm3, mm5
   
271          psrlw   mm0, 1                  ; mm0 >>= 1   (/2)          psrlw   mm0, 1                  ; mm0 >>= 1   (/2)
272          psrlw   mm3, 1                  ;          psrlw   mm3, 1                  ;
   
273          pxor    mm0, mm1                ; mm0 *= sign(mm0)          pxor    mm0, mm1                ; mm0 *= sign(mm0)
274          pxor    mm3, mm4        ;          pxor    mm3, mm4        ;
275          psubw   mm0, mm1                ; undisplace          psubw   mm0, mm1                ; undisplace
276          psubw   mm3, mm4                ;          psubw   mm3, mm4                ;
   
277          movq    [edi + 8*ecx], mm0          movq    [edi + 8*ecx], mm0
278          movq    [edi + 8*ecx + 8], mm3          movq    [edi + 8*ecx + 8], mm3
279    
# Line 315  Line 283 
283          jmp             near .done          jmp             near .done
284    
285    
286  align ALIGN  ALIGN 16
287  .q2loop  .q2loop
288          movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]          movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
289          movq    mm3, [esi + 8*ecx + 8]  ;          movq    mm3, [esi + 8*ecx + 8]  ;
   
290          pxor    mm1, mm1                ; mm1 = 0          pxor    mm1, mm1                ; mm1 = 0
291          pxor    mm4, mm4                ;          pxor    mm4, mm4                ;
   
292          pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)          pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
293          pcmpgtw mm4, mm3                ;          pcmpgtw mm4, mm3                ;
   
294          pxor    mm0, mm1                ; mm0 = |mm0|          pxor    mm0, mm1                ; mm0 = |mm0|
295          pxor    mm3, mm4                ;          pxor    mm3, mm4                ;
296          psubw   mm0, mm1                ; displace          psubw   mm0, mm1                ; displace
297          psubw   mm3, mm4                ;          psubw   mm3, mm4                ;
   
298          psllw   mm0, 4          psllw   mm0, 4
299          psllw   mm3, 4          psllw   mm3, 4
300      movq mm2, [ebx + 8*ecx]
         movq    mm2, [intra_matrix + 8*ecx]  
301          psrlw   mm2, 1          psrlw   mm2, 1
302          paddw   mm0, mm2          paddw   mm0, mm2
303      movq mm2, [ebx + 256 + ecx*8]
         movq    mm2, [intra_matrix_fix + ecx*8]  
304          pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]          pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
305      movq mm2, [ebx + 8*ecx + 8]
         movq    mm2, [intra_matrix + 8*ecx + 8]  
306          psrlw   mm2, 1          psrlw   mm2, 1
307          paddw   mm3, mm2          paddw   mm3, mm2
308      movq mm2, [ebx + 256 + ecx*8 + 8]
         movq    mm2, [intra_matrix_fix + ecx*8 + 8]  
309          pmulhw  mm3, mm2          pmulhw  mm3, mm2
   
310          paddw   mm0, mm5          paddw   mm0, mm5
311          paddw   mm3, mm5          paddw   mm3, mm5
   
312          psrlw   mm0, 2                  ; mm0 >>= 1   (/4)          psrlw   mm0, 2                  ; mm0 >>= 1   (/4)
313          psrlw   mm3, 2                  ;          psrlw   mm3, 2                  ;
   
314          pxor    mm0, mm1                ; mm0 *= sign(mm0)          pxor    mm0, mm1                ; mm0 *= sign(mm0)
315          pxor    mm3, mm4        ;          pxor    mm3, mm4        ;
316          psubw   mm0, mm1                ; undisplace          psubw   mm0, mm1                ; undisplace
317          psubw   mm3, mm4                ;          psubw   mm3, mm4                ;
   
318          movq    [edi + 8*ecx], mm0          movq    [edi + 8*ecx], mm0
319          movq    [edi + 8*ecx + 8], mm3          movq    [edi + 8*ecx + 8], mm3
320    
# Line 366  Line 322 
322          cmp             ecx,16          cmp             ecx,16
323          jnz             near .q2loop          jnz             near .q2loop
324          jmp             near .done          jmp             near .done
325    .endfunc
326    
327    ;-----------------------------------------------------------------------------
 ;===========================================================================  
328  ;  ;
329  ; uint32_t quant_mpeg_inter_mmx(int16_t * coeff,  ; uint32_t quant_mpeg_inter_mmx(int16_t * coeff,
330  ;                               const int16_t const * data,  ;                               const int16_t const * data,
331  ;                               const uint32_t quant);  ;                               const uint32_t quant,
332    ;                               const uint16_t *mpeg_matrices);
333  ;  ;
334  ;===========================================================================  ;-----------------------------------------------------------------------------
335    
336  align ALIGN  ALIGN 16
 cglobal quant_mpeg_inter_mmx  
337  quant_mpeg_inter_mmx:  quant_mpeg_inter_mmx:
338    
339          push    ecx          push    ecx
340          push    esi          push    esi
341          push    edi          push    edi
342      push ebx
343    
344          mov             edi, [esp + 12 + 4]             ; coeff    mov edi, [esp + 16 + 4]       ; coeff
345          mov             esi, [esp + 12 + 8]             ; data    mov esi, [esp + 16 + 8]       ; data
346          mov             eax, [esp + 12 + 12]    ; quant    mov eax, [esp + 16 + 12]  ; quant
347      mov ebx, [esp + 16 + 16]              ; mpeg_quant_matrices
348    
349          xor             ecx, ecx          xor             ecx, ecx
350    
# Line 400  Line 358 
358    
359          movq    mm7, [mmx_div + eax * 8 - 8]    ; divider          movq    mm7, [mmx_div + eax * 8 - 8]    ; divider
360    
361  align ALIGN  ALIGN 16
362  .loop  .loop
363          movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]          movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
364          movq    mm3, [esi + 8*ecx + 8]  ;          movq    mm3, [esi + 8*ecx + 8]  ;
# Line 412  Line 370 
370          pxor    mm3, mm4                ;          pxor    mm3, mm4                ;
371          psubw   mm0, mm1                ; displace          psubw   mm0, mm1                ; displace
372          psubw   mm3, mm4                ;          psubw   mm3, mm4                ;
   
373          psllw   mm0, 4          psllw   mm0, 4
374          psllw   mm3, 4          psllw   mm3, 4
375      movq mm2, [ebx + 512 + 8*ecx]
         movq    mm2, [inter_matrix + 8*ecx]  
376          psrlw   mm2, 1          psrlw   mm2, 1
377          paddw   mm0, mm2          paddw   mm0, mm2
378      movq mm2, [ebx + 768 + ecx*8]
         movq    mm2, [inter_matrix_fix + ecx*8]  
379          pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]          pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
380      movq mm2, [ebx + 512 + 8*ecx + 8]
         movq    mm2, [inter_matrix + 8*ecx + 8]  
381          psrlw   mm2, 1          psrlw   mm2, 1
382          paddw   mm3, mm2          paddw   mm3, mm2
383      movq mm2, [ebx + 768 + ecx*8 + 8]
         movq    mm2, [inter_matrix_fix + ecx*8 + 8]  
384          pmulhw  mm3, mm2          pmulhw  mm3, mm2
   
385          pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16          pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16
386          pmulhw  mm3, mm7                ;          pmulhw  mm3, mm7                ;
387          psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17          psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17
388          psrlw   mm3, 1          psrlw   mm3, 1
   
389          paddw   mm5, mm0                ; sum += mm0          paddw   mm5, mm0                ; sum += mm0
390          pxor    mm0, mm1                ; mm0 *= sign(mm0)          pxor    mm0, mm1                ; mm0 *= sign(mm0)
391          paddw   mm5, mm3                ;          paddw   mm5, mm3                ;
# Line 455  Line 406 
406          paddd   mm0, mm5          paddd   mm0, mm5
407          movd    eax, mm0                ; return sum          movd    eax, mm0                ; return sum
408    
409      pop ebx
410          pop             edi          pop             edi
411          pop             esi          pop             esi
412          pop             ecx          pop             ecx
413    
414          ret          ret
415    
416  align ALIGN  ALIGN 16
417  .q1loop  .q1loop
418          movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]          movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
419          movq    mm3, [esi + 8*ecx+ 8]          movq    mm3, [esi + 8*ecx+ 8]
                                 ;  
420          pxor    mm1, mm1                ; mm1 = 0          pxor    mm1, mm1                ; mm1 = 0
421          pxor    mm4, mm4                ;          pxor    mm4, mm4                ;
   
422          pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)          pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
423          pcmpgtw mm4, mm3                ;          pcmpgtw mm4, mm3                ;
   
424          pxor    mm0, mm1                ; mm0 = |mm0|          pxor    mm0, mm1                ; mm0 = |mm0|
425          pxor    mm3, mm4                ;          pxor    mm3, mm4                ;
426          psubw   mm0, mm1                ; displace          psubw   mm0, mm1                ; displace
427          psubw   mm3, mm4                ;          psubw   mm3, mm4                ;
   
428          psllw   mm0, 4          psllw   mm0, 4
429          psllw   mm3, 4          psllw   mm3, 4
430      movq mm2, [ebx + 512 + 8*ecx]
         movq    mm2, [inter_matrix + 8*ecx]  
431          psrlw   mm2, 1          psrlw   mm2, 1
432          paddw   mm0, mm2          paddw   mm0, mm2
433      movq mm2, [ebx + 768 + ecx*8]
         movq    mm2, [inter_matrix_fix + ecx*8]  
434          pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]          pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
435      movq mm2, [ebx + 512 + 8*ecx + 8]
         movq    mm2, [inter_matrix + 8*ecx + 8]  
436          psrlw   mm2, 1          psrlw   mm2, 1
437          paddw   mm3, mm2          paddw   mm3, mm2
438      movq mm2, [ebx + 768 + ecx*8 + 8]
         movq    mm2, [inter_matrix_fix + ecx*8 + 8]  
439          pmulhw  mm3, mm2          pmulhw  mm3, mm2
   
440          psrlw   mm0, 1                  ; mm0 >>= 1   (/2)          psrlw   mm0, 1                  ; mm0 >>= 1   (/2)
441          psrlw   mm3, 1                  ;          psrlw   mm3, 1                  ;
   
442          paddw   mm5, mm0                ; sum += mm0          paddw   mm5, mm0                ; sum += mm0
443          pxor    mm0, mm1                ; mm0 *= sign(mm0)          pxor    mm0, mm1                ; mm0 *= sign(mm0)
444          paddw   mm5, mm3                ;          paddw   mm5, mm3                ;
445          pxor    mm3, mm4                ;          pxor    mm3, mm4                ;
446          psubw   mm0, mm1                ; undisplace          psubw   mm0, mm1                ; undisplace
447          psubw   mm3, mm4          psubw   mm3, mm4
   
448          movq    [edi + 8*ecx], mm0          movq    [edi + 8*ecx], mm0
449          movq    [edi + 8*ecx + 8], mm3          movq    [edi + 8*ecx + 8], mm3
450    
# Line 513  Line 454 
454    
455          jmp             .done          jmp             .done
456    
457    ALIGN 16
 align ALIGN  
458  .q2loop  .q2loop
459          movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]          movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
460          movq    mm3, [esi + 8*ecx+ 8]          movq    mm3, [esi + 8*ecx+ 8]
                                 ;  
461          pxor    mm1, mm1                ; mm1 = 0          pxor    mm1, mm1                ; mm1 = 0
462          pxor    mm4, mm4                ;          pxor    mm4, mm4                ;
   
463          pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)          pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
464          pcmpgtw mm4, mm3                ;          pcmpgtw mm4, mm3                ;
   
465          pxor    mm0, mm1                ; mm0 = |mm0|          pxor    mm0, mm1                ; mm0 = |mm0|
466          pxor    mm3, mm4                ;          pxor    mm3, mm4                ;
467          psubw   mm0, mm1                ; displace          psubw   mm0, mm1                ; displace
468          psubw   mm3, mm4                ;          psubw   mm3, mm4                ;
   
469          psllw   mm0, 4          psllw   mm0, 4
470          psllw   mm3, 4          psllw   mm3, 4
471      movq mm2, [ebx + 512 + 8*ecx]
         movq    mm2, [inter_matrix + 8*ecx]  
472          psrlw   mm2, 1          psrlw   mm2, 1
473          paddw   mm0, mm2          paddw   mm0, mm2
474      movq mm2, [ebx + 768 + ecx*8]
         movq    mm2, [inter_matrix_fix + ecx*8]  
475          pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]          pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
476      movq mm2, [ebx + 512 + 8*ecx + 8]
         movq    mm2, [inter_matrix + 8*ecx + 8]  
477          psrlw   mm2, 1          psrlw   mm2, 1
478          paddw   mm3, mm2          paddw   mm3, mm2
479      movq mm2, [ebx + 768 + ecx*8 + 8]
         movq    mm2, [inter_matrix_fix + ecx*8 + 8]  
480          pmulhw  mm3, mm2          pmulhw  mm3, mm2
   
481          psrlw   mm0, 2                  ; mm0 >>= 1   (/2)          psrlw   mm0, 2                  ; mm0 >>= 1   (/2)
482          psrlw   mm3, 2                  ;          psrlw   mm3, 2                  ;
   
483          paddw   mm5, mm0                ; sum += mm0          paddw   mm5, mm0                ; sum += mm0
484          pxor    mm0, mm1                ; mm0 *= sign(mm0)          pxor    mm0, mm1                ; mm0 *= sign(mm0)
485          paddw   mm5, mm3                ;          paddw   mm5, mm3                ;
486          pxor    mm3, mm4                ;          pxor    mm3, mm4                ;
487          psubw   mm0, mm1                ; undisplace          psubw   mm0, mm1                ; undisplace
488          psubw   mm3, mm4          psubw   mm3, mm4
   
489          movq    [edi + 8*ecx], mm0          movq    [edi + 8*ecx], mm0
490          movq    [edi + 8*ecx + 8], mm3          movq    [edi + 8*ecx + 8], mm3
491    
# Line 565  Line 494 
494          jnz             near .q2loop          jnz             near .q2loop
495    
496          jmp     .done          jmp     .done
497    .endfunc
498    
499    
500  ;===========================================================================  ;-----------------------------------------------------------------------------
501  ;  ;
502  ; uint32_t dequant_mpeg_intra_mmx(int16_t *data,  ; uint32_t dequant_mpeg_intra_mmx(int16_t *data,
503  ;                                 const int16_t const *coeff,  ;                                 const int16_t const *coeff,
504  ;                                 const uint32_t quant,  ;                                 const uint32_t quant,
505  ;                                 const uint32_t dcscalar);  ;                                 const uint32_t dcscalar,
506    ;                                 const uint16_t *mpeg_matrices);
507  ;  ;
508  ;===========================================================================  ;-----------------------------------------------------------------------------
509    
510    ;   Note: in order to saturate 'easily', we pre-shift the quantifier    ;   Note: in order to saturate 'easily', we pre-shift the quantifier
511    ; 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 595  Line 526 
526          psubw   mm0, mm1    ; -> mm0 = abs(coeff[i]), mm1 = sign of coeff[i]          psubw   mm0, mm1    ; -> mm0 = abs(coeff[i]), mm1 = sign of coeff[i]
527    
528          movq    mm2, mm7     ; mm2 = quant          movq    mm2, mm7     ; mm2 = quant
529          pmullw  mm2, [intra_matrix + 8*eax + 8*16 ]  ; matrix[i]*quant.    pmullw mm2, [ebx + 8*eax + 8*16 ]  ; matrix[i]*quant.
530    
531          movq    mm6, mm2          movq    mm6, mm2
532          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 615  Line 546 
546    
547    ;********************************************************************    ;********************************************************************
548    
549  align 16  ALIGN 16
 cglobal dequant_mpeg_intra_mmx  
550  dequant_mpeg_intra_mmx:  dequant_mpeg_intra_mmx:
551    
552          mov             edx, [esp+4]  ; data    push ebx
553          mov             ecx, [esp+8]  ; coeff  
554          mov             eax, [esp+12] ; quant    mov edx, [esp + 4 + 4]  ; data
555      mov ecx, [esp + 4 + 8]  ; coeff
556      mov eax, [esp + 4 + 12] ; quant
557      mov ebx, [esp + 4 + 20] ; mpeg_quant_matrices
558    
559          movq    mm7, [mmx_mul_quant  + eax*8 - 8]          movq    mm7, [mmx_mul_quant  + eax*8 - 8]
560          mov             eax, -16   ; to keep aligned, we regularly process coeff[0]    mov eax, -16      ; to keep ALIGNed, we regularly process coeff[0]
561          psllw   mm7, 2   ; << 2. See comment.          psllw   mm7, 2   ; << 2. See comment.
562          pxor    mm6, mm6   ; this is a NOP          pxor    mm6, mm6   ; this is a NOP
563    
564  align 16  ALIGN 16
565  .loop  .loop
566          movq    mm0, [ecx+8*eax + 8*16]   ; mm0 = c  = coeff[i]          movq    mm0, [ecx+8*eax + 8*16]   ; mm0 = c  = coeff[i]
567          movq    mm3, [ecx+8*eax + 8*16 +8]; mm3 = c' = coeff[i+1]          movq    mm3, [ecx+8*eax + 8*16 +8]; mm3 = c' = coeff[i+1]
# Line 638  Line 571 
571          movq    mm2, mm7     ; mm2 = quant          movq    mm2, mm7     ; mm2 = quant
572    
573          pcmpgtw mm4, mm3  ; mm4 = sgn(c')          pcmpgtw mm4, mm3  ; mm4 = sgn(c')
574          pmullw  mm2,  [intra_matrix + 8*eax + 8*16 ]  ; matrix[i]*quant    pmullw mm2,  [ebx + 8*eax + 8*16 ]  ; matrix[i]*quant
575    
576          pxor    mm0, mm1     ; negate if negative          pxor    mm0, mm1     ; negate if negative
577          pxor    mm3, mm4     ; negate if negative          pxor    mm3, mm4     ; negate if negative
# Line 654  Line 587 
587          pmulhw  mm0, mm5   ; high of coeff*(matrix*quant)          pmulhw  mm0, mm5   ; high of coeff*(matrix*quant)
588          movq    mm5, mm7     ; mm2 = quant          movq    mm5, mm7     ; mm2 = quant
589    
590          pmullw  mm5,  [intra_matrix + 8*eax + 8*16 +8]  ; matrix[i+1]*quant    pmullw mm5,  [ebx + 8*eax + 8*16 +8]  ; matrix[i+1]*quant
591    
592          movq    mm6, mm5          movq    mm6, mm5
593          add             eax,2   ; z-flag will be tested later          add             eax,2   ; z-flag will be tested later
# Line 685  Line 618 
618          jnz             near .loop          jnz             near .loop
619    
620      ; deal with DC      ; deal with DC
   
621          movd    mm0, [ecx]          movd    mm0, [ecx]
622          pmullw  mm0, [esp+16]  ; dcscalar    pmullw mm0, [esp + 4 + 16]  ; dcscalar
623          movq    mm2, [mmx_32767_minus_2047]          movq    mm2, [mmx_32767_minus_2047]
624          paddsw  mm0, mm2          paddsw  mm0, mm2
625          psubsw  mm0, mm2          psubsw  mm0, mm2
# Line 698  Line 630 
630          mov             [edx], ax          mov             [edx], ax
631    
632          xor             eax, eax          xor             eax, eax
633    
634      pop ebx
635    
636          ret          ret
637    .endfunc
638    
639  ;===========================================================================  ;-----------------------------------------------------------------------------
640  ;  ;
641  ; uint32_t dequant_mpeg_inter_mmx(int16_t * data,  ; uint32_t dequant_mpeg_inter_mmx(int16_t * data,
642  ;                                 const int16_t * const coeff,  ;                                 const int16_t * const coeff,
643  ;                                 const uint32_t quant);  ;                                 const uint32_t quant,
644    ;                                 const uint16_t *mpeg_matrices);
645  ;  ;
646  ;===========================================================================  ;-----------------------------------------------------------------------------
647    
648      ; Note:  We use (2*c + sgn(c) - sgn(-c)) as multiplier      ; Note:  We use (2*c + sgn(c) - sgn(-c)) as multiplier
649      ; 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.
650      ; 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.
651      ; It's mixed with the extraction of the absolute value.      ; It's mixed with the extraction of the absolute value.
652    
653  align 16  ALIGN 16
 cglobal dequant_mpeg_inter_mmx  
654  dequant_mpeg_inter_mmx:  dequant_mpeg_inter_mmx:
655    
656          mov             edx, [esp+ 4]        ; data    push ebx
657          mov             ecx, [esp+ 8]        ; coeff  
658          mov             eax, [esp+12]        ; quant    mov edx, [esp + 4 + 4]        ; data
659      mov ecx, [esp + 4 + 8]        ; coeff
660      mov eax, [esp + 4 + 12]        ; quant
661      mov ebx, [esp + 4 + 16]                  ; mpeg_quant_matrices
662    
663          movq    mm7, [mmx_mul_quant  + eax*8 - 8]          movq    mm7, [mmx_mul_quant  + eax*8 - 8]
664          mov             eax, -16          mov             eax, -16
665          paddw   mm7, mm7    ; << 1          paddw   mm7, mm7    ; << 1
666          pxor    mm6, mm6 ; mismatch sum          pxor    mm6, mm6 ; mismatch sum
667    
668  align 16  ALIGN 16
669  .loop  .loop
670          movq    mm0, [ecx+8*eax + 8*16   ]   ; mm0 = coeff[i]          movq    mm0, [ecx+8*eax + 8*16   ]   ; mm0 = coeff[i]
671          movq    mm2, [ecx+8*eax + 8*16 +8]   ; mm2 = coeff[i+1]          movq    mm2, [ecx+8*eax + 8*16 +8]   ; mm2 = coeff[i+1]
# Line 754  Line 694 
694      ; we're short on register, here. Poor pairing...      ; we're short on register, here. Poor pairing...
695    
696          movq    mm4, mm7     ; (matrix*quant)          movq    mm4, mm7     ; (matrix*quant)
697          pmullw  mm4,  [inter_matrix + 8*eax + 8*16 -2*8]    pmullw mm4,  [ebx + 512 + 8*eax + 8*16 -2*8]
698          movq    mm5, mm4          movq    mm5, mm4
699          pmulhw  mm5, mm0   ; high of c*(matrix*quant)          pmulhw  mm5, mm0   ; high of c*(matrix*quant)
700          pmullw  mm0, mm4   ; low  of c*(matrix*quant)          pmullw  mm0, mm4   ; low  of c*(matrix*quant)
701    
702          movq    mm4, mm7     ; (matrix*quant)          movq    mm4, mm7     ; (matrix*quant)
703          pmullw  mm4,  [inter_matrix + 8*eax + 8*16 -2*8 + 8]    pmullw mm4,  [ebx + 512 + 8*eax + 8*16 -2*8 + 8]
704    
705          pcmpgtw mm5, [zero]          pcmpgtw mm5, [zero]
706          paddusw mm0, mm5          paddusw mm0, mm5
# Line 804  Line 744 
744          xor             word [edx + 2*63], ax          xor             word [edx + 2*63], ax
745    
746          xor             eax, eax          xor             eax, eax
747    
748      pop ebx
749    
750          ret          ret
751    .endfunc
752    

Legend:
Removed from v.1.1.2.2  
changed lines
  Added in v.1.5

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