[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.10, Tue Nov 11 20:46:24 2008 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                            %define ENDFUNC .endfunc
38                    %else
39                  global _%1                  global _%1
40                  %define %1 _%1                  %define %1 _%1
41                            %define ENDFUNC
42                    %endif
43            %else
44                    %ifdef MARK_FUNCS
45                            global %1:function %1.endfunc-%1
46                            %define ENDFUNC .endfunc
47          %else          %else
48                  global %1                  global %1
49                            %define ENDFUNC
50                    %endif
51          %endif          %endif
52  %endmacro  %endmacro
53    
# Line 50  Line 60 
60          %endif          %endif
61  %endmacro  %endmacro
62    
63  ;***************************************************************************  ;=============================================================================
64  ; Local data  ; Local data (Read Only)
65  ;***************************************************************************  ;=============================================================================
66    
67  %ifdef FORMAT_COFF  %ifdef FORMAT_COFF
68  SECTION .data data  SECTION .rodata
69  %else  %else
70  SECTION .data data align=8  SECTION .rodata align=16
71  %endif  %endif
72    
73  mmx_one:  mmx_one:
74          times 4 dw       1          times 4 dw       1
75    
76  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
77  ; divide by 2Q table  ; divide by 2Q table
78  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
79    
80  align 16  ALIGN 16
81  mmx_div:  mmx_div:
82  %assign quant 1          times 4 dw 65535 ; the div by 2 formula will overflow for the case
83  %rep 31                           ; 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 30
88          times 4 dw  (1<<17) / (quant*2) + 1          times 4 dw  (1<<17) / (quant*2) + 1
89          %assign quant quant+1          %assign quant quant+1
90  %endrep  %endrep
91    
 ;===========================================================================  
 ;  
 ; intra matrix  
 ;  
 ;===========================================================================  
   
 cextern intra_matrix  
 cextern intra_matrix_fix  
   
 ;===========================================================================  
 ;  
 ; inter matrix  
 ;  
 ;===========================================================================  
   
 cextern inter_matrix  
 cextern inter_matrix_fix  
   
   
92  %define VM18P 3  %define VM18P 3
93  %define VM18Q 4  %define VM18Q 4
94    
95    
96  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
97  ; quantd table  ; quantd table
98  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
99    
100  quantd:  quantd:
101  %assign quant 1  %assign quant 1
# Line 113  Line 104 
104          %assign quant quant+1          %assign quant quant+1
105  %endrep  %endrep
106    
107  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
108  ; multiple by 2Q table  ; multiple by 2Q table
109  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
110    
111  mmx_mul_quant:  mmx_mul_quant:
112  %assign quant 1  %assign quant 1
# Line 126  Line 115 
115          %assign quant quant+1          %assign quant quant+1
116  %endrep  %endrep
117    
118  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
119  ; saturation limits  ; saturation limits
120  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
121    
122  align 16  ALIGN 16
123    
124  mmx_32767_minus_2047:  mmx_32767_minus_2047:
125          times 4 dw (32767-2047)          times 4 dw (32767-2047)
# Line 145  Line 132 
132  zero:  zero:
133          times 4 dw 0          times 4 dw 0
134    
135  ;***************************************************************************  ;=============================================================================
136  ; Local data  ; rounding
137  ;***************************************************************************  ;=============================================================================
138    
139  section .text  mmx_rounding:
140            dw (1<<13)
141            dw 0
142            dw (1<<13)
143            dw 0
144    
145    ;=============================================================================
146    ; Code
147    ;=============================================================================
148    
149  ;===========================================================================  SECTION .text
 ;  
 ; uint32_t quant_mpeg_intra_mmx(int16_t * coeff,  
 ;                               const int16_t const * data,  
 ;                               const uint32_t quant,  
 ;                               const uint32_t dcscalar);  
 ;  
 ;===========================================================================  
150    
 align ALIGN  
151  cglobal quant_mpeg_intra_mmx  cglobal quant_mpeg_intra_mmx
152  quant_mpeg_intra_mmx:  cglobal quant_mpeg_inter_mmx
153    cglobal dequant_mpeg_intra_mmx
154          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                  ;  
   
         movq    mm2, [intra_matrix + 8*ecx]  
         psrlw   mm2, 1                  ; intra_matrix[i]>>1  
         paddw   mm0, mm2  
155    
         movq    mm2, [intra_matrix_fix + ecx*8]  
         pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]  
156    
157          movq    mm2, [intra_matrix + 8*ecx + 8]  %macro QUANT_MMX        1
158          psrlw   mm2, 1          movq    mm0, [eax + 16*(%1)]                    ; data
159          paddw   mm3, mm2          movq    mm2, [ecx + 16*(%1) + 128]              ; intra_matrix_rec
160            movq    mm4, [eax + 16*(%1) + 8]                ; data
161            movq    mm6, [ecx + 16*(%1) + 128 + 8]  ; intra_matrix_rec
162    
163          movq    mm2, [intra_matrix_fix + ecx*8 + 8]          movq    mm1, mm0
164          pmulhw  mm3, mm2          movq    mm5, mm4
165    
166          paddw   mm0, mm5                ; + quantd          pmullw  mm0, mm2                                        ; low results
167          paddw   mm3, mm5          pmulhw  mm1, mm2                                        ; high results
168          pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16          pmullw  mm4, mm6                                        ; low results
169          pmulhw  mm3, mm7                ;          pmulhw  mm5, mm6                                        ; high results
170          psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17  
171          psrlw   mm3, 1          movq    mm2, mm0
172            movq    mm6, mm4
173    
174            punpckhwd mm0, mm1
175            punpcklwd mm2, mm1
176            punpckhwd mm4, mm5
177            punpcklwd mm6, mm5
178    
179            paddd   mm2, mm7
180            paddd   mm0, mm7
181            paddd   mm6, mm7
182            paddd   mm4, mm7
183    
184            psrad   mm2, 14
185            psrad   mm0, 14
186            psrad   mm6, 14
187            psrad   mm4, 14
188    
189          pxor    mm0, mm1                ; mm0 *= sign(mm0)          packssdw mm2, mm0
190          pxor    mm3, mm4                ;          packssdw mm6, mm4
         psubw   mm0, mm1                ; undisplace  
         psubw   mm3, mm4                ;  
191    
192          movq    [edi + 8*ecx], mm0          movq    [edi + 16*(%1)], mm2
193          movq    [edi + 8*ecx + 8], mm3          movq    [edi + 16*(%1)+8], mm6
194    %endmacro
195    
196          add             ecx,2  ;-----------------------------------------------------------------------------
197          cmp             ecx,16  ;
198          jnz     near .loop  ; uint32_t quant_mpeg_intra_mmx(int16_t * coeff,
199    ;                               const int16_t const * data,
200    ;                               const uint32_t quant,
201    ;                               const uint32_t dcscalar,
202    ;                               const uint16_t *mpeg_matrices);
203    ;
204    ;-----------------------------------------------------------------------------
205    
206  .done  ALIGN 16
207                  ; caclulate  data[0] // (int32_t)dcscalar)  quant_mpeg_intra_mmx:
208    
209          mov     ecx, [esp + 12 + 16]    ; dcscalar    push edi
210          mov     edx, ecx    movq mm7, [mmx_rounding]
         movsx   eax, word [esi] ; data[0]  
         shr     edx, 1                  ; edx = dcscalar /2  
         cmp             eax, 0  
         jg              .gtzero  
   
         sub             eax, edx  
         jmp             short .mul  
 .gtzero  
         add             eax, edx  
 .mul  
         cdq                             ; expand eax -> edx:eax  
         idiv    ecx                     ; eax = edx:eax / dcscalar  
211    
212          mov     [edi], ax               ; coeff[0] = ax    mov eax, [esp + 4 + 8]                ; data
213      mov ecx, [esp + 4 + 20]               ; mpeg_quant_matrices
214      mov edi, [esp + 4 + 4]                ; coeff
215    
216      QUANT_MMX(0)
217      QUANT_MMX(1)
218      QUANT_MMX(2)
219      QUANT_MMX(3)
220      QUANT_MMX(4)
221      QUANT_MMX(5)
222      QUANT_MMX(6)
223      QUANT_MMX(7)
224    
225      ; calculate DC
226      movsx eax, word [eax]     ; data[0]
227      mov ecx, [esp + 4 + 16]   ; dcscalar
228      mov edx, eax
229      mov edi, ecx
230      shr ecx, 1                ; ecx = dcscalar/2
231      sar edx, 31               ; edx = sign extend of eax (ready for division too)
232      xor ecx, edx              ; adjust ecx according to the sign of data[0]
233      sub ecx, edx
234      add eax, ecx
235    
236      mov ecx, [esp + 4 + 4]        ; coeff again
237      idiv edi                  ; eax = edx:eax / dcscalar
238      mov [ecx], 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]  ;
285          pxor    mm1, mm1                ; mm1 = 0          pxor    mm1, mm1                ; mm1 = 0
# 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 448  Line 319 
319          cmp             ecx, 16          cmp             ecx, 16
320          jnz             near .loop          jnz             near .loop
321    
322  .done  .done:
323          pmaddwd mm5, [mmx_one]          pmaddwd mm5, [mmx_one]
324          movq    mm0, mm5          movq    mm0, mm5
325          psrlq   mm5, 32          psrlq   mm5, 32
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
378  align ALIGN  .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]
488          pxor    mm1, mm1          pxor    mm1, mm1
# 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]
592          add             eax, 2          add             eax, 2
# 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    
673    
674    %ifidn __OUTPUT_FORMAT__,elf
675    section ".note.GNU-stack" noalloc noexec nowrite progbits
676    %endif
677    

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

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