[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.7, Tue Jul 11 10:01:27 2006 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  ; rounding
133  ;***************************************************************************  ;=============================================================================
134    
135    mmx_rounding:
136            dw (1<<13)
137            dw 0
138            dw (1<<13)
139            dw 0
140    
141    ;=============================================================================
142    ; Code
143    ;=============================================================================
144    
145  section .text  SECTION .text
146    
 ;===========================================================================  
 ;  
 ; uint32_t quant_mpeg_intra_mmx(int16_t * coeff,  
 ;                               const int16_t const * data,  
 ;                               const uint32_t quant,  
 ;                               const uint32_t dcscalar);  
 ;  
 ;===========================================================================  
   
 align ALIGN  
147  cglobal quant_mpeg_intra_mmx  cglobal quant_mpeg_intra_mmx
148  quant_mpeg_intra_mmx:  cglobal quant_mpeg_inter_mmx
149    cglobal dequant_mpeg_intra_mmx
150          push    ecx  cglobal dequant_mpeg_inter_mmx
         push    esi  
         push    edi  
   
         mov             edi, [esp + 12 + 4]             ; coeff  
         mov             esi, [esp + 12 + 8]             ; data  
         mov             eax, [esp + 12 + 12]    ; quant  
   
         movq    mm5, [quantd + eax * 8 - 8] ; quantd -> mm5  
   
         xor             ecx, ecx  
         cmp             al, 1  
         jz              near .q1loop  
   
         cmp             al, 2  
         jz              near .q2loop  
   
         movq    mm7, [mmx_div + eax * 8 - 8] ; multipliers[quant] -> mm7  
   
 align ALIGN  
 .loop  
         movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]  
         movq    mm3, [esi + 8*ecx + 8]  ;  
   
         pxor    mm1, mm1                ; mm1 = 0  
         pxor    mm4, mm4  
   
         pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)  
         pcmpgtw mm4, mm3  
   
         pxor    mm0, mm1                ; mm0 = |mm0|  
         pxor    mm3, mm4                ;  
         psubw   mm0, mm1                ; displace  
         psubw   mm3, mm4                ;  
   
         psllw   mm0, 4                  ; level << 4  
         psllw   mm3, 4                  ;  
151    
         movq    mm2, [intra_matrix + 8*ecx]  
         psrlw   mm2, 1                  ; intra_matrix[i]>>1  
         paddw   mm0, mm2  
152    
153          movq    mm2, [intra_matrix_fix + ecx*8]  %macro QUANT_MMX        1
154          pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]          movq    mm0, [eax + 16*(%1)]                    ; data
155            movq    mm2, [ecx + 16*(%1) + 128]              ; intra_matrix_rec
156            movq    mm4, [eax + 16*(%1) + 8]                ; data
157            movq    mm6, [ecx + 16*(%1) + 128 + 8]  ; intra_matrix_rec
158    
159          movq    mm2, [intra_matrix + 8*ecx + 8]          movq    mm1, mm0
160          psrlw   mm2, 1          movq    mm5, mm4
         paddw   mm3, mm2  
161    
162          movq    mm2, [intra_matrix_fix + ecx*8 + 8]          pmullw  mm0, mm2                                        ; low results
163          pmulhw  mm3, mm2          pmulhw  mm1, mm2                                        ; high results
164            pmullw  mm4, mm6                                        ; low results
165            pmulhw  mm5, mm6                                        ; high results
166    
167            movq    mm2, mm0
168            movq    mm6, mm4
169    
170            punpckhwd mm0, mm1
171            punpcklwd mm2, mm1
172            punpckhwd mm4, mm5
173            punpcklwd mm6, mm5
174    
175            paddd   mm2, mm7
176            paddd   mm0, mm7
177            paddd   mm6, mm7
178            paddd   mm4, mm7
179    
180            psrad   mm2, 14
181            psrad   mm0, 14
182            psrad   mm6, 14
183            psrad   mm4, 14
184    
185          paddw   mm0, mm5                ; + quantd          packssdw mm2, mm0
186          paddw   mm3, mm5          packssdw mm6, mm4
         pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16  
         pmulhw  mm3, mm7                ;  
         psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17  
         psrlw   mm3, 1  
187    
188          pxor    mm0, mm1                ; mm0 *= sign(mm0)          movq    [edi + 16*(%1)], mm2
189          pxor    mm3, mm4                ;          movq    [edi + 16*(%1)+8], mm6
190          psubw   mm0, mm1                ; undisplace  %endmacro
         psubw   mm3, mm4                ;  
191    
192          movq    [edi + 8*ecx], mm0  ;-----------------------------------------------------------------------------
193          movq    [edi + 8*ecx + 8], mm3  ;
194    ; uint32_t quant_mpeg_intra_mmx(int16_t * coeff,
195    ;                               const int16_t const * data,
196    ;                               const uint32_t quant,
197    ;                               const uint32_t dcscalar,
198    ;                               const uint16_t *mpeg_matrices);
199    ;
200    ;-----------------------------------------------------------------------------
201    
202          add             ecx,2  ALIGN 16
203          cmp             ecx,16  quant_mpeg_intra_mmx:
         jnz     near .loop  
204    
205  .done    push edi
206                  ; caclulate  data[0] // (int32_t)dcscalar)    movq mm7, [mmx_rounding]
207    
208          mov     ecx, [esp + 12 + 16]    ; dcscalar    mov eax, [esp + 4 + 8]                ; data
209      mov ecx, [esp + 4 + 20]               ; mpeg_quant_matrices
210      mov edi, [esp + 4 + 4]                ; coeff
211    
212      QUANT_MMX(0)
213      QUANT_MMX(1)
214      QUANT_MMX(2)
215      QUANT_MMX(3)
216      QUANT_MMX(4)
217      QUANT_MMX(5)
218      QUANT_MMX(6)
219      QUANT_MMX(7)
220    
221      ; calculate DC
222      movsx eax, word [eax]     ; data[0]
223      mov ecx, [esp + 4 + 16]   ; dcscalar
224          mov     edx, ecx          mov     edx, ecx
         movsx   eax, word [esi] ; data[0]  
225          shr     edx, 1                  ; edx = dcscalar /2          shr     edx, 1                  ; edx = dcscalar /2
226          cmp             eax, 0    mov edi, edx
227          jg              .gtzero    neg edi
228    
229      cmp eax, 0
230      cmovg edx, edi
231          sub             eax, edx          sub             eax, edx
232          jmp             short .mul  
233  .gtzero    mov edi, [esp + 4 + 4]        ; coeff again
234          add             eax, edx  
 .mul  
235          cdq                             ; expand eax -> edx:eax          cdq                             ; expand eax -> edx:eax
236          idiv    ecx                     ; eax = edx:eax / dcscalar          idiv    ecx                     ; eax = edx:eax / dcscalar
237    
238          mov     [edi], ax               ; coeff[0] = ax          mov     [edi], ax               ; coeff[0] = ax
239    
240          pop     edi          pop     edi
         pop     esi  
         pop     ecx  
241    
242          xor eax, eax                            ; return(0);          xor eax, eax                            ; return(0);
243          ret          ret
244    .endfunc
245    
 align ALIGN  
 .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, [intra_matrix + 8*ecx]  
         psrlw   mm2, 1  
         paddw   mm0, mm2  
   
         movq    mm2, [intra_matrix_fix + ecx*8]  
         pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]  
246    
247          movq    mm2, [intra_matrix + 8*ecx + 8]  ;-----------------------------------------------------------------------------
         psrlw   mm2, 1  
         paddw   mm3, mm2  
   
         movq    mm2, [intra_matrix_fix + 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 ALIGN  
 .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, [intra_matrix + 8*ecx]  
         psrlw   mm2, 1  
         paddw   mm0, mm2  
   
         movq    mm2, [intra_matrix_fix + ecx*8]  
         pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]  
   
         movq    mm2, [intra_matrix + 8*ecx + 8]  
         psrlw   mm2, 1  
         paddw   mm3, mm2  
   
         movq    mm2, [intra_matrix_fix + 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  
   
   
 ;===========================================================================  
248  ;  ;
249  ; uint32_t quant_mpeg_inter_mmx(int16_t * coeff,  ; uint32_t quant_mpeg_inter_mmx(int16_t * coeff,
250  ;                               const int16_t const * data,  ;                               const int16_t const * data,
251  ;                               const uint32_t quant);  ;                               const uint32_t quant,
252    ;                               const uint16_t *mpeg_matrices);
253  ;  ;
254  ;===========================================================================  ;-----------------------------------------------------------------------------
255    
256  align ALIGN  ALIGN 16
 cglobal quant_mpeg_inter_mmx  
257  quant_mpeg_inter_mmx:  quant_mpeg_inter_mmx:
258    
259          push    ecx          push    ecx
260          push    esi          push    esi
261          push    edi          push    edi
262      push ebx
263    
264          mov             edi, [esp + 12 + 4]             ; coeff    mov edi, [esp + 16 + 4]       ; coeff
265          mov             esi, [esp + 12 + 8]             ; data    mov esi, [esp + 16 + 8]       ; data
266          mov             eax, [esp + 12 + 12]    ; quant    mov eax, [esp + 16 + 12]  ; quant
267      mov ebx, [esp + 16 + 16]              ; mpeg_quant_matrices
268    
269          xor             ecx, ecx          xor             ecx, ecx
270    
# Line 400  Line 278 
278    
279          movq    mm7, [mmx_div + eax * 8 - 8]    ; divider          movq    mm7, [mmx_div + eax * 8 - 8]    ; divider
280    
281  align ALIGN  ALIGN 16
282  .loop  .loop
283          movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]          movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
284          movq    mm3, [esi + 8*ecx + 8]  ;          movq    mm3, [esi + 8*ecx + 8]  ;
# Line 412  Line 290 
290          pxor    mm3, mm4                ;          pxor    mm3, mm4                ;
291          psubw   mm0, mm1                ; displace          psubw   mm0, mm1                ; displace
292          psubw   mm3, mm4                ;          psubw   mm3, mm4                ;
   
293          psllw   mm0, 4          psllw   mm0, 4
294          psllw   mm3, 4          psllw   mm3, 4
295      movq mm2, [ebx + 512 + 8*ecx]
         movq    mm2, [inter_matrix + 8*ecx]  
296          psrlw   mm2, 1          psrlw   mm2, 1
297          paddw   mm0, mm2          paddw   mm0, mm2
298      movq mm2, [ebx + 768 + ecx*8]
         movq    mm2, [inter_matrix_fix + ecx*8]  
299          pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]          pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
300      movq mm2, [ebx + 512 + 8*ecx + 8]
         movq    mm2, [inter_matrix + 8*ecx + 8]  
301          psrlw   mm2, 1          psrlw   mm2, 1
302          paddw   mm3, mm2          paddw   mm3, mm2
303      movq mm2, [ebx + 768 + ecx*8 + 8]
         movq    mm2, [inter_matrix_fix + ecx*8 + 8]  
304          pmulhw  mm3, mm2          pmulhw  mm3, mm2
   
305          pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16          pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16
306          pmulhw  mm3, mm7                ;          pmulhw  mm3, mm7                ;
307          psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17          psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17
308          psrlw   mm3, 1          psrlw   mm3, 1
   
309          paddw   mm5, mm0                ; sum += mm0          paddw   mm5, mm0                ; sum += mm0
310          pxor    mm0, mm1                ; mm0 *= sign(mm0)          pxor    mm0, mm1                ; mm0 *= sign(mm0)
311          paddw   mm5, mm3                ;          paddw   mm5, mm3                ;
# Line 455  Line 326 
326          paddd   mm0, mm5          paddd   mm0, mm5
327          movd    eax, mm0                ; return sum          movd    eax, mm0                ; return sum
328    
329      pop ebx
330          pop             edi          pop             edi
331          pop             esi          pop             esi
332          pop             ecx          pop             ecx
333    
334          ret          ret
335    
336  align ALIGN  ALIGN 16
337  .q1loop  .q1loop
338          movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]          movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
339          movq    mm3, [esi + 8*ecx+ 8]          movq    mm3, [esi + 8*ecx+ 8]
                                 ;  
340          pxor    mm1, mm1                ; mm1 = 0          pxor    mm1, mm1                ; mm1 = 0
341          pxor    mm4, mm4                ;          pxor    mm4, mm4                ;
   
342          pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)          pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
343          pcmpgtw mm4, mm3                ;          pcmpgtw mm4, mm3                ;
   
344          pxor    mm0, mm1                ; mm0 = |mm0|          pxor    mm0, mm1                ; mm0 = |mm0|
345          pxor    mm3, mm4                ;          pxor    mm3, mm4                ;
346          psubw   mm0, mm1                ; displace          psubw   mm0, mm1                ; displace
347          psubw   mm3, mm4                ;          psubw   mm3, mm4                ;
   
348          psllw   mm0, 4          psllw   mm0, 4
349          psllw   mm3, 4          psllw   mm3, 4
350      movq mm2, [ebx + 512 + 8*ecx]
         movq    mm2, [inter_matrix + 8*ecx]  
351          psrlw   mm2, 1          psrlw   mm2, 1
352          paddw   mm0, mm2          paddw   mm0, mm2
353      movq mm2, [ebx + 768 + ecx*8]
         movq    mm2, [inter_matrix_fix + ecx*8]  
354          pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]          pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
355      movq mm2, [ebx + 512 + 8*ecx + 8]
         movq    mm2, [inter_matrix + 8*ecx + 8]  
356          psrlw   mm2, 1          psrlw   mm2, 1
357          paddw   mm3, mm2          paddw   mm3, mm2
358      movq mm2, [ebx + 768 + ecx*8 + 8]
         movq    mm2, [inter_matrix_fix + ecx*8 + 8]  
359          pmulhw  mm3, mm2          pmulhw  mm3, mm2
   
360          psrlw   mm0, 1                  ; mm0 >>= 1   (/2)          psrlw   mm0, 1                  ; mm0 >>= 1   (/2)
361          psrlw   mm3, 1                  ;          psrlw   mm3, 1                  ;
   
362          paddw   mm5, mm0                ; sum += mm0          paddw   mm5, mm0                ; sum += mm0
363          pxor    mm0, mm1                ; mm0 *= sign(mm0)          pxor    mm0, mm1                ; mm0 *= sign(mm0)
364          paddw   mm5, mm3                ;          paddw   mm5, mm3                ;
365          pxor    mm3, mm4                ;          pxor    mm3, mm4                ;
366          psubw   mm0, mm1                ; undisplace          psubw   mm0, mm1                ; undisplace
367          psubw   mm3, mm4          psubw   mm3, mm4
   
368          movq    [edi + 8*ecx], mm0          movq    [edi + 8*ecx], mm0
369          movq    [edi + 8*ecx + 8], mm3          movq    [edi + 8*ecx + 8], mm3
370    
# Line 513  Line 374 
374    
375          jmp             .done          jmp             .done
376    
377    ALIGN 16
 align ALIGN  
378  .q2loop  .q2loop
379          movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]          movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
380          movq    mm3, [esi + 8*ecx+ 8]          movq    mm3, [esi + 8*ecx+ 8]
                                 ;  
381          pxor    mm1, mm1                ; mm1 = 0          pxor    mm1, mm1                ; mm1 = 0
382          pxor    mm4, mm4                ;          pxor    mm4, mm4                ;
   
383          pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)          pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
384          pcmpgtw mm4, mm3                ;          pcmpgtw mm4, mm3                ;
   
385          pxor    mm0, mm1                ; mm0 = |mm0|          pxor    mm0, mm1                ; mm0 = |mm0|
386          pxor    mm3, mm4                ;          pxor    mm3, mm4                ;
387          psubw   mm0, mm1                ; displace          psubw   mm0, mm1                ; displace
388          psubw   mm3, mm4                ;          psubw   mm3, mm4                ;
   
389          psllw   mm0, 4          psllw   mm0, 4
390          psllw   mm3, 4          psllw   mm3, 4
391      movq mm2, [ebx + 512 + 8*ecx]
         movq    mm2, [inter_matrix + 8*ecx]  
392          psrlw   mm2, 1          psrlw   mm2, 1
393          paddw   mm0, mm2          paddw   mm0, mm2
394      movq mm2, [ebx + 768 + ecx*8]
         movq    mm2, [inter_matrix_fix + ecx*8]  
395          pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]          pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
396      movq mm2, [ebx + 512 + 8*ecx + 8]
         movq    mm2, [inter_matrix + 8*ecx + 8]  
397          psrlw   mm2, 1          psrlw   mm2, 1
398          paddw   mm3, mm2          paddw   mm3, mm2
399      movq mm2, [ebx + 768 + ecx*8 + 8]
         movq    mm2, [inter_matrix_fix + ecx*8 + 8]  
400          pmulhw  mm3, mm2          pmulhw  mm3, mm2
   
401          psrlw   mm0, 2                  ; mm0 >>= 1   (/2)          psrlw   mm0, 2                  ; mm0 >>= 1   (/2)
402          psrlw   mm3, 2                  ;          psrlw   mm3, 2                  ;
   
403          paddw   mm5, mm0                ; sum += mm0          paddw   mm5, mm0                ; sum += mm0
404          pxor    mm0, mm1                ; mm0 *= sign(mm0)          pxor    mm0, mm1                ; mm0 *= sign(mm0)
405          paddw   mm5, mm3                ;          paddw   mm5, mm3                ;
406          pxor    mm3, mm4                ;          pxor    mm3, mm4                ;
407          psubw   mm0, mm1                ; undisplace          psubw   mm0, mm1                ; undisplace
408          psubw   mm3, mm4          psubw   mm3, mm4
   
409          movq    [edi + 8*ecx], mm0          movq    [edi + 8*ecx], mm0
410          movq    [edi + 8*ecx + 8], mm3          movq    [edi + 8*ecx + 8], mm3
411    
# Line 565  Line 414 
414          jnz             near .q2loop          jnz             near .q2loop
415    
416          jmp     .done          jmp     .done
417    .endfunc
418    
419    
420  ;===========================================================================  ;-----------------------------------------------------------------------------
421  ;  ;
422  ; uint32_t dequant_mpeg_intra_mmx(int16_t *data,  ; uint32_t dequant_mpeg_intra_mmx(int16_t *data,
423  ;                                 const int16_t const *coeff,  ;                                 const int16_t const *coeff,
424  ;                                 const uint32_t quant,  ;                                 const uint32_t quant,
425  ;                                 const uint32_t dcscalar);  ;                                 const uint32_t dcscalar,
426    ;                                 const uint16_t *mpeg_matrices);
427  ;  ;
428  ;===========================================================================  ;-----------------------------------------------------------------------------
429    
430    ;   Note: in order to saturate 'easily', we pre-shift the quantifier    ;   Note: in order to saturate 'easily', we pre-shift the quantifier
431    ; 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 446 
446          psubw   mm0, mm1    ; -> mm0 = abs(coeff[i]), mm1 = sign of coeff[i]          psubw   mm0, mm1    ; -> mm0 = abs(coeff[i]), mm1 = sign of coeff[i]
447    
448          movq    mm2, mm7     ; mm2 = quant          movq    mm2, mm7     ; mm2 = quant
449          pmullw  mm2, [intra_matrix + 8*eax + 8*16 ]  ; matrix[i]*quant.    pmullw mm2, [ebx + 8*eax + 8*16 ]  ; matrix[i]*quant.
450    
451          movq    mm6, mm2          movq    mm6, mm2
452          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 466 
466    
467    ;********************************************************************    ;********************************************************************
468    
469  align 16  ALIGN 16
 cglobal dequant_mpeg_intra_mmx  
470  dequant_mpeg_intra_mmx:  dequant_mpeg_intra_mmx:
471    
472          mov             edx, [esp+4]  ; data    push ebx
473          mov             ecx, [esp+8]  ; coeff  
474          mov             eax, [esp+12] ; quant    mov edx, [esp + 4 + 4]  ; data
475      mov ecx, [esp + 4 + 8]  ; coeff
476      mov eax, [esp + 4 + 12] ; quant
477      mov ebx, [esp + 4 + 20] ; mpeg_quant_matrices
478    
479          movq    mm7, [mmx_mul_quant  + eax*8 - 8]          movq    mm7, [mmx_mul_quant  + eax*8 - 8]
480          mov             eax, -16   ; to keep aligned, we regularly process coeff[0]    mov eax, -16      ; to keep ALIGNed, we regularly process coeff[0]
481          psllw   mm7, 2   ; << 2. See comment.          psllw   mm7, 2   ; << 2. See comment.
482          pxor    mm6, mm6   ; this is a NOP          pxor    mm6, mm6   ; this is a NOP
483    
484  align 16  ALIGN 16
485  .loop  .loop
486          movq    mm0, [ecx+8*eax + 8*16]   ; mm0 = c  = coeff[i]          movq    mm0, [ecx+8*eax + 8*16]   ; mm0 = c  = coeff[i]
487          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 491 
491          movq    mm2, mm7     ; mm2 = quant          movq    mm2, mm7     ; mm2 = quant
492    
493          pcmpgtw mm4, mm3  ; mm4 = sgn(c')          pcmpgtw mm4, mm3  ; mm4 = sgn(c')
494          pmullw  mm2,  [intra_matrix + 8*eax + 8*16 ]  ; matrix[i]*quant    pmullw mm2,  [ebx + 8*eax + 8*16 ]  ; matrix[i]*quant
495    
496          pxor    mm0, mm1     ; negate if negative          pxor    mm0, mm1     ; negate if negative
497          pxor    mm3, mm4     ; negate if negative          pxor    mm3, mm4     ; negate if negative
# Line 654  Line 507 
507          pmulhw  mm0, mm5   ; high of coeff*(matrix*quant)          pmulhw  mm0, mm5   ; high of coeff*(matrix*quant)
508          movq    mm5, mm7     ; mm2 = quant          movq    mm5, mm7     ; mm2 = quant
509    
510          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
511    
512          movq    mm6, mm5          movq    mm6, mm5
513          add             eax,2   ; z-flag will be tested later          add             eax,2   ; z-flag will be tested later
# Line 685  Line 538 
538          jnz             near .loop          jnz             near .loop
539    
540      ; deal with DC      ; deal with DC
   
541          movd    mm0, [ecx]          movd    mm0, [ecx]
542          pmullw  mm0, [esp+16]  ; dcscalar    pmullw mm0, [esp + 4 + 16]  ; dcscalar
543          movq    mm2, [mmx_32767_minus_2047]          movq    mm2, [mmx_32767_minus_2047]
544          paddsw  mm0, mm2          paddsw  mm0, mm2
545          psubsw  mm0, mm2          psubsw  mm0, mm2
# Line 698  Line 550 
550          mov             [edx], ax          mov             [edx], ax
551    
552          xor             eax, eax          xor             eax, eax
553    
554      pop ebx
555    
556          ret          ret
557    .endfunc
558    
559  ;===========================================================================  ;-----------------------------------------------------------------------------
560  ;  ;
561  ; uint32_t dequant_mpeg_inter_mmx(int16_t * data,  ; uint32_t dequant_mpeg_inter_mmx(int16_t * data,
562  ;                                 const int16_t * const coeff,  ;                                 const int16_t * const coeff,
563  ;                                 const uint32_t quant);  ;                                 const uint32_t quant,
564    ;                                 const uint16_t *mpeg_matrices);
565  ;  ;
566  ;===========================================================================  ;-----------------------------------------------------------------------------
567    
568      ; Note:  We use (2*c + sgn(c) - sgn(-c)) as multiplier      ; Note:  We use (2*c + sgn(c) - sgn(-c)) as multiplier
569      ; 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.
570      ; 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.
571      ; It's mixed with the extraction of the absolute value.      ; It's mixed with the extraction of the absolute value.
572    
573  align 16  ALIGN 16
 cglobal dequant_mpeg_inter_mmx  
574  dequant_mpeg_inter_mmx:  dequant_mpeg_inter_mmx:
575    
576          mov             edx, [esp+ 4]        ; data    push ebx
577          mov             ecx, [esp+ 8]        ; coeff  
578          mov             eax, [esp+12]        ; quant    mov edx, [esp + 4 + 4]        ; data
579      mov ecx, [esp + 4 + 8]        ; coeff
580      mov eax, [esp + 4 + 12]        ; quant
581      mov ebx, [esp + 4 + 16]                  ; mpeg_quant_matrices
582    
583          movq    mm7, [mmx_mul_quant  + eax*8 - 8]          movq    mm7, [mmx_mul_quant  + eax*8 - 8]
584          mov             eax, -16          mov             eax, -16
585          paddw   mm7, mm7    ; << 1          paddw   mm7, mm7    ; << 1
586          pxor    mm6, mm6 ; mismatch sum          pxor    mm6, mm6 ; mismatch sum
587    
588  align 16  ALIGN 16
589  .loop  .loop
590          movq    mm0, [ecx+8*eax + 8*16   ]   ; mm0 = coeff[i]          movq    mm0, [ecx+8*eax + 8*16   ]   ; mm0 = coeff[i]
591          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 614 
614      ; we're short on register, here. Poor pairing...      ; we're short on register, here. Poor pairing...
615    
616          movq    mm4, mm7     ; (matrix*quant)          movq    mm4, mm7     ; (matrix*quant)
617          pmullw  mm4,  [inter_matrix + 8*eax + 8*16 -2*8]    pmullw mm4,  [ebx + 512 + 8*eax + 8*16 -2*8]
618          movq    mm5, mm4          movq    mm5, mm4
619          pmulhw  mm5, mm0   ; high of c*(matrix*quant)          pmulhw  mm5, mm0   ; high of c*(matrix*quant)
620          pmullw  mm0, mm4   ; low  of c*(matrix*quant)          pmullw  mm0, mm4   ; low  of c*(matrix*quant)
621    
622          movq    mm4, mm7     ; (matrix*quant)          movq    mm4, mm7     ; (matrix*quant)
623          pmullw  mm4,  [inter_matrix + 8*eax + 8*16 -2*8 + 8]    pmullw mm4,  [ebx + 512 + 8*eax + 8*16 -2*8 + 8]
624    
625          pcmpgtw mm5, [zero]          pcmpgtw mm5, [zero]
626          paddusw mm0, mm5          paddusw mm0, mm5
# Line 804  Line 664 
664          xor             word [edx + 2*63], ax          xor             word [edx + 2*63], ax
665    
666          xor             eax, eax          xor             eax, eax
667    
668      pop ebx
669    
670          ret          ret
671    .endfunc
672    

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

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