[cvs] / xvidcore / src / quant / x86_asm / quantize_h263_mmx.asm Repository:
ViewVC logotype

Diff of /xvidcore/src/quant/x86_asm/quantize_h263_mmx.asm

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

revision 1.1.2.1, Tue Oct 7 13:02:35 2003 UTC revision 1.8, Tue Aug 19 09:06:48 2008 UTC
# Line 1  Line 1 
1  ;/**************************************************************************  ;/*****************************************************************************
2  ; *  ; *
3  ; *     XVID MPEG-4 VIDEO CODEC  ; *     XVID MPEG-4 VIDEO CODEC
4  ; *     mmx quantization/dequantization  ; *  - MPEG4 Quantization H263 implementation / MMX optimized -
5  ; *  ; *
6  ; *     This program is an implementation of a part of one or more MPEG-4  ; *  Copyright(C) 2001-2003 Peter Ross <pross@xvid.org>
7  ; *     Video tools as specified in ISO/IEC 14496-2 standard.  Those intending  ; *               2002-2003 Pascal Massimino <skal@planet-d.net>
8  ; *     to use this software module in hardware or software products are  ; *               2004      Jean-Marc Bastide <jmtest@voila.fr>
 ; *     advised that its use may infringe existing patents or copyrights, and  
 ; *     any such use would be at such party's own risk.  The original  
 ; *     developer of this software module and his/her company, and subsequent  
 ; *     editors and their companies, will have no liability for use of this  
 ; *     software or modifications or derivatives thereof.  
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
11  ; *     it under the terms of the GNU General Public License as published by  ; *     it under the terms of the GNU General Public License as published by
# Line 24  Line 19 
19  ; *  ; *
20  ; *     You should have received a copy of the GNU General Public License  ; *     You should have received a copy of the GNU General Public License
21  ; *     along with this program; if not, write to the Free Software  ; *     along with this program; if not, write to the Free Software
22  ; *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  ; *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23  ; *  ; *
24  ; *************************************************************************/  ; * $Id$
   
 ;/**************************************************************************  
 ; *  
 ; *     History:  
 ; *  
 ; * 09.08.2002  sse2 dequant funcs revamped  
 ; * 14.06.2002  mmx+xmm dequant_* funcs revamped  -Skal-  
 ; * 24.02.2002  sse2 quant_intra / dequant_intra (have to use movdqu ???)  
 ; * 17.04.2002  sse2 quant_inter / dequant_inter  
 ; * 26.12.2001  minor bug fixes, dequant saturate, further optimization  
 ; * 19.11.2001  quant_inter_mmx now returns sum of abs. coefficient values  
 ; *     04.11.2001      nasm version; (c)2001 peter ross <pross@cs.rmit.edu.au>  
25  ; *  ; *
26  ; *************************************************************************/  ; ****************************************************************************/
27    
28  ; enable dequant saturate [-2048,2047], test purposes only.  ; enable dequant saturate [-2048,2047], test purposes only.
29  %define SATURATE  %define SATURATE
30    
31  ; data/text alignment  BITS 32
 %define ALIGN 8  
   
 bits 32  
   
 section .data  
   
32    
33  %macro cglobal 1  %macro cglobal 1
34          %ifdef PREFIX          %ifdef PREFIX
35                    %ifdef MARK_FUNCS
36                            global _%1:function %1.endfunc-%1
37                            %define %1 _%1:function %1.endfunc-%1
38                    %else
39                  global _%1                  global _%1
40                  %define %1 _%1                  %define %1 _%1
41                    %endif
42            %else
43                    %ifdef MARK_FUNCS
44                            global %1:function %1.endfunc-%1
45          %else          %else
46                  global %1                  global %1
47          %endif          %endif
48            %endif
49  %endmacro  %endmacro
50    
51  align 16  ;=============================================================================
52    ; Read only Local data
53    ;=============================================================================
54    
55  plus_one times 8        dw       1  %ifdef FORMAT_COFF
56    SECTION .rodata
57    %else
58    SECTION .rodata align=16
59    %endif
60    
61  ;===========================================================================  ALIGN 16
62    plus_one:
63            times 8 dw 1
64    
65    ;-----------------------------------------------------------------------------
66  ;  ;
67  ; subtract by Q/2 table  ; quant table
68  ;  ;
69  ;===========================================================================  ;-----------------------------------------------------------------------------
70    
71  %macro MMX_SUB  1  ALIGN 16
72  times 4 dw %1 / 2  mmx_quant:
73  %endmacro  %assign quant 0
74    %rep 32
75  align 16          times 4 dw quant
76  mmx_sub          %assign quant quant+1
77                  MMX_SUB 1  %endrep
                 MMX_SUB 2  
                 MMX_SUB 3  
                 MMX_SUB 4  
                 MMX_SUB 5  
                 MMX_SUB 6  
                 MMX_SUB 7  
                 MMX_SUB 8  
                 MMX_SUB 9  
                 MMX_SUB 10  
                 MMX_SUB 11  
                 MMX_SUB 12  
                 MMX_SUB 13  
                 MMX_SUB 14  
                 MMX_SUB 15  
                 MMX_SUB 16  
                 MMX_SUB 17  
                 MMX_SUB 18  
                 MMX_SUB 19  
                 MMX_SUB 20  
                 MMX_SUB 21  
                 MMX_SUB 22  
                 MMX_SUB 23  
                 MMX_SUB 24  
                 MMX_SUB 25  
                 MMX_SUB 26  
                 MMX_SUB 27  
                 MMX_SUB 28  
                 MMX_SUB 29  
                 MMX_SUB 30  
                 MMX_SUB 31  
78    
79    ;-----------------------------------------------------------------------------
80    ;
81    ; subtract by Q/2 table
82    ;
83    ;-----------------------------------------------------------------------------
84    
85    ALIGN 16
86    mmx_sub:
87    %assign quant 1
88    %rep 31
89            times 4 dw  quant / 2
90            %assign quant quant+1
91    %endrep
92    
93  ;===========================================================================  ;-----------------------------------------------------------------------------
94  ;  ;
95  ; divide by 2Q table  ; divide by 2Q table
96  ;  ;
# Line 120  Line 98 
98  ; for q=1, _pmulhw_ will overflow so it is treated seperately  ; for q=1, _pmulhw_ will overflow so it is treated seperately
99  ; (3dnow2 provides _pmulhuw_ which wont cause overflow)  ; (3dnow2 provides _pmulhuw_ which wont cause overflow)
100  ;  ;
101  ;===========================================================================  ;-----------------------------------------------------------------------------
   
 %macro MMX_DIV  1  
 times 4 dw  (1 << 16) / (%1 * 2) + 1  
 %endmacro  
   
 align 16  
 mmx_div  
                 MMX_DIV 1  
                 MMX_DIV 2  
                 MMX_DIV 3  
                 MMX_DIV 4  
                 MMX_DIV 5  
                 MMX_DIV 6  
                 MMX_DIV 7  
                 MMX_DIV 8  
                 MMX_DIV 9  
                 MMX_DIV 10  
                 MMX_DIV 11  
                 MMX_DIV 12  
                 MMX_DIV 13  
                 MMX_DIV 14  
                 MMX_DIV 15  
                 MMX_DIV 16  
                 MMX_DIV 17  
                 MMX_DIV 18  
                 MMX_DIV 19  
                 MMX_DIV 20  
                 MMX_DIV 21  
                 MMX_DIV 22  
                 MMX_DIV 23  
                 MMX_DIV 24  
                 MMX_DIV 25  
                 MMX_DIV 26  
                 MMX_DIV 27  
                 MMX_DIV 28  
                 MMX_DIV 29  
                 MMX_DIV 30  
                 MMX_DIV 31  
   
   
   
 ;===========================================================================  
 ;  
 ; add by (odd(Q) ? Q : Q - 1) table  
 ;  
 ;===========================================================================  
   
 %macro MMX_ADD  1  
 %if %1 % 2 != 0  
 times 4 dw %1  
 %else  
 times 4 dw %1 - 1  
 %endif  
 %endmacro  
   
 align 16  
 mmx_add  
                 MMX_ADD 1  
                 MMX_ADD 2  
                 MMX_ADD 3  
                 MMX_ADD 4  
                 MMX_ADD 5  
                 MMX_ADD 6  
                 MMX_ADD 7  
                 MMX_ADD 8  
                 MMX_ADD 9  
                 MMX_ADD 10  
                 MMX_ADD 11  
                 MMX_ADD 12  
                 MMX_ADD 13  
                 MMX_ADD 14  
                 MMX_ADD 15  
                 MMX_ADD 16  
                 MMX_ADD 17  
                 MMX_ADD 18  
                 MMX_ADD 19  
                 MMX_ADD 20  
                 MMX_ADD 21  
                 MMX_ADD 22  
                 MMX_ADD 23  
                 MMX_ADD 24  
                 MMX_ADD 25  
                 MMX_ADD 26  
                 MMX_ADD 27  
                 MMX_ADD 28  
                 MMX_ADD 29  
                 MMX_ADD 30  
                 MMX_ADD 31  
   
   
 ;===========================================================================  
 ;  
 ; multiple by 2Q table  
 ;  
 ;===========================================================================  
   
 %macro MMX_MUL  1  
 times 4 dw %1 * 2  
 %endmacro  
   
 align 16  
 mmx_mul  
                 MMX_MUL 1  
                 MMX_MUL 2  
                 MMX_MUL 3  
                 MMX_MUL 4  
                 MMX_MUL 5  
                 MMX_MUL 6  
                 MMX_MUL 7  
                 MMX_MUL 8  
                 MMX_MUL 9  
                 MMX_MUL 10  
                 MMX_MUL 11  
                 MMX_MUL 12  
                 MMX_MUL 13  
                 MMX_MUL 14  
                 MMX_MUL 15  
                 MMX_MUL 16  
                 MMX_MUL 17  
                 MMX_MUL 18  
                 MMX_MUL 19  
                 MMX_MUL 20  
                 MMX_MUL 21  
                 MMX_MUL 22  
                 MMX_MUL 23  
                 MMX_MUL 24  
                 MMX_MUL 25  
                 MMX_MUL 26  
                 MMX_MUL 27  
                 MMX_MUL 28  
                 MMX_MUL 29  
                 MMX_MUL 30  
                 MMX_MUL 31  
   
   
 ;===========================================================================  
 ;  
 ; saturation limits  
 ;  
 ;===========================================================================  
   
 align 16  
 sse2_2047       times 8 dw 2047  
   
 align 16  
 mmx_2047        times 4 dw 2047  
   
 align 8  
 mmx_32768_minus_2048                            times 4 dw (32768-2048)  
 mmx_32767_minus_2047                            times 4 dw (32767-2047)  
102    
103    ALIGN 16
104    mmx_div:
105    %assign quant 1
106    %rep 31
107            times 4 dw  (1<<16) / (quant*2) + 1
108            %assign quant quant+1
109    %endrep
110    
111    ;=============================================================================
112    ; Code
113    ;=============================================================================
114    
115  section .text  SECTION .text
116    
117    cglobal quant_h263_intra_mmx
118    cglobal quant_h263_intra_sse2
119    cglobal quant_h263_inter_mmx
120    cglobal quant_h263_inter_sse2
121    cglobal dequant_h263_intra_mmx
122    cglobal dequant_h263_intra_xmm
123    cglobal dequant_h263_intra_sse2
124    cglobal dequant_h263_inter_mmx
125    cglobal dequant_h263_inter_xmm
126    cglobal dequant_h263_inter_sse2
127    
128  ;===========================================================================  ;-----------------------------------------------------------------------------
129  ;  ;
130  ; void quant_intra_mmx(int16_t * coeff,  ; uint32_t quant_h263_intra_mmx(int16_t * coeff,
131  ;                                       const int16_t const * data,  ;                                       const int16_t const * data,
132  ;                                       const uint32_t quant,  ;                                       const uint32_t quant,
133  ;                                       const uint32_t dcscalar);  ;                               const uint32_t dcscalar,
134    ;                               const uint16_t *mpeg_matrices);
135  ;  ;
136  ;===========================================================================  ;-----------------------------------------------------------------------------
137    
138  align ALIGN  ALIGN 16
 cglobal quant_h263_intra_mmx  
139  quant_h263_intra_mmx:  quant_h263_intra_mmx:
140    
                 push    ecx  
141                  push    esi                  push    esi
                 push    edi  
   
                 mov     edi, [esp + 12 + 4]             ; coeff  
                 mov     esi, [esp + 12 + 8]             ; data  
                 mov     eax, [esp + 12 + 12]            ; quant  
   
                 xor ecx, ecx  
                 cmp     al, 1  
                 jz      .q1loop  
142    
143                  movq    mm7, [mmx_div + eax * 8 - 8]    mov esi, [esp + 4 + 8]     ; data
144  align ALIGN    mov ecx,[esp + 4 + 16]     ; dcscalar
 .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                ;  
                 pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16  
                 pmulhw  mm3, mm7                ;  
                 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     .loop  
   
 .done  
         ; caclulate  data[0] // (int32_t)dcscalar)  
   
                 mov     ecx, [esp + 12 + 16]    ; dcscalar  
                 mov     edx, ecx  
145                  movsx   eax, word [esi] ; data[0]                  movsx   eax, word [esi] ; data[0]
                 shr     edx, 1                  ; edx = dcscalar /2  
                 cmp             eax, 0  
                 jg              .gtzero  
146    
147      sar ecx,1                  ; dcscalar /2
148      mov edx,eax
149      sar edx,31                 ; sgn(data[0])
150      xor ecx,edx                ; *sgn(data[0])
151                  sub             eax, edx                  sub             eax, edx
152                  jmp             short .mul    add eax,ecx                ; + (dcscalar/2)*sgn(data[0])
 .gtzero  
                 add             eax, edx  
 .mul  
                 cdq                             ; expand eax -> edx:eax  
                 idiv    ecx                     ; eax = edx:eax / dcscalar  
   
                 mov     [edi], ax               ; coeff[0] = ax  
153    
154                  pop     edi    mov ecx, [esp + 4 + 12]    ; quant
155                  pop     esi    cdq
156                  pop     ecx    idiv dword [esp + 4 + 16]  ; dcscalar
157      cmp ecx, 1
158      mov edx, [esp + 4 + 4]     ; coeff
159      je .low
160    
161                  ret    movq mm7, [mmx_div+ecx * 8 - 8]
162      mov ecx,4
163    
164  align ALIGN  .loop
165  .q1loop    movq mm0, [esi]           ; data
166                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]    pxor mm4,mm4
167                  movq    mm3, [esi + 8*ecx + 8]  ;    movq mm1, [esi + 8]
168                  pxor    mm1, mm1                ; mm1 = 0    pcmpgtw mm4,mm0           ; (data<0)
169                  pxor    mm4, mm4                ;    pxor mm5,mm5
170                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)    pmulhw mm0,mm7            ; /(2*quant)
171                  pcmpgtw mm4, mm3                ;    pcmpgtw mm5,mm1
172                  pxor    mm0, mm1                ; mm0 = |mm0|    movq mm2, [esi+16]
173                  pxor    mm3, mm4                ;    psubw mm0,mm4             ;  +(data<0)
174                  psubw   mm0, mm1                ; displace    pmulhw mm1,mm7
175                  psubw   mm3, mm4                ;    pxor mm4,mm4
176                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)    movq mm3,[esi+24]
177                  psrlw   mm3, 1                  ;    pcmpgtw mm4,mm2
178                  pxor    mm0, mm1                ; mm0 *= sign(mm0)    psubw mm1,mm5
179                  pxor    mm3, mm4        ;    pmulhw mm2,mm7
180                  psubw   mm0, mm1                ; undisplace    pxor mm5,mm5
181                  psubw   mm3, mm4                ;    pcmpgtw mm5,mm3
182                  movq    [edi + 8*ecx], mm0    pmulhw mm3,mm7
183                  movq    [edi + 8*ecx + 8], mm3    psubw mm2,mm4
184      psubw mm3,mm5
185      movq [edx], mm0
186      lea esi, [esi+32]
187      movq [edx + 8], mm1
188      movq [edx + 16], mm2
189      movq [edx + 24], mm3
190    
191      dec ecx
192      lea edx, [edx+32]
193      jne .loop
194      jmp .end
195    
196    .low
197      movd mm7,ecx
198      mov ecx,4
199    .loop_low
200      movq mm0, [esi]
201      pxor mm4,mm4
202      movq mm1, [esi + 8]
203      pcmpgtw mm4,mm0
204      pxor mm5,mm5
205      psubw mm0,mm4
206      pcmpgtw mm5,mm1
207      psraw mm0,mm7
208      psubw mm1,mm5
209      movq mm2,[esi+16]
210      pxor mm4,mm4
211      psraw mm1,mm7
212      pcmpgtw mm4,mm2
213      pxor mm5,mm5
214      psubw mm2,mm4
215      movq mm3,[esi+24]
216      pcmpgtw mm5,mm3
217      psraw mm2,mm7
218      psubw mm3,mm5
219      movq [edx], mm0
220      psraw mm3,mm7
221      movq [edx + 8], mm1
222      movq [edx+16],mm2
223      lea esi, [esi+32]
224      movq [edx+24],mm3
225    
226      dec ecx
227      lea edx, [edx+32]
228      jne .loop_low
229    
230                  add ecx,2  .end
231                  cmp ecx,16    mov edx, [esp + 4 + 4]     ; coeff
232                  jnz     .q1loop    mov [edx],ax
233                  jmp     short .done    xor eax,eax                ; return 0
234    
235      pop esi
236      ret
237    .endfunc
238    
239    
240  ;===========================================================================  ;-----------------------------------------------------------------------------
241  ;  ;
242  ; void quant_intra_sse2(int16_t * coeff,  ; uint32_t quant_h263_intra_sse2(int16_t * coeff,
243  ;                                       const int16_t const * data,  ;                                       const int16_t const * data,
244  ;                                       const uint32_t quant,  ;                                       const uint32_t quant,
245  ;                                       const uint32_t dcscalar);  ;                                const uint32_t dcscalar,
246    ;                                const uint16_t *mpeg_matrices);
247  ;  ;
248  ;===========================================================================  ;-----------------------------------------------------------------------------
249    
250  align ALIGN  ALIGN 16
 cglobal quant_h263_intra_sse2  
251  quant_h263_intra_sse2:  quant_h263_intra_sse2:
252    
253                  push    esi                  push    esi
                 push    edi  
254    
255                  mov             edi, [esp + 8 + 4]                      ; coeff    mov esi, [esp + 4 + 8]     ; data
                 mov             esi, [esp + 8 + 8]                      ; data  
                 mov             eax, [esp + 8 + 12]                     ; quant  
256    
257                  xor             ecx, ecx    movsx eax, word [esi]      ; data[0]
                 cmp             al, 1  
                 jz              near .qas2_q1loop  
258    
259  .qas2_not1    mov ecx,[esp + 4 + 16]     ; dcscalar
260                  movq    mm7, [mmx_div + eax*8 - 8]    mov edx,eax
261                  movq2dq xmm7, mm7    sar ecx,1
262      add eax,ecx
263      sub edx,ecx
264      cmovl eax,edx              ; +/- dcscalar/2
265      mov ecx, [esp + 4 + 12]    ; quant
266      cdq
267      idiv dword [esp + 4 + 16]  ; dcscalar
268      cmp ecx, 1
269      mov edx, [esp + 4 + 4]     ; coeff
270      movq xmm7, [mmx_div+ecx * 8 - 8]
271      je .low
272    
273      mov ecx,2
274                  movlhps xmm7, xmm7                  movlhps xmm7, xmm7
275    
276  align 16  .loop
277  .qas2_loop    movdqa xmm0, [esi]
                 movdqa  xmm0, [esi + ecx*8]                     ; xmm0 = [1st]  
                 movdqa  xmm3, [esi + ecx*8 + 16]        ; xmm3 = [2nd]  
                 pxor    xmm1, xmm1  
278                  pxor    xmm4, xmm4                  pxor    xmm4, xmm4
279                  pcmpgtw xmm1, xmm0    movdqa xmm1, [esi + 16]
280                  pcmpgtw xmm4, xmm3    pcmpgtw xmm4,xmm0
281                  pxor    xmm0, xmm1    pxor xmm5,xmm5
                 pxor    xmm3, xmm4  
                 psubw   xmm0, xmm1  
                 psubw   xmm3, xmm4  
282                  pmulhw  xmm0, xmm7                  pmulhw  xmm0, xmm7
283      pcmpgtw xmm5,xmm1
284      movdqa xmm2, [esi+32]
285      psubw xmm0,xmm4
286      pmulhw xmm1,xmm7
287      pxor xmm4,xmm4
288      movdqa xmm3,[esi+48]
289      pcmpgtw xmm4,xmm2
290      psubw xmm1,xmm5
291      pmulhw xmm2,xmm7
292      pxor xmm5,xmm5
293      pcmpgtw xmm5,xmm3
294                  pmulhw  xmm3, xmm7                  pmulhw  xmm3, xmm7
295                  pxor    xmm0, xmm1    psubw xmm2,xmm4
296                  pxor    xmm3, xmm4    psubw xmm3,xmm5
297                  psubw   xmm0, xmm1    movdqa [edx], xmm0
298                  psubw   xmm3, xmm4    lea esi, [esi+64]
299                  movdqa  [edi + ecx*8], xmm0    movdqa [edx + 16], xmm1
300                  movdqa  [edi + ecx*8 + 16], xmm3    movdqa [edx + 32], xmm2
301      movdqa [edx + 48], xmm3
302                  add             ecx, 4  
303                  cmp             ecx, 16    dec ecx
304                  jnz     .qas2_loop    lea edx, [edx+64]
305      jne .loop
306  .qas2_done    jmp .end
307                  mov     ecx, [esp + 8 + 16]     ; dcscalar  
308                  mov     edx, ecx  .low
309                  movsx   eax, word [esi]    movd xmm7,ecx
310                  shr     edx, 1    mov ecx,2
311                  cmp             eax, 0  .loop_low
312                  jg              .qas2_gtzero    movdqa xmm0, [esi]
313      pxor xmm4,xmm4
314                  sub             eax, edx    movdqa xmm1, [esi + 16]
315                  jmp             short .qas2_mul    pcmpgtw xmm4,xmm0
316  .qas2_gtzero    pxor xmm5,xmm5
317                  add             eax, edx    psubw xmm0,xmm4
318  .qas2_mul    pcmpgtw xmm5,xmm1
319                  cdq    psraw xmm0,xmm7
320                  idiv    ecx    psubw xmm1,xmm5
321      movdqa xmm2,[esi+32]
322      pxor xmm4,xmm4
323      psraw xmm1,xmm7
324      pcmpgtw xmm4,xmm2
325      pxor xmm5,xmm5
326      psubw xmm2,xmm4
327      movdqa xmm3,[esi+48]
328      pcmpgtw xmm5,xmm3
329      psraw xmm2,xmm7
330      psubw xmm3,xmm5
331      movdqa [edx], xmm0
332      psraw xmm3,xmm7
333      movdqa [edx+16], xmm1
334      movdqa [edx+32],xmm2
335      lea esi, [esi+64]
336      movdqa [edx+48],xmm3
337    
338      dec ecx
339      lea edx, [edx+64]
340      jne .loop_low
341    
342                  mov             [edi], ax  .end
343      mov edx, [esp + 4 + 4]     ; coeff
344      mov [edx],ax
345      xor eax,eax                ; return 0
346    
                 pop             edi  
347                  pop             esi                  pop             esi
   
348                  ret                  ret
349    .endfunc
350    
351  align 16  ;-----------------------------------------------------------------------------
 .qas2_q1loop  
                 movdqa  xmm0, [esi + ecx*8]                     ; xmm0 = [1st]  
                 movdqa  xmm3, [esi + ecx*8 + 16]        ; xmm3 = [2nd]  
                 pxor    xmm1, xmm1  
                 pxor    xmm4, xmm4  
                 pcmpgtw xmm1, xmm0  
                 pcmpgtw xmm4, xmm3  
                 pxor    xmm0, xmm1  
                 pxor    xmm3, xmm4  
                 psubw   xmm0, xmm1  
                 psubw   xmm3, xmm4  
                 psrlw   xmm0, 1  
                 psrlw   xmm3, 1  
                 pxor    xmm0, xmm1  
                 pxor    xmm3, xmm4  
                 psubw   xmm0, xmm1  
                 psubw   xmm3, xmm4  
                 movdqa  [edi + ecx*8], xmm0  
                 movdqa  [edi + ecx*8 + 16], xmm3  
   
                 add             ecx, 4  
                 cmp             ecx, 16  
                 jnz             .qas2_q1loop  
                 jmp             near .qas2_done  
   
   
   
 ;===========================================================================  
352  ;  ;
353  ; uint32_t quant_inter_mmx(int16_t * coeff,  ; uint32_t quant_h263_inter_mmx(int16_t * coeff,
354  ;                                       const int16_t const * data,  ;                                       const int16_t const * data,
355  ;                                       const uint32_t quant);  ;                               const uint32_t quant,
356    ;                               const uint16_t *mpeg_matrices);
357  ;  ;
358  ;===========================================================================  ;-----------------------------------------------------------------------------
359    
360  align ALIGN  ALIGN 16
 cglobal quant_h263_inter_mmx  
361  quant_h263_inter_mmx:  quant_h263_inter_mmx:
362    
363                  push    ecx                  push    ecx
# Line 516  Line 378 
378    
379                  movq    mm7, [mmx_div + eax * 8 - 8]    ; divider                  movq    mm7, [mmx_div + eax * 8 - 8]    ; divider
380    
381  align ALIGN  ALIGN 8
382  .loop  .loop
383                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
384                  movq    mm3, [esi + 8*ecx + 8]  ;    movq mm3, [esi + 8*ecx + 8]
385                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
386                  pxor    mm4, mm4                ;                  pxor    mm4, mm4                ;
387                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
# Line 550  Line 412 
412                  movq    mm0, mm5                  movq    mm0, mm5
413                  psrlq   mm5, 32                  psrlq   mm5, 32
414                  paddd   mm0, mm5                  paddd   mm0, mm5
                 movd    eax, mm0                ; return sum  
415    
416      movd eax, mm0     ; return sum
417                  pop     edi                  pop     edi
418                  pop     esi                  pop     esi
419                  pop ecx                  pop ecx
420    
421                  ret                  ret
422    
423  align ALIGN  ALIGN 8
424  .q1loop  .q1loop
425                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
426                  movq    mm3, [esi + 8*ecx+ 8]           ;                  movq    mm3, [esi + 8*ecx+ 8]           ;
# Line 588  Line 450 
450                  jnz     .q1loop                  jnz     .q1loop
451    
452                  jmp     .done                  jmp     .done
453    .endfunc
454    
455    
456    
457  ;===========================================================================  ;-----------------------------------------------------------------------------
458  ;  ;
459  ; uint32_t quant_inter_sse2(int16_t * coeff,  ; uint32_t quant_h263_inter_sse2(int16_t * coeff,
460  ;                                       const int16_t const * data,  ;                                       const int16_t const * data,
461  ;                                       const uint32_t quant);  ;                                const uint32_t quant,
462    ;                                const uint16_t *mpeg_matrices);
463  ;  ;
464  ;===========================================================================  ;-----------------------------------------------------------------------------
465    
466  align 16  ALIGN 16
 cglobal quant_h263_inter_sse2  
467  quant_h263_inter_sse2:  quant_h263_inter_sse2:
468    
469                  push    esi                  push    esi
# Line 626  Line 489 
489                  movq2dq xmm7, mm0                  movq2dq xmm7, mm0
490                  movlhps xmm7, xmm7                  movlhps xmm7, xmm7
491    
492  align 16  ALIGN 16
493  .qes2_loop  .qes2_loop
494                  movdqa  xmm0, [esi + ecx*8]                     ; xmm0 = [1st]                  movdqa  xmm0, [esi + ecx*8]                     ; xmm0 = [1st]
495                  movdqa  xmm3, [esi + ecx*8 + 16]        ; xmm3 = [2nd]                  movdqa  xmm3, [esi + ecx*8 + 16]        ; xmm3 = [2nd]
# Line 665  Line 528 
528                  movq    mm5, mm0                  movq    mm5, mm0
529                  psrlq   mm5, 32                  psrlq   mm5, 32
530                  paddd   mm0, mm5                  paddd   mm0, mm5
531    
532                  movd    eax, mm0                                        ; return sum                  movd    eax, mm0                                        ; return sum
533    
534                  pop             edi                  pop             edi
# Line 672  Line 536 
536    
537                  ret                  ret
538    
539  align 16  ALIGN 16
540  .qes2_q1loop  .qes2_q1loop
541                  movdqa  xmm0, [esi + ecx*8]                     ; xmm0 = [1st]                  movdqa  xmm0, [esi + ecx*8]                     ; xmm0 = [1st]
542                  movdqa  xmm3, [esi + ecx*8 + 16]        ; xmm3 = [2nd]                  movdqa  xmm3, [esi + ecx*8 + 16]        ; xmm3 = [2nd]
# Line 701  Line 565 
565                  cmp             ecx,16                  cmp             ecx,16
566                  jnz             .qes2_q1loop                  jnz             .qes2_q1loop
567                  jmp             .qes2_done                  jmp             .qes2_done
568    .endfunc
569    
570    
571  ;===========================================================================  ;-----------------------------------------------------------------------------
572  ;  ;
573  ; void dequant_intra_mmx(int16_t *data,  ; uint32_t dequant_h263_intra_mmx(int16_t *data,
574  ;                                       const int16_t const *coeff,  ;                                       const int16_t const *coeff,
575  ;                                       const uint32_t quant,  ;                                       const uint32_t quant,
576  ;                                       const uint32_t dcscalar);  ;                                 const uint32_t dcscalar,
577    ;                                 const uint16_t *mpeg_matrices);
578  ;  ;
579  ;===========================================================================  ;-----------------------------------------------------------------------------
   
   ; note: we only saturate to +2047 *before* restoring the sign.  
   ; Hence, final clamp really is [-2048,2047]  
580    
581  align ALIGN  ALIGN 16
 cglobal dequant_h263_intra_mmx  
582  dequant_h263_intra_mmx:  dequant_h263_intra_mmx:
583    
584      mov ecx, [esp+12]                 ; quant
585      mov eax, [esp+ 8]                 ; coeff
586      pcmpeqw mm0,mm0
587      movq mm6, [mmx_quant + ecx*8]     ; quant
588      shl ecx,31                        ; quant & 1 ? 0 : - 1
589      movq mm7,mm6
590      movq mm5,mm0
591      movd mm1,ecx
592    mov    edx, [esp+ 4]        ; data    mov    edx, [esp+ 4]        ; data
593    mov    ecx, [esp+ 8]        ; coeff    psllw mm0,mm1
594    mov    eax, [esp+12]        ; quant    paddw mm7,mm7                     ; 2*quant
595    movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1    paddw mm6,mm0                     ; quant-1
596    movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant    psllw mm5,12
597    mov eax, -16    mov ecx,8
598      psrlw mm5,1
599    
600  align ALIGN  .loop:
601  .loop    movq mm0,[eax]
602    movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]    pxor mm2,mm2
   movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]  
   pxor mm1, mm1  
603    pxor mm4, mm4    pxor mm4, mm4
604    pcmpgtw mm1, mm0  ; sign(c)    pcmpgtw mm2,mm0
605    pcmpgtw mm4, mm3  ; sign(c')    pcmpeqw mm4,mm0
606      pmullw mm0,mm7      ; * 2 * quant
607      movq mm1,[eax+8]
608      psubw mm0,mm2
609      pxor mm2,mm6
610      pxor mm3,mm3
611      pandn mm4,mm2
612    pxor mm2, mm2    pxor mm2, mm2
613    pxor mm5, mm5    pcmpgtw mm3,mm1
614    pcmpeqw mm2, mm0  ; c is zero    pcmpeqw mm2,mm1
615    pcmpeqw mm5, mm3  ; c' is zero    pmullw mm1,mm7
616    pandn mm2, mm6    ; offset = isZero ? 0 : quant_add    paddw mm0,mm4
617    pandn mm5, mm6    psubw mm1,mm3
618    pxor mm0, mm1     ; negate if negative    pxor mm3,mm6
619    pxor mm3, mm4     ; negate if negative    pandn mm2,mm3
620    psubw mm0, mm1    paddsw mm0, mm5        ; saturate
621    psubw mm3, mm4    paddw mm1,mm2
622    pmullw mm0, mm7 ; *= 2Q  
623    pmullw mm3, mm7 ; *= 2Q    paddsw mm1, mm5
624    paddw mm0, mm2 ; + offset    psubsw mm0, mm5
625    paddw mm3, mm5 ; + offset    psubsw mm1, mm5
626    paddw mm0, mm1 ; negate back    psubsw mm0, mm5
627    paddw mm3, mm4 ; negate back    psubsw mm1, mm5
628      paddsw mm0, mm5
629      ; saturates to +2047    paddsw mm1, mm5
630    movq mm2, [mmx_32767_minus_2047]  
631    add eax, 2    movq [edx],mm0
632    paddsw mm0, mm2    lea eax,[eax+16]
633    paddsw mm3, mm2    movq [edx+8],mm1
634    psubsw mm0, mm2  
635    psubsw mm3, mm2    dec ecx
636      lea edx,[edx+16]
637    pxor mm0, mm1    jne .loop
   pxor mm3, mm4  
   movq [edx + 8*eax + 8*16   - 2*8], mm0  
   movq [edx + 8*eax + 8*16+8 - 2*8], mm3  
   jnz   near .loop  
638    
639      ; deal with DC      ; deal with DC
640      mov eax, [esp+ 8]                ; coeff
641    movd mm0, [ecx]    movd mm1,[esp+16]                ; dcscalar
642    pmullw mm0, [esp+16]    ; dcscalar    movd mm0,[eax]                   ; coeff[0]
643    movq mm2, [mmx_32767_minus_2047]    pmullw mm0,mm1                   ; * dcscalar
644    paddsw mm0, mm2    mov edx, [esp+ 4]                ; data
645    psubsw mm0, mm2    paddsw mm0, mm5                  ; saturate +
646    movq mm3, [mmx_32768_minus_2048]    psubsw mm0, mm5
647    psubsw mm0, mm3    psubsw mm0, mm5                  ; saturate -
648    paddsw mm0, mm3    paddsw mm0, mm5
649    movd eax, mm0    movd eax, mm0
650    mov [edx], ax    mov [edx], ax
651    
652      xor eax, eax                    ; return 0
653    ret    ret
654    .endfunc
655    
656  ;===========================================================================  ;-----------------------------------------------------------------------------
657  ;  ;
658  ; void dequant_intra_xmm(int16_t *data,  ; uint32_t dequant_h263_intra_xmm(int16_t *data,
659  ;                                       const int16_t const *coeff,  ;                                       const int16_t const *coeff,
660  ;                                       const uint32_t quant,  ;                                       const uint32_t quant,
661  ;                                       const uint32_t dcscalar);  ;                                 const uint32_t dcscalar,
662    ;                                 const uint16_t *mpeg_matrices);
663  ;  ;
664  ;===========================================================================  ;-----------------------------------------------------------------------------
665    
   ; this is the same as dequant_inter_mmx, except that we're  
   ; saturating using 'pminsw' (saves 2 cycles/loop => ~5% faster)  
666    
667  align ALIGN  ALIGN 16
 cglobal dequant_h263_intra_xmm  
668  dequant_h263_intra_xmm:  dequant_h263_intra_xmm:
669    
670      mov ecx, [esp+12]                 ; quant
671      mov eax, [esp+ 8]                 ; coeff
672    
673      movd mm6,ecx                      ; quant
674      pcmpeqw mm0,mm0
675      pshufw mm6,mm6,0                  ; all quant
676      shl ecx,31
677      movq mm5,mm0
678      movq mm7,mm6
679      movd mm1,ecx
680    mov    edx, [esp+ 4]        ; data    mov    edx, [esp+ 4]        ; data
681    mov    ecx, [esp+ 8]        ; coeff    psllw mm0,mm1                     ; quant & 1 ? 0 : - 1
682    mov    eax, [esp+12]        ; quant    movq mm4,mm5
683    movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1    paddw mm7,mm7                     ; quant*2
684    movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant    paddw mm6,mm0                     ; quant-1
685    mov eax, -16    psrlw mm4,5                       ; mm4=2047
686      mov ecx,8
687      pxor mm5,mm4                      ; mm5=-2048
688    
689  align ALIGN  .loop:
690  .loop    movq mm0,[eax]
   movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]  
   movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]  
   pxor mm1, mm1  
   pxor mm4, mm4  
   pcmpgtw mm1, mm0  ; sign(c)  
   pcmpgtw mm4, mm3  ; sign(c')  
691    pxor mm2, mm2    pxor mm2, mm2
692    pxor mm5, mm5    pxor mm3,mm3
   pcmpeqw mm2, mm0  ; c is zero  
   pcmpeqw mm5, mm3  ; c' is zero  
   pandn mm2, mm6    ; offset = isZero ? 0 : quant_add  
   pandn mm5, mm6  
   pxor mm0, mm1     ; negate if negative  
   pxor mm3, mm4     ; negate if negative  
   psubw mm0, mm1  
   psubw mm3, mm4  
   pmullw mm0, mm7 ; *= 2Q  
   pmullw mm3, mm7 ; *= 2Q  
   paddw mm0, mm2 ; + offset  
   paddw mm3, mm5 ; + offset  
   paddw mm0, mm1 ; negate back  
   paddw mm3, mm4 ; negate back  
   
     ; saturates to +2047  
   movq mm2, [mmx_2047]  
   pminsw mm0, mm2  
   add eax, 2  
   pminsw mm3, mm2  
   
   pxor mm0, mm1  
   pxor mm3, mm4  
   movq [edx + 8*eax + 8*16   - 2*8], mm0  
   movq [edx + 8*eax + 8*16+8 - 2*8], mm3  
   jnz   near .loop  
693    
694      ; deal with DC    pcmpgtw mm2,mm0
695      pcmpeqw mm3,mm0     ; if coeff==0...
696      pmullw mm0,mm7      ; * 2 * quant
697      movq mm1,[eax+8]
698    
699      psubw mm0,mm2
700      pxor mm2,mm6
701      pandn mm3,mm2       ; ...then data=0
702      pxor mm2,mm2
703      paddw mm0,mm3
704      pxor mm3,mm3
705      pcmpeqw mm2,mm1
706      pcmpgtw mm3,mm1
707      pmullw mm1,mm7
708    
709      pminsw mm0,mm4
710      psubw mm1,mm3
711      pxor mm3,mm6
712      pandn mm2,mm3
713      paddw mm1,mm2
714    
715      pmaxsw mm0,mm5
716      pminsw mm1,mm4
717      movq [edx],mm0
718      pmaxsw mm1,mm5
719      lea eax,[eax+16]
720      movq [edx+8],mm1
721    
722      dec ecx
723      lea edx,[edx+16]
724      jne .loop
725    
726    movd mm0, [ecx]     ; deal with DC
727    pmullw mm0, [esp+16]    ; dcscalar    mov eax, [esp+ 8]                 ; coeff
728    movq mm2, [mmx_32767_minus_2047]    movd mm1,[esp+16]                 ; dcscalar
729    paddsw mm0, mm2    movd mm0, [eax]
730    psubsw mm0, mm2    pmullw mm0, mm1
731    movq mm2, [mmx_32768_minus_2048]    mov edx, [esp+ 4]                 ; data
732    psubsw mm0, mm2    pminsw mm0,mm4
733    paddsw mm0, mm2    pmaxsw mm0,mm5
734    movd eax, mm0    movd eax, mm0
735    mov [edx], ax    mov [edx], ax
736    
737      xor eax, eax                      ; return 0
738    ret    ret
739    .endfunc
740    
741    
742  ;===========================================================================  ;-----------------------------------------------------------------------------
743  ;  ;
744  ; void dequant_intra_sse2(int16_t *data,  ; uint32_t dequant_h263_intra_sse2(int16_t *data,
745  ;                                       const int16_t const *coeff,  ;                                       const int16_t const *coeff,
746  ;                                       const uint32_t quant,  ;                                       const uint32_t quant,
747  ;                                       const uint32_t dcscalar);  ;                                  const uint32_t dcscalar,
748    ;                                  const uint16_t *mpeg_matrices);
749  ;  ;
750  ;===========================================================================  ;-----------------------------------------------------------------------------
751  align ALIGN  
752  cglobal dequant_h263_intra_sse2  ALIGN 16
753  dequant_h263_intra_sse2:  dequant_h263_intra_sse2:
754    
755      mov ecx, [esp+12]                 ; quant
756      mov eax, [esp+ 8]                 ; coeff
757    
758      movd xmm6,ecx                     ; quant
759    
760      shl ecx,31
761      pshuflw xmm6,xmm6,0
762      pcmpeqw xmm0,xmm0
763      movlhps xmm6,xmm6                 ; all quant
764      movd xmm1,ecx
765      movdqa xmm5,xmm0
766      movdqa xmm7,xmm6
767          mov edx, [esp+ 4]        ; data          mov edx, [esp+ 4]        ; data
768          mov ecx, [esp+ 8]        ; coeff    paddw xmm7,xmm7                   ; quant *2
769          mov eax, [esp+12]        ; quant    psllw xmm0,xmm1                   ; quant & 1 ? 0 : - 1
770          movq mm6, [mmx_add + eax * 8 - 8]    movdqa xmm4,xmm5
771          movq mm7, [mmx_mul + eax * 8 - 8]    paddw xmm6,xmm0                   ; quant-1
772          movq2dq xmm6, mm6    psrlw xmm4,5                      ; 2047
773          movq2dq xmm7, mm7    mov ecx,4
774          movlhps xmm6, xmm6    pxor xmm5,xmm4                    ; mm5=-2048
         movlhps xmm7, xmm7  
         mov eax, -16  
775    
776  align ALIGN  .loop:
777  .loop    movdqa xmm0,[eax]
         movdqa xmm0, [ecx + 8*16 + 8*eax]      ; c  = coeff[i]  
         movdqa xmm3, [ecx + 8*16 + 8*eax+ 16]  
         pxor xmm1, xmm1  
         pxor xmm4, xmm4  
         pcmpgtw xmm1, xmm0  ; sign(c)  
         pcmpgtw xmm4, xmm3  
778          pxor xmm2, xmm2          pxor xmm2, xmm2
779          pxor xmm5, xmm5    pxor xmm3,xmm3
         pcmpeqw xmm2, xmm0  ; c is zero  
         pcmpeqw xmm5, xmm3  
         pandn xmm2, xmm6    ; offset = isZero ? 0 : quant_add  
         pandn xmm5, xmm6  
         pxor xmm0, xmm1     ; negate if negative  
         pxor xmm3, xmm4  
         psubw xmm0, xmm1  
         psubw xmm3, xmm4  
         pmullw xmm0, xmm7 ; *= 2Q  
         pmullw xmm3, xmm7  
         paddw xmm0, xmm2 ; + offset  
         paddw xmm3, xmm5  
         paddw xmm0, xmm1 ; negate back  
         paddw xmm3, xmm4  
   
         ; saturates to +2047  
         movdqa xmm2, [sse2_2047]  
         pminsw xmm0, xmm2  
         add eax, 4  
         pminsw xmm3, xmm2  
780    
781          pxor xmm0, xmm1    pcmpgtw xmm2,xmm0
782          pxor xmm3, xmm4    pcmpeqw xmm3,xmm0
783          movdqa [edx + 8*16 - 8*4 + 8*eax], xmm0    pmullw xmm0,xmm7      ; * 2 * quant
784          movdqa [edx + 8*16 - 8*4 + 8*eax + 16], xmm3    movdqa xmm1,[eax+16]
785          jnz     near .loop  
786      psubw xmm0,xmm2
787      pxor xmm2,xmm6
788      pandn xmm3,xmm2
789      pxor xmm2,xmm2
790      paddw xmm0,xmm3
791      pxor xmm3,xmm3
792      pcmpeqw xmm2,xmm1
793      pcmpgtw xmm3,xmm1
794      pmullw xmm1,xmm7
795    
796      pminsw xmm0,xmm4
797      psubw xmm1,xmm3
798      pxor xmm3,xmm6
799      pandn xmm2,xmm3
800      paddw xmm1,xmm2
801    
802      pmaxsw xmm0,xmm5
803      pminsw xmm1,xmm4
804      movdqa [edx],xmm0
805      pmaxsw xmm1,xmm5
806      lea eax,[eax+32]
807      movdqa [edx+16],xmm1
808    
809      dec ecx
810      lea edx,[edx+32]
811      jne .loop
812    
813          ; deal with DC          ; deal with DC
         movd mm0, [ecx]  
         pmullw mm0, [esp+16]    ; dcscalar  
         movq mm2, [mmx_32767_minus_2047]  
         paddsw mm0, mm2  
         psubsw mm0, mm2  
         movq mm2, [mmx_32768_minus_2048]  
         psubsw mm0, mm2  
         paddsw mm0, mm2  
         movd eax, mm0  
         mov [edx], ax  
   
         ret  
814    
815      mov eax, [esp+ 8]             ; coeff
816      movsx eax,word [eax]
817      imul dword [esp+16]           ; dcscalar
818      mov edx, [esp+ 4]             ; data
819      movd xmm0,eax
820      pminsw xmm0,xmm4
821      pmaxsw xmm0,xmm5
822      movd eax,xmm0
823    
824      mov [edx], ax
825    
826      xor eax, eax                  ; return 0
827      ret
828    .endfunc
829    
830  ;===========================================================================  ;-----------------------------------------------------------------------------
831  ;  ;
832  ; void dequant_inter_mmx(int16_t * data,  ; uint32t dequant_h263_inter_mmx(int16_t * data,
833  ;                                       const int16_t * const coeff,  ;                                       const int16_t * const coeff,
834  ;                                       const uint32_t quant);  ;                                const uint32_t quant,
835    ;                                const uint16_t *mpeg_matrices);
836  ;  ;
837  ;===========================================================================  ;-----------------------------------------------------------------------------
838    
839  align ALIGN  ALIGN 16
 cglobal dequant_h263_inter_mmx  
840  dequant_h263_inter_mmx:  dequant_h263_inter_mmx:
841    
842      mov ecx, [esp+12]                 ; quant
843      mov eax, [esp+ 8]                 ; coeff
844      pcmpeqw mm0,mm0
845      movq mm6, [mmx_quant + ecx*8]     ; quant
846      shl ecx,31                        ; odd/even
847      movq mm7,mm6
848      movd mm1,ecx
849    mov    edx, [esp+ 4]        ; data    mov    edx, [esp+ 4]        ; data
850    mov    ecx, [esp+ 8]        ; coeff    movq mm5,mm0
851    mov    eax, [esp+12]        ; quant    psllw mm0,mm1                     ; quant & 1 ? 0 : - 1
852    movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1    paddw mm7,mm7                     ; quant*2
853    movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant    paddw mm6,mm0                     ; quant & 1 ? quant : quant - 1
854    mov eax, -16    psllw mm5,12
855      mov ecx,8
856      psrlw mm5,1                       ; 32767-2047 (32768-2048)
857    
858  align ALIGN  .loop:
859  .loop    movq mm0,[eax]
   movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]  
   movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]  
   pxor mm1, mm1  
860    pxor mm4, mm4    pxor mm4, mm4
   pcmpgtw mm1, mm0  ; sign(c)  
   pcmpgtw mm4, mm3  ; sign(c')  
861    pxor mm2, mm2    pxor mm2, mm2
862    pxor mm5, mm5    pcmpeqw mm4,mm0     ; if coeff==0...
863    pcmpeqw mm2, mm0  ; c is zero    pcmpgtw mm2,mm0
864    pcmpeqw mm5, mm3  ; c' is zero    pmullw mm0,mm7      ; * 2 * quant
865    pandn mm2, mm6    ; offset = isZero ? 0 : quant_add    pxor mm3,mm3
866    pandn mm5, mm6    psubw mm0,mm2
867    pxor mm0, mm1     ; negate if negative    movq mm1,[eax+8]
868    pxor mm3, mm4     ; negate if negative    pxor mm2,mm6
869    psubw mm0, mm1    pcmpgtw mm3,mm1
870    psubw mm3, mm4    pandn mm4,mm2      ; ... then data==0
871    pmullw mm0, mm7 ; *= 2Q    pmullw mm1,mm7
872    pmullw mm3, mm7 ; *= 2Q    pxor mm2,mm2
873    paddw mm0, mm2 ; + offset    pcmpeqw mm2,mm1
874    paddw mm3, mm5 ; + offset    psubw mm1,mm3
875    paddw mm0, mm1 ; negate back    pxor mm3,mm6
876    paddw mm3, mm4 ; negate back    pandn mm2,mm3
877      paddw mm0,mm4
878      ; saturates to +2047    paddw mm1,mm2
879    movq mm2, [mmx_32767_minus_2047]  
880    add eax, 2    paddsw mm0, mm5        ; saturate
881    paddsw mm0, mm2    paddsw mm1, mm5
882    paddsw mm3, mm2    psubsw mm0, mm5
883    psubsw mm0, mm2    psubsw mm1, mm5
884    psubsw mm3, mm2    psubsw mm0, mm5
885      psubsw mm1, mm5
886    pxor mm0, mm1    paddsw mm0, mm5
887    pxor mm3, mm4    paddsw mm1, mm5
888    movq [edx + 8*eax + 8*16   - 2*8], mm0  
889    movq [edx + 8*eax + 8*16+8 - 2*8], mm3    movq [edx],mm0
890    jnz   near .loop    lea eax,[eax+16]
891      movq [edx+8],mm1
892    
893      dec ecx
894      lea edx,[edx+16]
895      jne .loop
896    
897      xor eax, eax              ; return 0
898    ret    ret
899    .endfunc
900    
901    
902  ;===========================================================================  ;-----------------------------------------------------------------------------
903  ;  ;
904  ; void dequant_inter_xmm(int16_t * data,  ; uint32_t dequant_h263_inter_xmm(int16_t * data,
905  ;                                       const int16_t * const coeff,  ;                                       const int16_t * const coeff,
906  ;                                       const uint32_t quant);  ;                                 const uint32_t quant,
907    ;                                 const uint16_t *mpeg_matrices);
908  ;  ;
909  ;===========================================================================  ;-----------------------------------------------------------------------------
910    ALIGN 16
   ; this is the same as dequant_inter_mmx,  
   ; except that we're saturating using 'pminsw' (saves 2 cycles/loop)  
   
 align ALIGN  
 cglobal dequant_h263_inter_xmm  
911  dequant_h263_inter_xmm:  dequant_h263_inter_xmm:
912    
913      mov ecx, [esp+12]                 ; quant
914      mov eax, [esp+ 8]                 ; coeff
915      pcmpeqw mm0,mm0
916      movq mm6, [mmx_quant + ecx*8]     ; quant
917      shl ecx,31
918      movq mm5,mm0
919      movd mm1,ecx
920      movq mm7,mm6
921      psllw mm0,mm1
922    mov    edx, [esp+ 4]        ; data    mov    edx, [esp+ 4]        ; data
923    mov    ecx, [esp+ 8]        ; coeff    movq mm4,mm5
924    mov    eax, [esp+12]        ; quant    paddw mm7,mm7
925    movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1    paddw mm6,mm0                     ; quant-1
926    movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant  
927    mov eax, -16    psrlw mm4,5
928      mov ecx,8
929  align ALIGN    pxor mm5,mm4                      ; mm5=-2048
930  .loop  
931    movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]  .loop:
932    movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]    movq mm0,[eax]
933    pxor mm1, mm1    pxor mm3,mm3
   pxor mm4, mm4  
   pcmpgtw mm1, mm0  ; sign(c)  
   pcmpgtw mm4, mm3  ; sign(c')  
934    pxor mm2, mm2    pxor mm2, mm2
935    pxor mm5, mm5    pcmpeqw mm3,mm0
936    pcmpeqw mm2, mm0  ; c is zero    pcmpgtw mm2,mm0
937    pcmpeqw mm5, mm3  ; c' is zero    pmullw mm0,mm7                    ; * 2 * quant
938    pandn mm2, mm6    ; offset = isZero ? 0 : quant_add    pandn mm3,mm6
939    pandn mm5, mm6    movq mm1,[eax+8]
940    pxor mm0, mm1     ; negate if negative    psubw mm0,mm2
941    pxor mm3, mm4     ; negate if negative    pxor mm2,mm3
942    psubw mm0, mm1    pxor mm3,mm3
943    psubw mm3, mm4    paddw mm0,mm2
944    pmullw mm0, mm7 ; *= 2Q    pxor mm2,mm2
945    pmullw mm3, mm7 ; *= 2Q    pcmpgtw mm3,mm1
946    paddw mm0, mm2 ; + offset    pcmpeqw mm2,mm1
947    paddw mm3, mm5 ; + offset    pmullw mm1,mm7
948    paddw mm0, mm1 ; start restoring sign    pandn mm2,mm6
949    paddw mm3, mm4 ; start restoring sign    psubw mm1,mm3
950      pxor mm3,mm2
951        ; saturates to +2047    paddw mm1,mm3
952    movq mm2, [mmx_2047]  
953    pminsw mm0, mm2    pminsw mm0,mm4
954    add eax, 2    pminsw mm1,mm4
955    pminsw mm3, mm2    pmaxsw mm0,mm5
956      pmaxsw mm1,mm5
957    pxor mm0, mm1 ; finish restoring sign  
958    pxor mm3, mm4 ; finish restoring sign    movq [edx],mm0
959    movq [edx + 8*eax + 8*16   - 2*8], mm0    lea eax,[eax+16]
960    movq [edx + 8*eax + 8*16+8 - 2*8], mm3    movq [edx+8],mm1
961    jnz   near .loop  
962      dec ecx
963      lea edx,[edx+16]
964      jne .loop
965    
966      xor eax, eax              ; return 0
967    ret    ret
968    .endfunc
969    
970    
971  ;===========================================================================  ;-----------------------------------------------------------------------------
972  ;  ;
973  ; void dequant_inter_sse2(int16_t * data,  ; uint32_t dequant_h263_inter_sse2(int16_t * data,
974  ;                                       const int16_t * const coeff,  ;                                       const int16_t * const coeff,
975  ;                                       const uint32_t quant);  ;                                  const uint32_t quant,
976    ;                                  const uint16_t *mpeg_matrices);
977  ;  ;
978  ;===========================================================================  ;-----------------------------------------------------------------------------
979  align ALIGN  
980  cglobal dequant_h263_inter_sse2  ALIGN 16
981  dequant_h263_inter_sse2:  dequant_h263_inter_sse2:
         mov edx, [esp + 4]      ; data  
         mov ecx, [esp + 8]      ; coeff  
         mov eax, [esp + 12]     ; quant  
         movq mm6, [mmx_add + eax * 8 - 8]  
         movq mm7, [mmx_mul + eax * 8 - 8]  
         movq2dq xmm6, mm6  
         movq2dq xmm7, mm7  
         movlhps xmm6, xmm6  
         movlhps xmm7, xmm7  
         mov eax, -16  
982    
983  align ALIGN    mov ecx, [esp+12]                 ; quant
984  .loop    mov eax, [esp+ 8]                 ; coeff
         movdqa xmm0, [ecx + 8*16 + 8*eax]  ; c  = coeff[i]  
         movdqa xmm3, [ecx + 8*16 + 8*eax + 16]  
985    
986          pxor xmm1, xmm1    movq xmm6, [mmx_quant + ecx*8]    ; quant
987          pxor xmm4, xmm4    inc ecx
988          pcmpgtw xmm1, xmm0  ; sign(c)    pcmpeqw xmm5,xmm5
989          pcmpgtw xmm4, xmm3    and ecx,1
990      movlhps xmm6,xmm6
991      movd xmm0,ecx
992      movdqa xmm7,xmm6
993      pshuflw xmm0,xmm0,0
994      movdqa xmm4,xmm5
995      mov edx, [esp+ 4]                 ; data
996      movlhps xmm0,xmm0
997      paddw xmm7,xmm7
998      psubw xmm6,xmm0
999      psrlw xmm4,5   ; 2047
1000      mov ecx,4
1001      pxor xmm5,xmm4 ; mm5=-2048
1002    
1003    .loop:
1004      movdqa xmm0,[eax]
1005      pxor xmm3,xmm3
1006          pxor xmm2, xmm2          pxor xmm2, xmm2
1007          pxor xmm5, xmm5    pcmpeqw xmm3,xmm0
1008          pcmpeqw xmm2, xmm0  ; c is zero    pcmpgtw xmm2,xmm0
1009          pcmpeqw xmm5, xmm3    pmullw xmm0,xmm7      ; * 2 * quant
1010      pandn xmm3,xmm6
1011      movdqa xmm1,[eax+16]
1012      psubw xmm0,xmm2
1013      pxor xmm2,xmm3
1014      pxor xmm3,xmm3
1015      paddw xmm0,xmm2
1016      pxor xmm2,xmm2
1017      pcmpgtw xmm3,xmm1
1018      pcmpeqw xmm2,xmm1
1019      pmullw xmm1,xmm7
1020          pandn xmm2, xmm6          pandn xmm2, xmm6
1021          pandn xmm5, xmm6    psubw xmm1,xmm3
1022          pxor xmm0, xmm1  ; negate if negative    pxor xmm3,xmm2
1023          pxor xmm3, xmm4    paddw xmm1,xmm3
1024          psubw xmm0, xmm1  
1025          psubw xmm3, xmm4    pminsw xmm0,xmm4
1026          pmullw xmm0, xmm7  ; *= 2Q    pminsw xmm1,xmm4
1027          pmullw xmm3, xmm7    pmaxsw xmm0,xmm5
1028          paddw xmm0, xmm2  ; + offset    pmaxsw xmm1,xmm5
1029          paddw xmm3, xmm5  
1030      movdqa [edx],xmm0
1031          paddw xmm0, xmm1  ; start restoring sign    lea eax,[eax+32]
1032          paddw xmm3, xmm4    movdqa [edx+16],xmm1
1033    
1034          ; saturates to +2047    dec ecx
1035          movdqa xmm2, [sse2_2047]    lea edx,[edx+32]
1036          pminsw xmm0, xmm2    jne .loop
         add eax, 4  
         pminsw xmm3, xmm2  
   
         pxor xmm0, xmm1 ; finish restoring sign  
         pxor xmm3, xmm4  
         movdqa [edx + 8*16 - 8*4 + 8*eax], xmm0  
         movdqa [edx + 8*16 - 8*4 + 8*eax + 16], xmm3  
         jnz     near .loop  
1037    
1038      xor eax, eax              ; return 0
1039          ret          ret
1040    .endfunc
1041    
1042    
1043    %ifidn __OUTPUT_FORMAT__,elf
1044    section ".note.GNU-stack" noalloc noexec nowrite progbits
1045    %endif
1046    

Legend:
Removed from v.1.1.2.1  
changed lines
  Added in v.1.8

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