[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.14, Thu Dec 4 14:41:50 2008 UTC
# Line 4  Line 4 
4  ; *  - 3dne Quantization/Dequantization -  ; *  - 3dne Quantization/Dequantization -
5  ; *  ; *
6  ; *  Copyright (C) 2002-2003 Peter Ross <pross@xvid.org>  ; *  Copyright (C) 2002-2003 Peter Ross <pross@xvid.org>
7  ; *                2002-2003 Michael Militzer <isibaar@xvid.org>  ; *                2002-2008 Michael Militzer <michael@xvid.org>
8  ; *                2002-2003 Pascal Massimino <skal@planet-d.net>  ; *                2002-2003 Pascal Massimino <skal@planet-d.net>
9  ; *  ; *
10  ; *  This program is free software ; you can redistribute it and/or modify  ; *  This program is free software ; you can redistribute it and/or modify
# Line 25  Line 25 
25  ; *  ; *
26  ; *************************************************************************/  ; *************************************************************************/
27    
 ; data/text alignment  
 %define ALIGN 8  
   
28  %define SATURATE  %define SATURATE
29    
30  bits 32  %include "nasm.inc"
   
 %macro cglobal 1  
         %ifdef PREFIX  
                 global _%1  
                 %define %1 _%1  
         %else  
                 global %1  
         %endif  
 %endmacro  
   
 %macro cextern 1  
         %ifdef PREFIX  
                 extern _%1  
                 %define %1 _%1  
         %else  
                 extern %1  
         %endif  
 %endmacro  
31    
32  ;***************************************************************************  ;=============================================================================
33  ; Local data  ; Local data (Read Only)
34  ;***************************************************************************  ;=============================================================================
35    
36  %ifdef FORMAT_COFF  DATA
 SECTION .data data  
 %else  
 SECTION .data data align=8  
 %endif  
37    
38  mmx_one:  mmx_one:
39          times 4 dw       1          times 4 dw       1
40    
41  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
42  ; divide by 2Q table  ; divide by 2Q table
43  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
44    
45  align 16  ALIGN SECTION_ALIGN
46  mmx_div:  mmx_div:
47  %assign quant 1          times 4 dw 65535 ; the div by 2 formula will overflow for the case
48  %rep 31                           ; quant=1 but we don't care much because quant=1
49                             ; is handled by a different piece of code that
50                             ; doesn't use this table.
51    %assign quant 2
52    %rep 30
53          times 4 dw  (1<<17) / (quant*2) + 1          times 4 dw  (1<<17) / (quant*2) + 1
54          %assign quant quant+1          %assign quant quant+1
55  %endrep  %endrep
56    
 ;===========================================================================  
 ;  
 ; intra matrix  
 ;  
 ;===========================================================================  
   
 cextern intra_matrix  
 cextern intra_matrix_fix  
   
 ;===========================================================================  
 ;  
 ; inter matrix  
 ;  
 ;===========================================================================  
   
 cextern inter_matrix  
 cextern inter_matrix_fix  
   
   
57  %define VM18P 3  %define VM18P 3
58  %define VM18Q 4  %define VM18Q 4
59    
60    
61  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
62  ; quantd table  ; quantd table
63  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
64    
65  quantd:  quantd:
66  %assign quant 1  %assign quant 1
# Line 113  Line 69 
69          %assign quant quant+1          %assign quant quant+1
70  %endrep  %endrep
71    
72  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
73  ; multiple by 2Q table  ; multiple by 2Q table
74  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
75    
76  mmx_mul_quant:  mmx_mul_quant:
77  %assign quant 1  %assign quant 1
# Line 126  Line 80 
80          %assign quant quant+1          %assign quant quant+1
81  %endrep  %endrep
82    
83  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
84  ; saturation limits  ; saturation limits
85  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
86    
87  align 16  ALIGN SECTION_ALIGN
88    
89  mmx_32767_minus_2047:  mmx_32767_minus_2047:
90          times 4 dw (32767-2047)          times 4 dw (32767-2047)
# Line 145  Line 97 
97  zero:  zero:
98          times 4 dw 0          times 4 dw 0
99    
100  ;***************************************************************************  ;=============================================================================
101  ; Local data  ; rounding
102  ;***************************************************************************  ;=============================================================================
   
 section .text  
   
 ;===========================================================================  
 ;  
 ; uint32_t quant_mpeg_intra_mmx(int16_t * coeff,  
 ;                               const int16_t const * data,  
 ;                               const uint32_t quant,  
 ;                               const uint32_t dcscalar);  
 ;  
 ;===========================================================================  
   
 align ALIGN  
 cglobal quant_mpeg_intra_mmx  
 quant_mpeg_intra_mmx:  
   
         push    ecx  
         push    esi  
         push    edi  
   
         mov             edi, [esp + 12 + 4]             ; coeff  
         mov             esi, [esp + 12 + 8]             ; data  
         mov             eax, [esp + 12 + 12]    ; quant  
103    
104          movq    mm5, [quantd + eax * 8 - 8] ; quantd -> mm5  ALIGN SECTION_ALIGN
105    
106          xor             ecx, ecx  mmx_rounding:
107          cmp             al, 1          dd (1<<13)
108          jz              near .q1loop          dd (1<<13)
   
         cmp             al, 2  
         jz              near .q2loop  
109    
110          movq    mm7, [mmx_div + eax * 8 - 8] ; multipliers[quant] -> mm7  ;=============================================================================
111    ; Code
112    ;=============================================================================
113    
114  align ALIGN  TEXT
 .loop  
         movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]  
         movq    mm3, [esi + 8*ecx + 8]  ;  
115    
116          pxor    mm1, mm1                ; mm1 = 0  cglobal quant_mpeg_intra_mmx
117          pxor    mm4, mm4  cglobal quant_mpeg_inter_mmx
118    cglobal dequant_mpeg_intra_mmx
119          pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)  cglobal dequant_mpeg_inter_mmx
         pcmpgtw mm4, mm3  
   
         pxor    mm0, mm1                ; mm0 = |mm0|  
         pxor    mm3, mm4                ;  
         psubw   mm0, mm1                ; displace  
         psubw   mm3, mm4                ;  
120    
         psllw   mm0, 4                  ; level << 4  
         psllw   mm3, 4                  ;  
121    
122          movq    mm2, [intra_matrix + 8*ecx]  %macro QUANT_MMX        1
123          psrlw   mm2, 1                  ; intra_matrix[i]>>1          movq    mm0, [_EAX + 16*(%1)]                   ; data
124          paddw   mm0, mm2          movq    mm2, [TMP0 + 16*(%1) + 128]             ; intra_matrix_rec
125            movq    mm4, [_EAX + 16*(%1) + 8]               ; data
126            movq    mm6, [TMP0 + 16*(%1) + 128 + 8] ; intra_matrix_rec
127    
128          movq    mm2, [intra_matrix_fix + ecx*8]          movq    mm1, mm0
129          pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]          movq    mm5, mm4
130    
131          movq    mm2, [intra_matrix + 8*ecx + 8]          pmullw  mm0, mm2                                        ; low results
132          psrlw   mm2, 1          pmulhw  mm1, mm2                                        ; high results
133          paddw   mm3, mm2          pmullw  mm4, mm6                                        ; low results
134            pmulhw  mm5, mm6                                        ; high results
135    
136            movq    mm2, mm0
137            movq    mm6, mm4
138    
139            punpckhwd mm0, mm1
140            punpcklwd mm2, mm1
141            punpckhwd mm4, mm5
142            punpcklwd mm6, mm5
143    
144            paddd   mm2, mm7
145            paddd   mm0, mm7
146            paddd   mm6, mm7
147            paddd   mm4, mm7
148    
149            psrad   mm2, 14
150            psrad   mm0, 14
151            psrad   mm6, 14
152            psrad   mm4, 14
153    
154          movq    mm2, [intra_matrix_fix + ecx*8 + 8]          packssdw mm2, mm0
155          pmulhw  mm3, mm2          packssdw mm6, mm4
156    
157          paddw   mm0, mm5                ; + quantd          movq    [TMP1 + 16*(%1)], mm2
158          paddw   mm3, mm5          movq    [TMP1 + 16*(%1)+8], mm6
159          pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16  %endmacro
         pmulhw  mm3, mm7                ;  
         psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17  
         psrlw   mm3, 1  
160    
161          pxor    mm0, mm1                ; mm0 *= sign(mm0)  ;-----------------------------------------------------------------------------
162          pxor    mm3, mm4                ;  ;
163          psubw   mm0, mm1                ; undisplace  ; uint32_t quant_mpeg_intra_mmx(int16_t * coeff,
164          psubw   mm3, mm4                ;  ;                               const int16_t const * data,
165    ;                               const uint32_t quant,
166    ;                               const uint32_t dcscalar,
167    ;                               const uint16_t *mpeg_matrices);
168    ;
169    ;-----------------------------------------------------------------------------
170    
171          movq    [edi + 8*ecx], mm0  ALIGN SECTION_ALIGN
172          movq    [edi + 8*ecx + 8], mm3  quant_mpeg_intra_mmx:
173    
174          add             ecx,2    mov _EAX, prm2                ; data
175          cmp             ecx,16    mov TMP0, prm5                ; mpeg_quant_matrices
176          jnz     near .loop    mov TMP1, prm1                ; coeff
177    
178      movq mm7, [mmx_rounding]
179    
180      QUANT_MMX(0)
181      QUANT_MMX(1)
182      QUANT_MMX(2)
183      QUANT_MMX(3)
184      QUANT_MMX(4)
185      QUANT_MMX(5)
186      QUANT_MMX(6)
187      QUANT_MMX(7)
188    
189      ; calculate DC
190      XVID_MOVSX _EAX, word [_EAX]   ; data[0]
191      mov TMP0, prm4            ; dcscalar
192      mov _EDX, _EAX
193      shr TMP0, 1               ; TMP0 = dcscalar/2
194      sar _EDX, 31              ; TMP1 = sign extend of _EAX (ready for division too)
195      xor TMP0, _EDX            ; adjust TMP0 according to the sign of data[0]
196      sub TMP0, _EDX
197      add _EAX, TMP0
198    
199  .done    mov TMP0, prm4            ; dcscalar
200                  ; caclulate  data[0] // (int32_t)dcscalar)    idiv TMP0                 ; _EAX = _EDX:_EAX / dcscalar
201    
202          mov     ecx, [esp + 12 + 16]    ; dcscalar    mov _EDX, prm1            ; coeff again
203          mov     edx, ecx    mov word [_EDX], ax       ; coeff[0] = ax
         movsx   eax, word [esi] ; data[0]  
         shr     edx, 1                  ; edx = dcscalar /2  
         cmp             eax, 0  
         jg              .gtzero  
   
         sub             eax, edx  
         jmp             short .mul  
 .gtzero  
         add             eax, edx  
 .mul  
         cdq                             ; expand eax -> edx:eax  
         idiv    ecx                     ; eax = edx:eax / dcscalar  
   
         mov     [edi], ax               ; coeff[0] = ax  
   
         pop     edi  
         pop     esi  
         pop     ecx  
204    
205          xor eax, eax                            ; return(0);    xor _EAX, _EAX            ; return(0);
206          ret          ret
207    ENDFUNC
208    
 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]  
   
         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  
209    
210          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  
   
   
 ;===========================================================================  
211  ;  ;
212  ; uint32_t quant_mpeg_inter_mmx(int16_t * coeff,  ; uint32_t quant_mpeg_inter_mmx(int16_t * coeff,
213  ;                               const int16_t const * data,  ;                               const int16_t const * data,
214  ;                               const uint32_t quant);  ;                               const uint32_t quant,
215    ;                               const uint16_t *mpeg_matrices);
216  ;  ;
217  ;===========================================================================  ;-----------------------------------------------------------------------------
218    
219  align ALIGN  ALIGN SECTION_ALIGN
 cglobal quant_mpeg_inter_mmx  
220  quant_mpeg_inter_mmx:  quant_mpeg_inter_mmx:
221    
222          push    ecx    mov TMP1, prm1           ; coeff
223          push    esi    mov _EAX, prm3           ; quant
224          push    edi    mov TMP0, prm4           ; mpeg_quant_matrices
225    
226          mov             edi, [esp + 12 + 4]             ; coeff    push _ESI
227          mov             esi, [esp + 12 + 8]             ; data  %ifdef ARCH_IS_X86_64
228          mov             eax, [esp + 12 + 12]    ; quant    mov _ESI, prm2           ; data
229    %else
230      mov _ESI, [_ESP + 4 + 8] ; data
231    %endif
232    
233          xor             ecx, ecx    push _EBX
234      xor _EBX, _EBX
235    
236          pxor    mm5, mm5                                        ; sum          pxor    mm5, mm5                                        ; sum
237    
# Line 398  Line 241 
241          cmp             al, 2          cmp             al, 2
242          jz              near .q2loop          jz              near .q2loop
243    
244          movq    mm7, [mmx_div + eax * 8 - 8]    ; divider  %ifdef ARCH_IS_X86_64
245      lea r9, [mmx_div]
246      movq mm7, [r9 + _EAX * 8 - 8]
247    %else
248      movq mm7, [mmx_div + _EAX * 8 - 8] ; divider
249    %endif
250    
251  align ALIGN  ALIGN SECTION_ALIGN
252  .loop  .loop:
253          movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]    movq mm0, [_ESI + 8*_EBX]       ; mm0 = [1st]
254          movq    mm3, [esi + 8*ecx + 8]  ;    movq mm3, [_ESI + 8*_EBX + 8]   ;
255          pxor    mm1, mm1                ; mm1 = 0          pxor    mm1, mm1                ; mm1 = 0
256          pxor    mm4, mm4                ;          pxor    mm4, mm4                ;
257          pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)          pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
# Line 412  Line 260 
260          pxor    mm3, mm4                ;          pxor    mm3, mm4                ;
261          psubw   mm0, mm1                ; displace          psubw   mm0, mm1                ; displace
262          psubw   mm3, mm4                ;          psubw   mm3, mm4                ;
   
263          psllw   mm0, 4          psllw   mm0, 4
264          psllw   mm3, 4          psllw   mm3, 4
265      movq mm2, [TMP0 + 512 + 8*_EBX]
         movq    mm2, [inter_matrix + 8*ecx]  
266          psrlw   mm2, 1          psrlw   mm2, 1
267          paddw   mm0, mm2          paddw   mm0, mm2
268      movq mm2, [TMP0 + 768 + _EBX*8]
         movq    mm2, [inter_matrix_fix + ecx*8]  
269          pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]          pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
270      movq mm2, [TMP0 + 512 + 8*_EBX + 8]
         movq    mm2, [inter_matrix + 8*ecx + 8]  
271          psrlw   mm2, 1          psrlw   mm2, 1
272          paddw   mm3, mm2          paddw   mm3, mm2
273      movq mm2, [TMP0 + 768 + _EBX*8 + 8]
         movq    mm2, [inter_matrix_fix + ecx*8 + 8]  
274          pmulhw  mm3, mm2          pmulhw  mm3, mm2
   
275          pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16          pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16
276          pmulhw  mm3, mm7                ;          pmulhw  mm3, mm7                ;
277          psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17          psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17
278          psrlw   mm3, 1          psrlw   mm3, 1
   
279          paddw   mm5, mm0                ; sum += mm0          paddw   mm5, mm0                ; sum += mm0
280          pxor    mm0, mm1                ; mm0 *= sign(mm0)          pxor    mm0, mm1                ; mm0 *= sign(mm0)
281          paddw   mm5, mm3                ;          paddw   mm5, mm3                ;
282          pxor    mm3, mm4                ;          pxor    mm3, mm4                ;
283          psubw   mm0, mm1                ; undisplace          psubw   mm0, mm1                ; undisplace
284          psubw   mm3, mm4          psubw   mm3, mm4
285          movq    [edi + 8*ecx], mm0    movq [TMP1 + 8*_EBX], mm0
286          movq    [edi + 8*ecx + 8], mm3    movq [TMP1 + 8*_EBX + 8], mm3
287    
288          add             ecx, 2    add _EBX, 2
289          cmp             ecx, 16    cmp _EBX, 16
290          jnz             near .loop          jnz             near .loop
291    
292  .done  .done:
293          pmaddwd mm5, [mmx_one]          pmaddwd mm5, [mmx_one]
294          movq    mm0, mm5          movq    mm0, mm5
295          psrlq   mm5, 32          psrlq   mm5, 32
296          paddd   mm0, mm5          paddd   mm0, mm5
297          movd    eax, mm0                ; return sum          movd    eax, mm0                ; return sum
298    
299          pop             edi    pop _EBX
300          pop             esi    pop _ESI
         pop             ecx  
301    
302          ret          ret
303    
304  align ALIGN  ALIGN SECTION_ALIGN
305  .q1loop  .q1loop:
306          movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]    movq mm0, [_ESI + 8*_EBX]       ; mm0 = [1st]
307          movq    mm3, [esi + 8*ecx+ 8]    movq mm3, [_ESI + 8*_EBX+ 8]
                                 ;  
308          pxor    mm1, mm1                ; mm1 = 0          pxor    mm1, mm1                ; mm1 = 0
309          pxor    mm4, mm4                ;          pxor    mm4, mm4                ;
   
310          pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)          pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
311          pcmpgtw mm4, mm3                ;          pcmpgtw mm4, mm3                ;
   
312          pxor    mm0, mm1                ; mm0 = |mm0|          pxor    mm0, mm1                ; mm0 = |mm0|
313          pxor    mm3, mm4                ;          pxor    mm3, mm4                ;
314          psubw   mm0, mm1                ; displace          psubw   mm0, mm1                ; displace
315          psubw   mm3, mm4                ;          psubw   mm3, mm4                ;
   
316          psllw   mm0, 4          psllw   mm0, 4
317          psllw   mm3, 4          psllw   mm3, 4
318      movq mm2, [TMP0 + 512 + 8*_EBX]
         movq    mm2, [inter_matrix + 8*ecx]  
319          psrlw   mm2, 1          psrlw   mm2, 1
320          paddw   mm0, mm2          paddw   mm0, mm2
321      movq mm2, [TMP0 + 768 + _EBX*8]
         movq    mm2, [inter_matrix_fix + ecx*8]  
322          pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]          pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
323      movq mm2, [TMP0 + 512 + 8*_EBX + 8]
         movq    mm2, [inter_matrix + 8*ecx + 8]  
324          psrlw   mm2, 1          psrlw   mm2, 1
325          paddw   mm3, mm2          paddw   mm3, mm2
326      movq mm2, [TMP0 + 768 + _EBX*8 + 8]
         movq    mm2, [inter_matrix_fix + ecx*8 + 8]  
327          pmulhw  mm3, mm2          pmulhw  mm3, mm2
   
328          psrlw   mm0, 1                  ; mm0 >>= 1   (/2)          psrlw   mm0, 1                  ; mm0 >>= 1   (/2)
329          psrlw   mm3, 1                  ;          psrlw   mm3, 1                  ;
   
330          paddw   mm5, mm0                ; sum += mm0          paddw   mm5, mm0                ; sum += mm0
331          pxor    mm0, mm1                ; mm0 *= sign(mm0)          pxor    mm0, mm1                ; mm0 *= sign(mm0)
332          paddw   mm5, mm3                ;          paddw   mm5, mm3                ;
333          pxor    mm3, mm4                ;          pxor    mm3, mm4                ;
334          psubw   mm0, mm1                ; undisplace          psubw   mm0, mm1                ; undisplace
335          psubw   mm3, mm4          psubw   mm3, mm4
336      movq [TMP1 + 8*_EBX], mm0
337      movq [TMP1 + 8*_EBX + 8], mm3
338    
339          movq    [edi + 8*ecx], mm0    add _EBX, 2
340          movq    [edi + 8*ecx + 8], mm3    cmp _EBX, 16
   
         add             ecx, 2  
         cmp             ecx, 16  
341          jnz             near .q1loop          jnz             near .q1loop
342    
343          jmp             .done          jmp             .done
344    
345    ALIGN SECTION_ALIGN
346  align ALIGN  .q2loop:
347  .q2loop    movq mm0, [_ESI + 8*_EBX]       ; mm0 = [1st]
348          movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]    movq mm3, [_ESI + 8*_EBX+ 8]
         movq    mm3, [esi + 8*ecx+ 8]  
                                 ;  
349          pxor    mm1, mm1                ; mm1 = 0          pxor    mm1, mm1                ; mm1 = 0
350          pxor    mm4, mm4                ;          pxor    mm4, mm4                ;
   
351          pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)          pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
352          pcmpgtw mm4, mm3                ;          pcmpgtw mm4, mm3                ;
   
353          pxor    mm0, mm1                ; mm0 = |mm0|          pxor    mm0, mm1                ; mm0 = |mm0|
354          pxor    mm3, mm4                ;          pxor    mm3, mm4                ;
355          psubw   mm0, mm1                ; displace          psubw   mm0, mm1                ; displace
356          psubw   mm3, mm4                ;          psubw   mm3, mm4                ;
   
357          psllw   mm0, 4          psllw   mm0, 4
358          psllw   mm3, 4          psllw   mm3, 4
359      movq mm2, [TMP0 + 512 + 8*_EBX]
         movq    mm2, [inter_matrix + 8*ecx]  
360          psrlw   mm2, 1          psrlw   mm2, 1
361          paddw   mm0, mm2          paddw   mm0, mm2
362      movq mm2, [TMP0 + 768 + _EBX*8]
         movq    mm2, [inter_matrix_fix + ecx*8]  
363          pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]          pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
364      movq mm2, [TMP0 + 512 + 8*_EBX + 8]
         movq    mm2, [inter_matrix + 8*ecx + 8]  
365          psrlw   mm2, 1          psrlw   mm2, 1
366          paddw   mm3, mm2          paddw   mm3, mm2
367      movq mm2, [TMP0 + 768 + _EBX*8 + 8]
         movq    mm2, [inter_matrix_fix + ecx*8 + 8]  
368          pmulhw  mm3, mm2          pmulhw  mm3, mm2
   
369          psrlw   mm0, 2                  ; mm0 >>= 1   (/2)          psrlw   mm0, 2                  ; mm0 >>= 1   (/2)
370          psrlw   mm3, 2                  ;          psrlw   mm3, 2                  ;
   
371          paddw   mm5, mm0                ; sum += mm0          paddw   mm5, mm0                ; sum += mm0
372          pxor    mm0, mm1                ; mm0 *= sign(mm0)          pxor    mm0, mm1                ; mm0 *= sign(mm0)
373          paddw   mm5, mm3                ;          paddw   mm5, mm3                ;
374          pxor    mm3, mm4                ;          pxor    mm3, mm4                ;
375          psubw   mm0, mm1                ; undisplace          psubw   mm0, mm1                ; undisplace
376          psubw   mm3, mm4          psubw   mm3, mm4
377      movq [TMP1 + 8*_EBX], mm0
378      movq [TMP1 + 8*_EBX + 8], mm3
379    
380          movq    [edi + 8*ecx], mm0    add _EBX, 2
381          movq    [edi + 8*ecx + 8], mm3    cmp _EBX, 16
   
         add             ecx, 2  
         cmp             ecx, 16  
382          jnz             near .q2loop          jnz             near .q2loop
383    
384          jmp     .done          jmp     .done
385    ENDFUNC
386    
387    
388  ;===========================================================================  ;-----------------------------------------------------------------------------
389  ;  ;
390  ; uint32_t dequant_mpeg_intra_mmx(int16_t *data,  ; uint32_t dequant_mpeg_intra_mmx(int16_t *data,
391  ;                                 const int16_t const *coeff,  ;                                 const int16_t const *coeff,
392  ;                                 const uint32_t quant,  ;                                 const uint32_t quant,
393  ;                                 const uint32_t dcscalar);  ;                                 const uint32_t dcscalar,
394    ;                                 const uint16_t *mpeg_matrices);
395  ;  ;
396  ;===========================================================================  ;-----------------------------------------------------------------------------
397    
398    ;   Note: in order to saturate 'easily', we pre-shift the quantifier    ;   Note: in order to saturate 'easily', we pre-shift the quantifier
399    ; 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 588  Line 407 
407    ; The original loop is:    ; The original loop is:
408    ;    ;
409  %if 0  %if 0
410          movq    mm0, [ecx+8*eax + 8*16]   ; mm0 = coeff[i]    movq mm0, [TMP0+8*_EAX + 8*16]   ; mm0 = coeff[i]
411          pxor    mm1, mm1          pxor    mm1, mm1
412          pcmpgtw mm1, mm0          pcmpgtw mm1, mm0
413          pxor    mm0, mm1     ; change sign if negative          pxor    mm0, mm1     ; change sign if negative
414          psubw   mm0, mm1    ; -> mm0 = abs(coeff[i]), mm1 = sign of coeff[i]          psubw   mm0, mm1    ; -> mm0 = abs(coeff[i]), mm1 = sign of coeff[i]
415    
416          movq    mm2, mm7     ; mm2 = quant          movq    mm2, mm7     ; mm2 = quant
417          pmullw  mm2, [intra_matrix + 8*eax + 8*16 ]  ; matrix[i]*quant.    pmullw mm2, [_EBX + 8*_EAX + 8*16 ]  ; matrix[i]*quant.
418    
419          movq    mm6, mm2          movq    mm6, mm2
420          pmulhw  mm2, mm0   ; high of coeff*(matrix*quant)  (should be 0 if no overflow)          pmulhw  mm2, mm0   ; high of coeff*(matrix*quant)  (should be 0 if no overflow)
# Line 609  Line 428 
428          por             mm0, mm2      ; saturate to 2047 if needed          por             mm0, mm2      ; saturate to 2047 if needed
429          pxor    mm0, mm1     ; finish negating back          pxor    mm0, mm1     ; finish negating back
430    
431          movq    [edx + 8*eax + 8*16], mm0   ; data[i]    movq [TMP1 + 8*_EAX + 8*16], mm0   ; data[i]
432          add             eax, 1    add _EAX, 1
433  %endif  %endif
434    
435    ;********************************************************************    ;********************************************************************
436    
437  align 16  ALIGN SECTION_ALIGN
 cglobal dequant_mpeg_intra_mmx  
438  dequant_mpeg_intra_mmx:  dequant_mpeg_intra_mmx:
439    
440          mov             edx, [esp+4]  ; data    mov TMP1, prm1  ; data
441          mov             ecx, [esp+8]  ; coeff    mov TMP0, prm2  ; coeff
442          mov             eax, [esp+12] ; quant    mov _EAX, prm5  ; mpeg_quant_matrices
443    
444      push _EBX
445      mov _EBX, _EAX
446    %ifdef ARCH_IS_X86_64
447      mov _EAX, prm3
448      lea prm1, [mmx_mul_quant]
449      movq mm7, [prm1 + _EAX*8 - 8]
450    %else
451      mov _EAX, [_ESP + 4 + 12] ; quant
452      movq mm7, [mmx_mul_quant  + _EAX*8 - 8]
453    %endif
454    
455          movq    mm7, [mmx_mul_quant  + eax*8 - 8]    mov _EAX, -16      ; to keep ALIGNed, we regularly process coeff[0]
         mov             eax, -16   ; to keep aligned, we regularly process coeff[0]  
456          psllw   mm7, 2   ; << 2. See comment.          psllw   mm7, 2   ; << 2. See comment.
457          pxor    mm6, mm6   ; this is a NOP          pxor    mm6, mm6   ; this is a NOP
458    
459  align 16  ALIGN SECTION_ALIGN
460  .loop  .loop:
461          movq    mm0, [ecx+8*eax + 8*16]   ; mm0 = c  = coeff[i]    movq mm0, [TMP0+8*_EAX + 8*16]   ; mm0 = c  = coeff[i]
462          movq    mm3, [ecx+8*eax + 8*16 +8]; mm3 = c' = coeff[i+1]    movq mm3, [TMP0+8*_EAX + 8*16 +8]; mm3 = c' = coeff[i+1]
463          pxor    mm1, mm1          pxor    mm1, mm1
464          pxor    mm4, mm4          pxor    mm4, mm4
465          pcmpgtw mm1, mm0  ; mm1 = sgn(c)          pcmpgtw mm1, mm0  ; mm1 = sgn(c)
466          movq    mm2, mm7     ; mm2 = quant          movq    mm2, mm7     ; mm2 = quant
467    
468          pcmpgtw mm4, mm3  ; mm4 = sgn(c')          pcmpgtw mm4, mm3  ; mm4 = sgn(c')
469          pmullw  mm2,  [intra_matrix + 8*eax + 8*16 ]  ; matrix[i]*quant    pmullw mm2,  [_EBX + 8*_EAX + 8*16 ]  ; matrix[i]*quant
470    
471          pxor    mm0, mm1     ; negate if negative          pxor    mm0, mm1     ; negate if negative
472          pxor    mm3, mm4     ; negate if negative          pxor    mm3, mm4     ; negate if negative
# Line 654  Line 482 
482          pmulhw  mm0, mm5   ; high of coeff*(matrix*quant)          pmulhw  mm0, mm5   ; high of coeff*(matrix*quant)
483          movq    mm5, mm7     ; mm2 = quant          movq    mm5, mm7     ; mm2 = quant
484    
485          pmullw  mm5,  [intra_matrix + 8*eax + 8*16 +8]  ; matrix[i+1]*quant    pmullw mm5,  [_EBX + 8*_EAX + 8*16 +8]  ; matrix[i+1]*quant
486    
487          movq    mm6, mm5          movq    mm6, mm5
488          add             eax,2   ; z-flag will be tested later    add _EAX,2   ; z-flag will be tested later
489    
490          pmullw  mm6, mm3   ; low  of coeff*(matrix*quant)          pmullw  mm6, mm3   ; low  of coeff*(matrix*quant)
491          pmulhw  mm3, mm5   ; high of coeff*(matrix*quant)          pmulhw  mm3, mm5   ; high of coeff*(matrix*quant)
# Line 679  Line 507 
507          psubw   mm2, mm1 ; finish negating back          psubw   mm2, mm1 ; finish negating back
508          psubw   mm6, mm4 ; finish negating back          psubw   mm6, mm4 ; finish negating back
509    
510          movq    [edx + 8*eax + 8*16   -2*8   ], mm2   ; data[i]    movq [TMP1 + 8*_EAX + 8*16   -2*8   ], mm2   ; data[i]
511          movq    [edx + 8*eax + 8*16   -2*8 +8], mm6   ; data[i+1]    movq [TMP1 + 8*_EAX + 8*16   -2*8 +8], mm6   ; data[i+1]
512    
513          jnz             near .loop          jnz             near .loop
514    
515      ; deal with DC    pop _EBX
516    
517          movd    mm0, [ecx]      ; deal with DC
518          pmullw  mm0, [esp+16]  ; dcscalar    movd mm0, [TMP0]
519    %ifdef ARCH_IS_X86_64
520      movq mm6, prm4
521      pmullw mm0, mm6
522    %else
523      pmullw mm0, prm4  ; dcscalar
524    %endif
525          movq    mm2, [mmx_32767_minus_2047]          movq    mm2, [mmx_32767_minus_2047]
526          paddsw  mm0, mm2          paddsw  mm0, mm2
527          psubsw  mm0, mm2          psubsw  mm0, mm2
# Line 695  Line 529 
529          psubsw  mm0, mm2          psubsw  mm0, mm2
530          paddsw  mm0, mm2          paddsw  mm0, mm2
531          movd    eax, mm0          movd    eax, mm0
532          mov             [edx], ax    mov [TMP1], ax
533    
534      xor _EAX, _EAX
535    
         xor             eax, eax  
536          ret          ret
537    ENDFUNC
538    
539  ;===========================================================================  ;-----------------------------------------------------------------------------
540  ;  ;
541  ; uint32_t dequant_mpeg_inter_mmx(int16_t * data,  ; uint32_t dequant_mpeg_inter_mmx(int16_t * data,
542  ;                                 const int16_t * const coeff,  ;                                 const int16_t * const coeff,
543  ;                                 const uint32_t quant);  ;                                 const uint32_t quant,
544    ;                                 const uint16_t *mpeg_matrices);
545  ;  ;
546  ;===========================================================================  ;-----------------------------------------------------------------------------
547    
548      ; Note:  We use (2*c + sgn(c) - sgn(-c)) as multiplier      ; Note:  We use (2*c + sgn(c) - sgn(-c)) as multiplier
549      ; 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.
550      ; sgn(x) is the result of 'pcmpgtw 0,x':  0 if x>=0, -1 if x<0.      ; sgn(x) is the result of 'pcmpgtw 0,x':  0 if x>=0, -1 if x<0.
551      ; It's mixed with the extraction of the absolute value.      ; It's mixed with the extraction of the absolute value.
552    
553  align 16  ALIGN SECTION_ALIGN
 cglobal dequant_mpeg_inter_mmx  
554  dequant_mpeg_inter_mmx:  dequant_mpeg_inter_mmx:
555    
556          mov             edx, [esp+ 4]        ; data  
557          mov             ecx, [esp+ 8]        ; coeff    mov TMP1, prm1        ; data
558          mov             eax, [esp+12]        ; quant    mov TMP0, prm2        ; coeff
559          movq    mm7, [mmx_mul_quant  + eax*8 - 8]    mov _EAX, prm3        ; quant
560          mov             eax, -16  
561      push _EBX
562    %ifdef ARCH_IS_X86_64
563      mov _EBX, prm4
564      lea r9, [mmx_mul_quant]
565      movq mm7, [r9 + _EAX*8 - 8]
566    %else
567      mov _EBX, [_ESP + 4 + 16]     ; mpeg_quant_matrices
568      movq mm7, [mmx_mul_quant  + _EAX*8 - 8]
569    %endif
570    
571      mov _EAX, -16
572          paddw   mm7, mm7    ; << 1          paddw   mm7, mm7    ; << 1
573          pxor    mm6, mm6 ; mismatch sum          pxor    mm6, mm6 ; mismatch sum
574    
575  align 16  ALIGN SECTION_ALIGN
576  .loop  .loop:
577          movq    mm0, [ecx+8*eax + 8*16   ]   ; mm0 = coeff[i]    movq mm0, [TMP0+8*_EAX + 8*16   ]   ; mm0 = coeff[i]
578          movq    mm2, [ecx+8*eax + 8*16 +8]   ; mm2 = coeff[i+1]    movq mm2, [TMP0+8*_EAX + 8*16 +8]   ; mm2 = coeff[i+1]
579          add             eax, 2    add _EAX, 2
580    
581          pxor    mm1, mm1          pxor    mm1, mm1
582          pxor    mm3, mm3          pxor    mm3, mm3
# Line 754  Line 601 
601      ; we're short on register, here. Poor pairing...      ; we're short on register, here. Poor pairing...
602    
603          movq    mm4, mm7     ; (matrix*quant)          movq    mm4, mm7     ; (matrix*quant)
604          pmullw  mm4,  [inter_matrix + 8*eax + 8*16 -2*8]    pmullw mm4,  [_EBX + 512 + 8*_EAX + 8*16 -2*8]
605          movq    mm5, mm4          movq    mm5, mm4
606          pmulhw  mm5, mm0   ; high of c*(matrix*quant)          pmulhw  mm5, mm0   ; high of c*(matrix*quant)
607          pmullw  mm0, mm4   ; low  of c*(matrix*quant)          pmullw  mm0, mm4   ; low  of c*(matrix*quant)
608    
609          movq    mm4, mm7     ; (matrix*quant)          movq    mm4, mm7     ; (matrix*quant)
610          pmullw  mm4,  [inter_matrix + 8*eax + 8*16 -2*8 + 8]    pmullw mm4,  [_EBX + 512 + 8*_EAX + 8*16 -2*8 + 8]
611    
612          pcmpgtw mm5, [zero]          pcmpgtw mm5, [zero]
613          paddusw mm0, mm5          paddusw mm0, mm5
# Line 781  Line 628 
628          psubw   mm2, mm3   ; finish restoring sign          psubw   mm2, mm3   ; finish restoring sign
629    
630          pxor    mm6, mm0     ; mismatch control          pxor    mm6, mm0     ; mismatch control
631          movq    [edx + 8*eax + 8*16 -2*8   ], mm0   ; data[i]    movq [TMP1 + 8*_EAX + 8*16 -2*8   ], mm0   ; data[i]
632          pxor    mm6, mm2     ; mismatch control          pxor    mm6, mm2     ; mismatch control
633          movq    [edx + 8*eax + 8*16 -2*8 +8], mm2   ; data[i+1]    movq [TMP1 + 8*_EAX + 8*16 -2*8 +8], mm2   ; data[i+1]
634    
635          jnz             near .loop          jnz             near .loop
636    
# Line 799  Line 646 
646          pxor    mm6, mm1          pxor    mm6, mm1
647          pxor    mm6, mm2          pxor    mm6, mm2
648          movd    eax, mm6          movd    eax, mm6
649          and             eax, 1    and _EAX, 1
650          xor             eax, 1    xor _EAX, 1
651          xor             word [edx + 2*63], ax    xor word [TMP1 + 2*63], ax
652    
653      xor _EAX, _EAX
654    
655      pop _EBX
656    
         xor             eax, eax  
657          ret          ret
658    ENDFUNC
659    
660    
661    %ifidn __OUTPUT_FORMAT__,elf
662    section ".note.GNU-stack" noalloc noexec nowrite progbits
663    %endif
664    

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

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