[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.11.2.2, Tue Dec 2 14:00:09 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:  
25  ; *  ; *
26  ; * 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>  
 ; *  
 ; *************************************************************************/  
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  %include "nasm.inc"
 %define ALIGN 8  
32    
33  bits 32  ;=============================================================================
34    ; Read only Local data
35    ;=============================================================================
36    
37  section .data  DATA
38    
39    ALIGN SECTION_ALIGN
40    plus_one:
41            times 8 dw 1
42    
43  %macro cglobal 1  ;-----------------------------------------------------------------------------
44          %ifdef PREFIX  ;
45                  global _%1  ; quant table
46                  %define %1 _%1  ;
47          %else  ;-----------------------------------------------------------------------------
                 global %1  
         %endif  
 %endmacro  
   
 align 16  
48    
49  plus_one times 8        dw       1  ALIGN SECTION_ALIGN
50    mmx_quant:
51    %assign quant 0
52    %rep 32
53            times 4 dw quant
54            %assign quant quant+1
55    %endrep
56    
57  ;===========================================================================  ;-----------------------------------------------------------------------------
58  ;  ;
59  ; subtract by Q/2 table  ; subtract by Q/2 table
60  ;  ;
61  ;===========================================================================  ;-----------------------------------------------------------------------------
62    
63  %macro MMX_SUB  1  ALIGN SECTION_ALIGN
64  times 4 dw %1 / 2  mmx_sub:
65  %endmacro  %assign quant 1
66    %rep 31
67  align 16          times 4 dw  quant / 2
68  mmx_sub          %assign quant quant+1
69                  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  
70    
71    ;-----------------------------------------------------------------------------
   
 ;===========================================================================  
72  ;  ;
73  ; divide by 2Q table  ; divide by 2Q table
74  ;  ;
# Line 120  Line 76 
76  ; for q=1, _pmulhw_ will overflow so it is treated seperately  ; for q=1, _pmulhw_ will overflow so it is treated seperately
77  ; (3dnow2 provides _pmulhuw_ which wont cause overflow)  ; (3dnow2 provides _pmulhuw_ which wont cause overflow)
78  ;  ;
79  ;===========================================================================  ;-----------------------------------------------------------------------------
   
 %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  
80    
81  align 16  ALIGN SECTION_ALIGN
82  mmx_add  mmx_div:
83                  MMX_ADD 1  %assign quant 1
84                  MMX_ADD 2  %rep 31
85                  MMX_ADD 3          times 4 dw  (1<<16) / (quant*2) + 1
86                  MMX_ADD 4          %assign quant quant+1
87                  MMX_ADD 5  %endrep
88                  MMX_ADD 6  
89                  MMX_ADD 7  ;=============================================================================
90                  MMX_ADD 8  ; Code
91                  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)  
92    
93    SECTION .rotext align=SECTION_ALIGN
94    
95  section .text  cglobal quant_h263_intra_mmx
96    cglobal quant_h263_intra_sse2
97    cglobal quant_h263_inter_mmx
98    cglobal quant_h263_inter_sse2
99    cglobal dequant_h263_intra_mmx
100    cglobal dequant_h263_intra_xmm
101    cglobal dequant_h263_intra_sse2
102    cglobal dequant_h263_inter_mmx
103    cglobal dequant_h263_inter_xmm
104    cglobal dequant_h263_inter_sse2
105    
106  ;===========================================================================  ;-----------------------------------------------------------------------------
107  ;  ;
108  ; void quant_intra_mmx(int16_t * coeff,  ; uint32_t quant_h263_intra_mmx(int16_t * coeff,
109  ;                                       const int16_t const * data,  ;                                       const int16_t const * data,
110  ;                                       const uint32_t quant,  ;                                       const uint32_t quant,
111  ;                                       const uint32_t dcscalar);  ;                               const uint32_t dcscalar,
112    ;                               const uint16_t *mpeg_matrices);
113  ;  ;
114  ;===========================================================================  ;-----------------------------------------------------------------------------
115    
116  align ALIGN  ALIGN SECTION_ALIGN
 cglobal quant_h263_intra_mmx  
117  quant_h263_intra_mmx:  quant_h263_intra_mmx:
118    
119                  push    ecx    mov _EAX, prm2     ; data
120                  push    esi    mov TMP0, prm4     ; dcscalar
121                  push    edi    movsx _EAX, word [_EAX]  ; data[0]
122    
123                  mov     edi, [esp + 12 + 4]             ; coeff    sar TMP0, 1              ; dcscalar /2
124                  mov     esi, [esp + 12 + 8]             ; data    mov TMP1, _EAX
125                  mov     eax, [esp + 12 + 12]            ; quant    sar TMP1, 31             ; sgn(data[0])
126      xor TMP0,TMP1            ; *sgn(data[0])
127                  xor ecx, ecx    sub _EAX,TMP1
128                  cmp     al, 1    add _EAX,TMP0            ; + (dcscalar/2)*sgn(data[0])
129                  jz      .q1loop  
130      mov TMP0, prm3     ; quant
131                  movq    mm7, [mmx_div + eax * 8 - 8]    lea TMP1, [mmx_div]
132  align ALIGN    movq mm7, [TMP1+TMP0 * 8 - 8]
133  .loop  %ifdef ARCH_IS_X86_64
134                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]  %ifdef WINDOWS
135                  movq    mm3, [esi + 8*ecx + 8]  ;    mov TMP1, prm2
136                  pxor    mm1, mm1                ; mm1 = 0  %endif
137                  pxor    mm4, mm4                ;  %endif
138                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)    cdq
139                  pcmpgtw mm4, mm3                ;    idiv prm4d         ; dcscalar
140                  pxor    mm0, mm1                ; mm0 = |mm0|  %ifdef ARCH_IS_X86_64
141                  pxor    mm3, mm4                ;  %ifdef WINDOWS
142                  psubw   mm0, mm1                ; displace    mov prm2, TMP1
143                  psubw   mm3, mm4                ;  %endif
144                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16  %endif
145                  pmulhw  mm3, mm7                ;    cmp TMP0, 1
146                  pxor    mm0, mm1                ; mm0 *= sign(mm0)    mov TMP1, prm1     ; coeff
147                  pxor    mm3, mm4                ;    je .low
148                  psubw   mm0, mm1                ; undisplace  
149                  psubw   mm3, mm4                ;    mov TMP0, prm2     ; data
150                  movq    [edi + 8*ecx], mm0    push _EAX          ; DC
151                  movq    [edi + 8*ecx + 8], mm3    mov _EAX, TMP0
   
                 add ecx,2  
                 cmp ecx,16  
                 jnz     .loop  
152    
153  .done    mov TMP0,4
         ; caclulate  data[0] // (int32_t)dcscalar)  
154    
155                  mov     ecx, [esp + 12 + 16]    ; dcscalar  .loop:
156                  mov     edx, ecx    movq mm0, [_EAX]           ; data
157                  movsx   eax, word [esi] ; data[0]    pxor mm4,mm4
158                  shr     edx, 1                  ; edx = dcscalar /2    movq mm1, [_EAX + 8]
159                  cmp             eax, 0    pcmpgtw mm4,mm0           ; (data<0)
160                  jg              .gtzero    pxor mm5,mm5
161      pmulhw mm0,mm7            ; /(2*quant)
162                  sub             eax, edx    pcmpgtw mm5,mm1
163                  jmp             short .mul    movq mm2, [_EAX+16]
164  .gtzero    psubw mm0,mm4             ;  +(data<0)
165                  add             eax, edx    pmulhw mm1,mm7
166  .mul    pxor mm4,mm4
167                  cdq                             ; expand eax -> edx:eax    movq mm3,[_EAX+24]
168                  idiv    ecx                     ; eax = edx:eax / dcscalar    pcmpgtw mm4,mm2
169      psubw mm1,mm5
170                  mov     [edi], ax               ; coeff[0] = ax    pmulhw mm2,mm7
171      pxor mm5,mm5
172                  pop     edi    pcmpgtw mm5,mm3
173                  pop     esi    pmulhw mm3,mm7
174                  pop     ecx    psubw mm2,mm4
175      psubw mm3,mm5
176      movq [TMP1], mm0
177      lea _EAX, [_EAX+32]
178      movq [TMP1 + 8], mm1
179      movq [TMP1 + 16], mm2
180      movq [TMP1 + 24], mm3
181    
182      dec TMP0
183      lea TMP1, [TMP1+32]
184      jne .loop
185      jmp .end
186    
187    .low:
188      movd mm7,TMP0d
189    
190      mov TMP0, prm2
191      push _EAX
192      mov _EAX, TMP0
193    
194      mov TMP0,4
195    .loop_low:
196      movq mm0, [_EAX]
197      pxor mm4,mm4
198      movq mm1, [_EAX + 8]
199      pcmpgtw mm4,mm0
200      pxor mm5,mm5
201      psubw mm0,mm4
202      pcmpgtw mm5,mm1
203      psraw mm0,mm7
204      psubw mm1,mm5
205      movq mm2,[_EAX+16]
206      pxor mm4,mm4
207      psraw mm1,mm7
208      pcmpgtw mm4,mm2
209      pxor mm5,mm5
210      psubw mm2,mm4
211      movq mm3,[_EAX+24]
212      pcmpgtw mm5,mm3
213      psraw mm2,mm7
214      psubw mm3,mm5
215      movq [TMP1], mm0
216      psraw mm3,mm7
217      movq [TMP1 + 8], mm1
218      movq [TMP1+16],mm2
219      lea _EAX, [_EAX+32]
220      movq [TMP1+24],mm3
221    
222      dec TMP0
223      lea TMP1, [TMP1+32]
224      jne .loop_low
225    
226    .end:
227    
228      pop _EAX
229    
230      mov TMP1, prm1     ; coeff
231      mov [TMP1],ax
232      xor _EAX,_EAX       ; return 0
233    
234                  ret                  ret
235    ENDFUNC
 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                ;  
                 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     .q1loop  
                 jmp     short .done  
236    
237    
238    ;-----------------------------------------------------------------------------
 ;===========================================================================  
239  ;  ;
240  ; void quant_intra_sse2(int16_t * coeff,  ; uint32_t quant_h263_intra_sse2(int16_t * coeff,
241  ;                                       const int16_t const * data,  ;                                       const int16_t const * data,
242  ;                                       const uint32_t quant,  ;                                       const uint32_t quant,
243  ;                                       const uint32_t dcscalar);  ;                                const uint32_t dcscalar,
244    ;                                const uint16_t *mpeg_matrices);
245  ;  ;
246  ;===========================================================================  ;-----------------------------------------------------------------------------
247    
248  align ALIGN  ALIGN SECTION_ALIGN
 cglobal quant_h263_intra_sse2  
249  quant_h263_intra_sse2:  quant_h263_intra_sse2:
250      PUSH_XMM6_XMM7
251      mov _EAX, prm2     ; data
252    
253                  push    esi    movsx _EAX, word [_EAX]      ; data[0]
                 push    edi  
   
                 mov             edi, [esp + 8 + 4]                      ; coeff  
                 mov             esi, [esp + 8 + 8]                      ; data  
                 mov             eax, [esp + 8 + 12]                     ; quant  
254    
255                  xor             ecx, ecx    mov TMP0,prm4     ; dcscalar
256                  cmp             al, 1    mov TMP1,_EAX
257                  jz              near .qas2_q1loop    sar TMP0,1
258      add _EAX,TMP0
259      sub TMP1,TMP0
260      cmovl _EAX,TMP1              ; +/- dcscalar/2
261      mov TMP0, prm3    ; quant
262      lea TMP1, [mmx_div]
263      movq xmm7, [TMP1+TMP0 * 8 - 8]
264    
265    %ifdef ARCH_IS_X86_64
266    %ifdef WINDOWS
267      mov TMP1, prm2
268    %endif
269    %endif
270      cdq
271      idiv prm4d  ; dcscalar
272    %ifdef ARCH_IS_X86_64
273    %ifdef WINDOWS
274      mov prm2, TMP1
275    %endif
276    %endif
277      cmp TMP0, 1
278      mov TMP1, prm1     ; coeff
279      je near .low
280    
281      mov TMP0, prm2
282      push _EAX ; DC
283      mov _EAX, TMP0
284    
285  .qas2_not1    mov TMP0,2
                 movq    mm7, [mmx_div + eax*8 - 8]  
                 movq2dq xmm7, mm7  
286                  movlhps xmm7, xmm7                  movlhps xmm7, xmm7
287    
288  align 16  .loop:
289  .qas2_loop    movdqa xmm0, [_EAX]
                 movdqa  xmm0, [esi + ecx*8]                     ; xmm0 = [1st]  
                 movdqa  xmm3, [esi + ecx*8 + 16]        ; xmm3 = [2nd]  
                 pxor    xmm1, xmm1  
290                  pxor    xmm4, xmm4                  pxor    xmm4, xmm4
291                  pcmpgtw xmm1, xmm0    movdqa xmm1, [_EAX + 16]
292                  pcmpgtw xmm4, xmm3    pcmpgtw xmm4,xmm0
293                  pxor    xmm0, xmm1    pxor xmm5,xmm5
                 pxor    xmm3, xmm4  
                 psubw   xmm0, xmm1  
                 psubw   xmm3, xmm4  
294                  pmulhw  xmm0, xmm7                  pmulhw  xmm0, xmm7
295      pcmpgtw xmm5,xmm1
296      movdqa xmm2, [_EAX+32]
297      psubw xmm0,xmm4
298      pmulhw xmm1,xmm7
299      pxor xmm4,xmm4
300      movdqa xmm3,[_EAX+48]
301      pcmpgtw xmm4,xmm2
302      psubw xmm1,xmm5
303      pmulhw xmm2,xmm7
304      pxor xmm5,xmm5
305      pcmpgtw xmm5,xmm3
306                  pmulhw  xmm3, xmm7                  pmulhw  xmm3, xmm7
307                  pxor    xmm0, xmm1    psubw xmm2,xmm4
308                  pxor    xmm3, xmm4    psubw xmm3,xmm5
309                  psubw   xmm0, xmm1    movdqa [TMP1], xmm0
310                  psubw   xmm3, xmm4    lea _EAX, [_EAX+64]
311                  movdqa  [edi + ecx*8], xmm0    movdqa [TMP1 + 16], xmm1
312                  movdqa  [edi + ecx*8 + 16], xmm3    movdqa [TMP1 + 32], xmm2
313      movdqa [TMP1 + 48], xmm3
314                  add             ecx, 4  
315                  cmp             ecx, 16    dec TMP0
316                  jnz     .qas2_loop    lea TMP1, [TMP1+64]
317      jne .loop
318  .qas2_done    jmp .end
319                  mov     ecx, [esp + 8 + 16]     ; dcscalar  
320                  mov     edx, ecx  .low:
321                  movsx   eax, word [esi]    movd xmm7,TMP0d
322                  shr     edx, 1  
323                  cmp             eax, 0    mov TMP0, prm2
324                  jg              .qas2_gtzero    push _EAX ; DC
325      mov _EAX, TMP0
326                  sub             eax, edx  
327                  jmp             short .qas2_mul    mov TMP0,2
328  .qas2_gtzero  .loop_low:
329                  add             eax, edx    movdqa xmm0, [_EAX]
 .qas2_mul  
                 cdq  
                 idiv    ecx  
   
                 mov             [edi], ax  
   
                 pop             edi  
                 pop             esi  
   
                 ret  
   
 align 16  
 .qas2_q1loop  
                 movdqa  xmm0, [esi + ecx*8]                     ; xmm0 = [1st]  
                 movdqa  xmm3, [esi + ecx*8 + 16]        ; xmm3 = [2nd]  
                 pxor    xmm1, xmm1  
330                  pxor    xmm4, xmm4                  pxor    xmm4, xmm4
331                  pcmpgtw xmm1, xmm0    movdqa xmm1, [_EAX + 16]
332                  pcmpgtw xmm4, xmm3    pcmpgtw xmm4,xmm0
333                  pxor    xmm0, xmm1    pxor xmm5,xmm5
334                  pxor    xmm3, xmm4    psubw xmm0,xmm4
335                  psubw   xmm0, xmm1    pcmpgtw xmm5,xmm1
336                  psubw   xmm3, xmm4    psraw xmm0,xmm7
337                  psrlw   xmm0, 1    psubw xmm1,xmm5
338                  psrlw   xmm3, 1    movdqa xmm2,[_EAX+32]
339                  pxor    xmm0, xmm1    pxor xmm4,xmm4
340                  pxor    xmm3, xmm4    psraw xmm1,xmm7
341                  psubw   xmm0, xmm1    pcmpgtw xmm4,xmm2
342                  psubw   xmm3, xmm4    pxor xmm5,xmm5
343                  movdqa  [edi + ecx*8], xmm0    psubw xmm2,xmm4
344                  movdqa  [edi + ecx*8 + 16], xmm3    movdqa xmm3,[_EAX+48]
345      pcmpgtw xmm5,xmm3
346                  add             ecx, 4    psraw xmm2,xmm7
347                  cmp             ecx, 16    psubw xmm3,xmm5
348                  jnz             .qas2_q1loop    movdqa [TMP1], xmm0
349                  jmp             near .qas2_done    psraw xmm3,xmm7
350      movdqa [TMP1+16], xmm1
351      movdqa [TMP1+32],xmm2
352      lea _EAX, [_EAX+64]
353      movdqa [TMP1+48],xmm3
354    
355      dec TMP0
356      lea TMP1, [TMP1+64]
357      jne .loop_low
358    
359    .end:
360    
361      pop _EAX
362    
363      mov TMP1, prm1     ; coeff
364      mov [TMP1],ax
365      xor _EAX,_EAX            ; return 0
366      POP_XMM6_XMM7
367      ret
368    ENDFUNC
369    
370  ;===========================================================================  ;-----------------------------------------------------------------------------
371  ;  ;
372  ; uint32_t quant_inter_mmx(int16_t * coeff,  ; uint32_t quant_h263_inter_mmx(int16_t * coeff,
373  ;                                       const int16_t const * data,  ;                                       const int16_t const * data,
374  ;                                       const uint32_t quant);  ;                               const uint32_t quant,
375    ;                               const uint16_t *mpeg_matrices);
376  ;  ;
377  ;===========================================================================  ;-----------------------------------------------------------------------------
378    
379  align ALIGN  ALIGN SECTION_ALIGN
 cglobal quant_h263_inter_mmx  
380  quant_h263_inter_mmx:  quant_h263_inter_mmx:
381    
382                  push    ecx    mov TMP1, prm1           ; coeff
383                  push    esi    mov _EAX, prm3           ; quant
                 push    edi  
   
                 mov     edi, [esp + 12 + 4]             ; coeff  
                 mov     esi, [esp + 12 + 8]             ; data  
                 mov     eax, [esp + 12 + 12]    ; quant  
   
                 xor ecx, ecx  
384    
385                  pxor mm5, mm5                                   ; sum                  pxor mm5, mm5                                   ; sum
386                  movq mm6, [mmx_sub + eax * 8 - 8]       ; sub    lea TMP0, [mmx_sub]
387      movq mm6, [TMP0 + _EAX * 8 - 8] ; sub
388    
389                  cmp     al, 1                  cmp     al, 1
390                  jz  .q1loop    jz near .q1routine
391    
392                  movq    mm7, [mmx_div + eax * 8 - 8]    ; divider    lea TMP0, [mmx_div]
393      movq mm7, [TMP0 + _EAX * 8 - 8] ; divider
394    
395  align ALIGN    xor TMP0, TMP0
396  .loop    mov _EAX, prm2           ; data
397                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]  
398                  movq    mm3, [esi + 8*ecx + 8]  ;  ALIGN SECTION_ALIGN
399    .loop:
400      movq mm0, [_EAX + 8*TMP0]           ; mm0 = [1st]
401      movq mm3, [_EAX + 8*TMP0 + 8]
402                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
403                  pxor    mm4, mm4                ;                  pxor    mm4, mm4                ;
404                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
# Line 538  Line 417 
417                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
418                  psubw   mm0, mm1                ; undisplace                  psubw   mm0, mm1                ; undisplace
419                  psubw   mm3, mm4                  psubw   mm3, mm4
420                  movq    [edi + 8*ecx], mm0    movq [TMP1 + 8*TMP0], mm0
421                  movq    [edi + 8*ecx + 8], mm3    movq [TMP1 + 8*TMP0 + 8], mm3
422    
423                  add ecx, 2    add TMP0, 2
424                  cmp ecx, 16    cmp TMP0, 16
425                  jnz .loop                  jnz .loop
426    
427  .done  .done:
428                  pmaddwd mm5, [plus_one]                  pmaddwd mm5, [plus_one]
429                  movq    mm0, mm5                  movq    mm0, mm5
430                  psrlq   mm5, 32                  psrlq   mm5, 32
431                  paddd   mm0, mm5                  paddd   mm0, mm5
                 movd    eax, mm0                ; return sum  
432    
433                  pop     edi    movd eax, mm0     ; return sum
                 pop     esi  
                 pop ecx  
434    
435                  ret                  ret
436    
437  align ALIGN  .q1routine:
438  .q1loop    xor TMP0, TMP0
439                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]    mov _EAX, prm2           ; data
440                  movq    mm3, [esi + 8*ecx+ 8]           ;  
441    ALIGN SECTION_ALIGN
442    .q1loop:
443      movq mm0, [_EAX + 8*TMP0]           ; mm0 = [1st]
444      movq mm3, [_EAX + 8*TMP0+ 8]        ;
445                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
446                  pxor    mm4, mm4                ;                  pxor    mm4, mm4                ;
447                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
# Line 580  Line 460 
460                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
461                  psubw   mm0, mm1                ; undisplace                  psubw   mm0, mm1                ; undisplace
462                  psubw   mm3, mm4                  psubw   mm3, mm4
463                  movq    [edi + 8*ecx], mm0    movq [TMP1 + 8*TMP0], mm0
464                  movq    [edi + 8*ecx + 8], mm3    movq [TMP1 + 8*TMP0 + 8], mm3
465    
466                  add ecx,2    add TMP0, 2
467                  cmp ecx,16    cmp TMP0, 16
468                  jnz     .q1loop                  jnz     .q1loop
469    
470                  jmp     .done                  jmp     .done
471    ENDFUNC
472    
473    
474    
475  ;===========================================================================  ;-----------------------------------------------------------------------------
476  ;  ;
477  ; uint32_t quant_inter_sse2(int16_t * coeff,  ; uint32_t quant_h263_inter_sse2(int16_t * coeff,
478  ;                                       const int16_t const * data,  ;                                       const int16_t const * data,
479  ;                                       const uint32_t quant);  ;                                const uint32_t quant,
480    ;                                const uint16_t *mpeg_matrices);
481  ;  ;
482  ;===========================================================================  ;-----------------------------------------------------------------------------
483    
484  align 16  ALIGN SECTION_ALIGN
 cglobal quant_h263_inter_sse2  
485  quant_h263_inter_sse2:  quant_h263_inter_sse2:
486      PUSH_XMM6_XMM7
487    
488                  push    esi    mov TMP1, prm1      ; coeff
489                  push    edi    mov _EAX, prm3      ; quant
   
                 mov             edi, [esp + 8 + 4]                      ; coeff  
                 mov             esi, [esp + 8 + 8]                      ; data  
                 mov             eax, [esp + 8 + 12]                     ; quant  
   
                 xor             ecx, ecx  
490    
491                  pxor    xmm5, xmm5                                      ; sum                  pxor    xmm5, xmm5                                      ; sum
492    
493                  movq    mm0, [mmx_sub + eax*8 - 8]      ; sub    lea TMP0, [mmx_sub]
494      movq mm0, [TMP0 + _EAX*8 - 8]             ; sub
495                  movq2dq xmm6, mm0                                       ; load into low 8 bytes                  movq2dq xmm6, mm0                                       ; load into low 8 bytes
496                  movlhps xmm6, xmm6                                      ; duplicate into high 8 bytes                  movlhps xmm6, xmm6                                      ; duplicate into high 8 bytes
497    
498                  cmp             al, 1                  cmp             al, 1
499                  jz              near .qes2_q1loop    jz near .qes2_q1_routine
500    
501    .qes2_not1:
502      lea TMP0, [mmx_div]
503      movq mm0, [TMP0 + _EAX*8 - 8]          ; divider
504    
505      xor TMP0, TMP0
506      mov _EAX, prm2      ; data
507    
 .qes2_not1  
                 movq    mm0, [mmx_div + eax*8 - 8]      ; divider  
508                  movq2dq xmm7, mm0                  movq2dq xmm7, mm0
509                  movlhps xmm7, xmm7                  movlhps xmm7, xmm7
510    
511  align 16  ALIGN SECTION_ALIGN
512  .qes2_loop  .qes2_loop:
513                  movdqa  xmm0, [esi + ecx*8]                     ; xmm0 = [1st]    movdqa xmm0, [_EAX + TMP0*8]               ; xmm0 = [1st]
514                  movdqa  xmm3, [esi + ecx*8 + 16]        ; xmm3 = [2nd]    movdqa xmm3, [_EAX + TMP0*8 + 16]          ; xmm3 = [2nd]
515                  pxor    xmm1, xmm1                  pxor    xmm1, xmm1
516                  pxor    xmm4, xmm4                  pxor    xmm4, xmm4
517                  pcmpgtw xmm1, xmm0                  pcmpgtw xmm1, xmm0
# Line 648  Line 530 
530                  pxor    xmm3, xmm4                  pxor    xmm3, xmm4
531                  psubw   xmm0, xmm1                  psubw   xmm0, xmm1
532                  psubw   xmm3, xmm4                  psubw   xmm3, xmm4
533                  movdqa  [edi + ecx*8], xmm0    movdqa [TMP1 + TMP0*8], xmm0
534                  movdqa  [edi + ecx*8 + 16], xmm3    movdqa [TMP1 + TMP0*8 + 16], xmm3
535    
536                  add             ecx, 4    add TMP0, 4
537                  cmp             ecx, 16    cmp TMP0, 16
538                  jnz             .qes2_loop                  jnz             .qes2_loop
539    
540  .qes2_done  .qes2_done:
541                  movdqu  xmm6, [plus_one]                  movdqu  xmm6, [plus_one]
542                  pmaddwd xmm5, xmm6                  pmaddwd xmm5, xmm6
543                  movhlps xmm6, xmm5                  movhlps xmm6, xmm5
# Line 665  Line 547 
547                  movq    mm5, mm0                  movq    mm5, mm0
548                  psrlq   mm5, 32                  psrlq   mm5, 32
549                  paddd   mm0, mm5                  paddd   mm0, mm5
                 movd    eax, mm0                                        ; return sum  
550    
551                  pop             edi    movd eax, mm0         ; return sum
                 pop             esi  
552    
553      POP_XMM6_XMM7
554                  ret                  ret
555    
556  align 16  .qes2_q1_routine:
557  .qes2_q1loop    xor TMP0, TMP0
558                  movdqa  xmm0, [esi + ecx*8]                     ; xmm0 = [1st]    mov _EAX, prm2      ; data
559                  movdqa  xmm3, [esi + ecx*8 + 16]        ; xmm3 = [2nd]  
560    ALIGN SECTION_ALIGN
561    .qes2_q1loop:
562      movdqa xmm0, [_EAX + TMP0*8]        ; xmm0 = [1st]
563      movdqa xmm3, [_EAX + TMP0*8 + 16]   ; xmm3 = [2nd]
564                  pxor    xmm1, xmm1                  pxor    xmm1, xmm1
565                  pxor    xmm4, xmm4                  pxor    xmm4, xmm4
566                  pcmpgtw xmm1, xmm0                  pcmpgtw xmm1, xmm0
# Line 694  Line 579 
579                  pxor    xmm3, xmm4                  pxor    xmm3, xmm4
580                  psubw   xmm0, xmm1                  psubw   xmm0, xmm1
581                  psubw   xmm3, xmm4                  psubw   xmm3, xmm4
582                  movdqa  [edi + ecx*8], xmm0    movdqa [TMP1 + TMP0*8], xmm0
583                  movdqa  [edi + ecx*8 + 16], xmm3    movdqa [TMP1 + TMP0*8 + 16], xmm3
584    
585                  add             ecx,4    add TMP0, 4
586                  cmp             ecx,16    cmp TMP0, 16
587                  jnz             .qes2_q1loop                  jnz             .qes2_q1loop
588                  jmp             .qes2_done                  jmp             .qes2_done
589    ENDFUNC
590    
591    
592  ;===========================================================================  ;-----------------------------------------------------------------------------
593  ;  ;
594  ; void dequant_intra_mmx(int16_t *data,  ; uint32_t dequant_h263_intra_mmx(int16_t *data,
595  ;                                       const int16_t const *coeff,  ;                                       const int16_t const *coeff,
596  ;                                       const uint32_t quant,  ;                                       const uint32_t quant,
597  ;                                       const uint32_t dcscalar);  ;                                 const uint32_t dcscalar,
598    ;                                 const uint16_t *mpeg_matrices);
599  ;  ;
600  ;===========================================================================  ;-----------------------------------------------------------------------------
   
   ; note: we only saturate to +2047 *before* restoring the sign.  
   ; Hence, final clamp really is [-2048,2047]  
601    
602  align ALIGN  ALIGN SECTION_ALIGN
 cglobal dequant_h263_intra_mmx  
603  dequant_h263_intra_mmx:  dequant_h263_intra_mmx:
604    
605    mov    edx, [esp+ 4]        ; data    mov TMP0, prm3                 ; quant
606    mov    ecx, [esp+ 8]        ; coeff    mov _EAX, prm2                 ; coeff
607    mov    eax, [esp+12]        ; quant    pcmpeqw mm0,mm0
608    movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1    lea TMP1, [mmx_quant]
609    movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant    movq mm6, [TMP1 + TMP0*8] ; quant
610    mov eax, -16    shl TMP0,31                    ; quant & 1 ? 0 : - 1
611      movq mm7,mm6
612  align ALIGN    movq mm5,mm0
613  .loop    movd mm1,TMP0d
614    movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]    mov TMP1, prm1                 ; data
615    movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]    psllw mm0,mm1
616    pxor mm1, mm1    paddw mm7,mm7                  ; 2*quant
617      paddw mm6,mm0                  ; quant-1
618      psllw mm5,12
619      mov TMP0,8
620      psrlw mm5,1
621    
622    .loop:
623      movq mm0,[_EAX]
624      pxor mm2,mm2
625    pxor mm4, mm4    pxor mm4, mm4
626    pcmpgtw mm1, mm0  ; sign(c)    pcmpgtw mm2,mm0
627    pcmpgtw mm4, mm3  ; sign(c')    pcmpeqw mm4,mm0
628      pmullw mm0,mm7      ; * 2 * quant
629      movq mm1,[_EAX+8]
630      psubw mm0,mm2
631      pxor mm2,mm6
632      pxor mm3,mm3
633      pandn mm4,mm2
634    pxor mm2, mm2    pxor mm2, mm2
635    pxor mm5, mm5    pcmpgtw mm3,mm1
636    pcmpeqw mm2, mm0  ; c is zero    pcmpeqw mm2,mm1
637    pcmpeqw mm5, mm3  ; c' is zero    pmullw mm1,mm7
638    pandn mm2, mm6    ; offset = isZero ? 0 : quant_add    paddw mm0,mm4
639    pandn mm5, mm6    psubw mm1,mm3
640    pxor mm0, mm1     ; negate if negative    pxor mm3,mm6
641    pxor mm3, mm4     ; negate if negative    pandn mm2,mm3
642    psubw mm0, mm1    paddsw mm0, mm5        ; saturate
643    psubw mm3, mm4    paddw mm1,mm2
644    pmullw mm0, mm7 ; *= 2Q  
645    pmullw mm3, mm7 ; *= 2Q    paddsw mm1, mm5
646    paddw mm0, mm2 ; + offset    psubsw mm0, mm5
647    paddw mm3, mm5 ; + offset    psubsw mm1, mm5
648    paddw mm0, mm1 ; negate back    psubsw mm0, mm5
649    paddw mm3, mm4 ; negate back    psubsw mm1, mm5
650      paddsw mm0, mm5
651      ; saturates to +2047    paddsw mm1, mm5
652    movq mm2, [mmx_32767_minus_2047]  
653    add eax, 2    movq [TMP1],mm0
654    paddsw mm0, mm2    lea _EAX,[_EAX+16]
655    paddsw mm3, mm2    movq [TMP1+8],mm1
656    psubsw mm0, mm2  
657    psubsw mm3, mm2    dec TMP0
658      lea TMP1,[TMP1+16]
659    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  
660    
661      ; deal with DC      ; deal with DC
662      mov _EAX, prm2               ; coeff
663    movd mm0, [ecx]    movd mm1,prm4d                ; dcscalar
664    pmullw mm0, [esp+16]    ; dcscalar    movd mm0,[_EAX]                   ; coeff[0]
665    movq mm2, [mmx_32767_minus_2047]    pmullw mm0,mm1                   ; * dcscalar
666    paddsw mm0, mm2    mov TMP1, prm1               ; data
667    psubsw mm0, mm2    paddsw mm0, mm5                  ; saturate +
668    movq mm3, [mmx_32768_minus_2048]    psubsw mm0, mm5
669    psubsw mm0, mm3    psubsw mm0, mm5                  ; saturate -
670    paddsw mm0, mm3    paddsw mm0, mm5
671    movd eax, mm0    movd eax, mm0
672    mov [edx], ax    mov [TMP1], ax
673    
674      xor _EAX, _EAX                    ; return 0
675    ret    ret
676    ENDFUNC
677    
678  ;===========================================================================  ;-----------------------------------------------------------------------------
679  ;  ;
680  ; void dequant_intra_xmm(int16_t *data,  ; uint32_t dequant_h263_intra_xmm(int16_t *data,
681  ;                                       const int16_t const *coeff,  ;                                       const int16_t const *coeff,
682  ;                                       const uint32_t quant,  ;                                       const uint32_t quant,
683  ;                                       const uint32_t dcscalar);  ;                                 const uint32_t dcscalar,
684    ;                                 const uint16_t *mpeg_matrices);
685  ;  ;
686  ;===========================================================================  ;-----------------------------------------------------------------------------
687    
   ; this is the same as dequant_inter_mmx, except that we're  
   ; saturating using 'pminsw' (saves 2 cycles/loop => ~5% faster)  
688    
689  align ALIGN  ALIGN SECTION_ALIGN
 cglobal dequant_h263_intra_xmm  
690  dequant_h263_intra_xmm:  dequant_h263_intra_xmm:
691    
692    mov    edx, [esp+ 4]        ; data    mov TMP0, prm3                 ; quant
693    mov    ecx, [esp+ 8]        ; coeff    mov _EAX, prm2                 ; coeff
694    mov    eax, [esp+12]        ; quant  
695    movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1    movd mm6,TMP0d                  ; quant
696    movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant    pcmpeqw mm0,mm0
697    mov eax, -16    pshufw mm6,mm6,0               ; all quant
698      shl TMP0,31
699  align ALIGN    movq mm5,mm0
700  .loop    movq mm7,mm6
701    movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]    movd mm1,TMP0d
702    movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]    mov TMP1, prm1                 ; data
703    pxor mm1, mm1    psllw mm0,mm1                  ; quant & 1 ? 0 : - 1
704    pxor mm4, mm4    movq mm4,mm5
705    pcmpgtw mm1, mm0  ; sign(c)    paddw mm7,mm7                  ; quant*2
706    pcmpgtw mm4, mm3  ; sign(c')    paddw mm6,mm0                  ; quant-1
707      psrlw mm4,5                    ; mm4=2047
708      mov TMP0,8
709      pxor mm5,mm4                   ; mm5=-2048
710    
711    .loop:
712      movq mm0,[_EAX]
713    pxor mm2, mm2    pxor mm2, mm2
714    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  
715    
716      ; deal with DC    pcmpgtw mm2,mm0
717      pcmpeqw mm3,mm0     ; if coeff==0...
718      pmullw mm0,mm7      ; * 2 * quant
719      movq mm1,[_EAX+8]
720    
721      psubw mm0,mm2
722      pxor mm2,mm6
723      pandn mm3,mm2       ; ...then data=0
724      pxor mm2,mm2
725      paddw mm0,mm3
726      pxor mm3,mm3
727      pcmpeqw mm2,mm1
728      pcmpgtw mm3,mm1
729      pmullw mm1,mm7
730    
731      pminsw mm0,mm4
732      psubw mm1,mm3
733      pxor mm3,mm6
734      pandn mm2,mm3
735      paddw mm1,mm2
736    
737      pmaxsw mm0,mm5
738      pminsw mm1,mm4
739      movq [TMP1],mm0
740      pmaxsw mm1,mm5
741      lea _EAX,[_EAX+16]
742      movq [TMP1+8],mm1
743    
744      dec TMP0
745      lea TMP1,[TMP1+16]
746      jne .loop
747    
748    movd mm0, [ecx]     ; deal with DC
749    pmullw mm0, [esp+16]    ; dcscalar    mov _EAX, prm2                ; coeff
750    movq mm2, [mmx_32767_minus_2047]    movd mm1,prm4d                 ; dcscalar
751    paddsw mm0, mm2    movd mm0, [_EAX]
752    psubsw mm0, mm2    pmullw mm0, mm1
753    movq mm2, [mmx_32768_minus_2048]    mov TMP1, prm1                ; data
754    psubsw mm0, mm2    pminsw mm0,mm4
755    paddsw mm0, mm2    pmaxsw mm0,mm5
756    movd eax, mm0    movd eax, mm0
757    mov [edx], ax    mov [TMP1], ax
758    
759      xor _EAX, _EAX                ; return 0
760    ret    ret
761    ENDFUNC
762    
763    
764  ;===========================================================================  ;-----------------------------------------------------------------------------
765  ;  ;
766  ; void dequant_intra_sse2(int16_t *data,  ; uint32_t dequant_h263_intra_sse2(int16_t *data,
767  ;                                       const int16_t const *coeff,  ;                                       const int16_t const *coeff,
768  ;                                       const uint32_t quant,  ;                                       const uint32_t quant,
769  ;                                       const uint32_t dcscalar);  ;                                  const uint32_t dcscalar,
770    ;                                  const uint16_t *mpeg_matrices);
771  ;  ;
772  ;===========================================================================  ;-----------------------------------------------------------------------------
773  align ALIGN  
774  cglobal dequant_h263_intra_sse2  ALIGN SECTION_ALIGN
775  dequant_h263_intra_sse2:  dequant_h263_intra_sse2:
776          mov edx, [esp+ 4]        ; data    PUSH_XMM6_XMM7
         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  
777    
778  align ALIGN    mov TMP0, prm3                 ; quant
779  .loop    mov _EAX, prm2                 ; coeff
780          movdqa xmm0, [ecx + 8*16 + 8*eax]      ; c  = coeff[i]  
781          movdqa xmm3, [ecx + 8*16 + 8*eax+ 16]    movd xmm6,TMP0d                     ; quant
782          pxor xmm1, xmm1  
783          pxor xmm4, xmm4    shl TMP0,31
784          pcmpgtw xmm1, xmm0  ; sign(c)    pshuflw xmm6,xmm6,0
785          pcmpgtw xmm4, xmm3    pcmpeqw xmm0,xmm0
786      movlhps xmm6,xmm6                 ; all quant
787      movd xmm1,TMP0d
788      movdqa xmm5,xmm0
789      movdqa xmm7,xmm6
790      mov TMP1, prm1                 ; data
791      paddw xmm7,xmm7                   ; quant *2
792      psllw xmm0,xmm1                   ; quant & 1 ? 0 : - 1
793      movdqa xmm4,xmm5
794      paddw xmm6,xmm0                   ; quant-1
795      psrlw xmm4,5                      ; 2047
796      mov TMP0,4
797      pxor xmm5,xmm4                    ; mm5=-2048
798    
799    .loop:
800      movdqa xmm0,[_EAX]
801          pxor xmm2, xmm2          pxor xmm2, xmm2
802          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  
803    
804          pxor xmm0, xmm1    pcmpgtw xmm2,xmm0
805          pxor xmm3, xmm4    pcmpeqw xmm3,xmm0
806          movdqa [edx + 8*16 - 8*4 + 8*eax], xmm0    pmullw xmm0,xmm7      ; * 2 * quant
807          movdqa [edx + 8*16 - 8*4 + 8*eax + 16], xmm3    movdqa xmm1,[_EAX+16]
808          jnz     near .loop  
809      psubw xmm0,xmm2
810      pxor xmm2,xmm6
811      pandn xmm3,xmm2
812      pxor xmm2,xmm2
813      paddw xmm0,xmm3
814      pxor xmm3,xmm3
815      pcmpeqw xmm2,xmm1
816      pcmpgtw xmm3,xmm1
817      pmullw xmm1,xmm7
818    
819      pminsw xmm0,xmm4
820      psubw xmm1,xmm3
821      pxor xmm3,xmm6
822      pandn xmm2,xmm3
823      paddw xmm1,xmm2
824    
825      pmaxsw xmm0,xmm5
826      pminsw xmm1,xmm4
827      movdqa [TMP1],xmm0
828      pmaxsw xmm1,xmm5
829      lea _EAX,[_EAX+32]
830      movdqa [TMP1+16],xmm1
831    
832      dec TMP0
833      lea TMP1,[TMP1+32]
834      jne .loop
835    
836          ; 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  
837    
838          ret    mov _EAX, prm2             ; coeff
839      movsx _EAX,word [_EAX]
840      imul prm4d                 ; dcscalar
841      mov TMP1, prm1             ; data
842      movd xmm0,eax
843      pminsw xmm0,xmm4
844      pmaxsw xmm0,xmm5
845      movd eax,xmm0
846    
847      mov [TMP1], ax
848    
849      xor _EAX, _EAX                  ; return 0
850    
851      POP_XMM6_XMM7
852      ret
853    ENDFUNC
854    
855  ;===========================================================================  ;-----------------------------------------------------------------------------
856  ;  ;
857  ; void dequant_inter_mmx(int16_t * data,  ; uint32t dequant_h263_inter_mmx(int16_t * data,
858  ;                                       const int16_t * const coeff,  ;                                       const int16_t * const coeff,
859  ;                                       const uint32_t quant);  ;                                const uint32_t quant,
860    ;                                const uint16_t *mpeg_matrices);
861  ;  ;
862  ;===========================================================================  ;-----------------------------------------------------------------------------
863    
864  align ALIGN  ALIGN SECTION_ALIGN
 cglobal dequant_h263_inter_mmx  
865  dequant_h263_inter_mmx:  dequant_h263_inter_mmx:
866    
867    mov    edx, [esp+ 4]        ; data    mov TMP0, prm3                 ; quant
868    mov    ecx, [esp+ 8]        ; coeff    mov _EAX, prm2                 ; coeff
869    mov    eax, [esp+12]        ; quant    pcmpeqw mm0,mm0
870    movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1    lea TMP1, [mmx_quant]
871    movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant    movq mm6, [TMP1 + TMP0*8]      ; quant
872    mov eax, -16    shl TMP0,31                    ; odd/even
873      movq mm7,mm6
874  align ALIGN    movd mm1,TMP0d
875  .loop    mov TMP1, prm1                 ; data
876    movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]    movq mm5,mm0
877    movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]    psllw mm0,mm1                  ; quant & 1 ? 0 : - 1
878    pxor mm1, mm1    paddw mm7,mm7                  ; quant*2
879      paddw mm6,mm0                  ; quant & 1 ? quant : quant - 1
880      psllw mm5,12
881      mov TMP0,8
882      psrlw mm5,1                    ; 32767-2047 (32768-2048)
883    
884    .loop:
885      movq mm0,[_EAX]
886    pxor mm4, mm4    pxor mm4, mm4
   pcmpgtw mm1, mm0  ; sign(c)  
   pcmpgtw mm4, mm3  ; sign(c')  
887    pxor mm2, mm2    pxor mm2, mm2
888    pxor mm5, mm5    pcmpeqw mm4,mm0     ; if coeff==0...
889    pcmpeqw mm2, mm0  ; c is zero    pcmpgtw mm2,mm0
890    pcmpeqw mm5, mm3  ; c' is zero    pmullw mm0,mm7      ; * 2 * quant
891    pandn mm2, mm6    ; offset = isZero ? 0 : quant_add    pxor mm3,mm3
892    pandn mm5, mm6    psubw mm0,mm2
893    pxor mm0, mm1     ; negate if negative    movq mm1,[_EAX+8]
894    pxor mm3, mm4     ; negate if negative    pxor mm2,mm6
895    psubw mm0, mm1    pcmpgtw mm3,mm1
896    psubw mm3, mm4    pandn mm4,mm2      ; ... then data==0
897    pmullw mm0, mm7 ; *= 2Q    pmullw mm1,mm7
898    pmullw mm3, mm7 ; *= 2Q    pxor mm2,mm2
899    paddw mm0, mm2 ; + offset    pcmpeqw mm2,mm1
900    paddw mm3, mm5 ; + offset    psubw mm1,mm3
901    paddw mm0, mm1 ; negate back    pxor mm3,mm6
902    paddw mm3, mm4 ; negate back    pandn mm2,mm3
903      paddw mm0,mm4
904      ; saturates to +2047    paddw mm1,mm2
905    movq mm2, [mmx_32767_minus_2047]  
906    add eax, 2    paddsw mm0, mm5        ; saturate
907    paddsw mm0, mm2    paddsw mm1, mm5
908    paddsw mm3, mm2    psubsw mm0, mm5
909    psubsw mm0, mm2    psubsw mm1, mm5
910    psubsw mm3, mm2    psubsw mm0, mm5
911      psubsw mm1, mm5
912    pxor mm0, mm1    paddsw mm0, mm5
913    pxor mm3, mm4    paddsw mm1, mm5
914    movq [edx + 8*eax + 8*16   - 2*8], mm0  
915    movq [edx + 8*eax + 8*16+8 - 2*8], mm3    movq [TMP1],mm0
916    jnz   near .loop    lea _EAX,[_EAX+16]
917      movq [TMP1+8],mm1
918    
919      dec TMP0
920      lea TMP1,[TMP1+16]
921      jne .loop
922    
923      xor _EAX, _EAX              ; return 0
924    ret    ret
925    ENDFUNC
926    
927    
928  ;===========================================================================  ;-----------------------------------------------------------------------------
929  ;  ;
930  ; void dequant_inter_xmm(int16_t * data,  ; uint32_t dequant_h263_inter_xmm(int16_t * data,
931  ;                                       const int16_t * const coeff,  ;                                       const int16_t * const coeff,
932  ;                                       const uint32_t quant);  ;                                 const uint32_t quant,
933    ;                                 const uint16_t *mpeg_matrices);
934  ;  ;
935  ;===========================================================================  ;-----------------------------------------------------------------------------
936    ALIGN SECTION_ALIGN
   ; 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  
937  dequant_h263_inter_xmm:  dequant_h263_inter_xmm:
938    
939    mov    edx, [esp+ 4]        ; data    mov TMP0, prm3                 ; quant
940    mov    ecx, [esp+ 8]        ; coeff    mov _EAX, prm2                 ; coeff
941    mov    eax, [esp+12]        ; quant    pcmpeqw mm0,mm0
942    movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1    lea TMP1, [mmx_quant]
943    movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant    movq mm6, [TMP1 + TMP0*8]      ; quant
944    mov eax, -16    shl TMP0,31
945      movq mm5,mm0
946  align ALIGN    movd mm1,TMP0d
947  .loop    movq mm7,mm6
948    movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]    psllw mm0,mm1
949    movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]    mov TMP1, prm1                 ; data
950    pxor mm1, mm1    movq mm4,mm5
951    pxor mm4, mm4    paddw mm7,mm7
952    pcmpgtw mm1, mm0  ; sign(c)    paddw mm6,mm0                     ; quant-1
953    pcmpgtw mm4, mm3  ; sign(c')  
954      psrlw mm4,5
955      mov TMP0,8
956      pxor mm5,mm4                      ; mm5=-2048
957    
958    .loop:
959      movq mm0,[_EAX]
960      pxor mm3,mm3
961    pxor mm2, mm2    pxor mm2, mm2
962    pxor mm5, mm5    pcmpeqw mm3,mm0
963    pcmpeqw mm2, mm0  ; c is zero    pcmpgtw mm2,mm0
964    pcmpeqw mm5, mm3  ; c' is zero    pmullw mm0,mm7                    ; * 2 * quant
965    pandn mm2, mm6    ; offset = isZero ? 0 : quant_add    pandn mm3,mm6
966    pandn mm5, mm6    movq mm1,[_EAX+8]
967    pxor mm0, mm1     ; negate if negative    psubw mm0,mm2
968    pxor mm3, mm4     ; negate if negative    pxor mm2,mm3
969    psubw mm0, mm1    pxor mm3,mm3
970    psubw mm3, mm4    paddw mm0,mm2
971    pmullw mm0, mm7 ; *= 2Q    pxor mm2,mm2
972    pmullw mm3, mm7 ; *= 2Q    pcmpgtw mm3,mm1
973    paddw mm0, mm2 ; + offset    pcmpeqw mm2,mm1
974    paddw mm3, mm5 ; + offset    pmullw mm1,mm7
975    paddw mm0, mm1 ; start restoring sign    pandn mm2,mm6
976    paddw mm3, mm4 ; start restoring sign    psubw mm1,mm3
977      pxor mm3,mm2
978        ; saturates to +2047    paddw mm1,mm3
979    movq mm2, [mmx_2047]  
980    pminsw mm0, mm2    pminsw mm0,mm4
981    add eax, 2    pminsw mm1,mm4
982    pminsw mm3, mm2    pmaxsw mm0,mm5
983      pmaxsw mm1,mm5
984    pxor mm0, mm1 ; finish restoring sign  
985    pxor mm3, mm4 ; finish restoring sign    movq [TMP1],mm0
986    movq [edx + 8*eax + 8*16   - 2*8], mm0    lea _EAX,[_EAX+16]
987    movq [edx + 8*eax + 8*16+8 - 2*8], mm3    movq [TMP1+8],mm1
988    jnz   near .loop  
989      dec TMP0
990      lea TMP1,[TMP1+16]
991      jne .loop
992    
993      xor _EAX, _EAX              ; return 0
994    ret    ret
995    ENDFUNC
996    
997    
998  ;===========================================================================  ;-----------------------------------------------------------------------------
999  ;  ;
1000  ; void dequant_inter_sse2(int16_t * data,  ; uint32_t dequant_h263_inter_sse2(int16_t * data,
1001  ;                                       const int16_t * const coeff,  ;                                       const int16_t * const coeff,
1002  ;                                       const uint32_t quant);  ;                                  const uint32_t quant,
1003    ;                                  const uint16_t *mpeg_matrices);
1004  ;  ;
1005  ;===========================================================================  ;-----------------------------------------------------------------------------
1006  align ALIGN  
1007  cglobal dequant_h263_inter_sse2  ALIGN SECTION_ALIGN
1008  dequant_h263_inter_sse2:  dequant_h263_inter_sse2:
1009          mov edx, [esp + 4]      ; data    PUSH_XMM6_XMM7
         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  
1010    
1011  align ALIGN    mov TMP0, prm3                 ; quant
1012  .loop    mov _EAX, prm2                 ; coeff
         movdqa xmm0, [ecx + 8*16 + 8*eax]  ; c  = coeff[i]  
         movdqa xmm3, [ecx + 8*16 + 8*eax + 16]  
1013    
1014          pxor xmm1, xmm1    lea TMP1, [mmx_quant]
1015          pxor xmm4, xmm4    movq xmm6, [TMP1 + TMP0*8]    ; quant
1016          pcmpgtw xmm1, xmm0  ; sign(c)    inc TMP0
1017          pcmpgtw xmm4, xmm3    pcmpeqw xmm5,xmm5
1018      and TMP0,1
1019      movlhps xmm6,xmm6
1020      movd xmm0,TMP0d
1021      movdqa xmm7,xmm6
1022      pshuflw xmm0,xmm0,0
1023      movdqa xmm4,xmm5
1024      mov TMP1, prm1                 ; data
1025      movlhps xmm0,xmm0
1026      paddw xmm7,xmm7
1027      psubw xmm6,xmm0
1028      psrlw xmm4,5   ; 2047
1029      mov TMP0,4
1030      pxor xmm5,xmm4 ; mm5=-2048
1031    
1032    .loop:
1033      movdqa xmm0,[_EAX]
1034      pxor xmm3,xmm3
1035          pxor xmm2, xmm2          pxor xmm2, xmm2
1036          pxor xmm5, xmm5    pcmpeqw xmm3,xmm0
1037          pcmpeqw xmm2, xmm0  ; c is zero    pcmpgtw xmm2,xmm0
1038          pcmpeqw xmm5, xmm3    pmullw xmm0,xmm7      ; * 2 * quant
1039      pandn xmm3,xmm6
1040      movdqa xmm1,[_EAX+16]
1041      psubw xmm0,xmm2
1042      pxor xmm2,xmm3
1043      pxor xmm3,xmm3
1044      paddw xmm0,xmm2
1045      pxor xmm2,xmm2
1046      pcmpgtw xmm3,xmm1
1047      pcmpeqw xmm2,xmm1
1048      pmullw xmm1,xmm7
1049          pandn xmm2, xmm6          pandn xmm2, xmm6
1050          pandn xmm5, xmm6    psubw xmm1,xmm3
1051          pxor xmm0, xmm1  ; negate if negative    pxor xmm3,xmm2
1052          pxor xmm3, xmm4    paddw xmm1,xmm3
1053          psubw xmm0, xmm1  
1054          psubw xmm3, xmm4    pminsw xmm0,xmm4
1055          pmullw xmm0, xmm7  ; *= 2Q    pminsw xmm1,xmm4
1056          pmullw xmm3, xmm7    pmaxsw xmm0,xmm5
1057          paddw xmm0, xmm2  ; + offset    pmaxsw xmm1,xmm5
1058          paddw xmm3, xmm5  
1059      movdqa [TMP1],xmm0
1060          paddw xmm0, xmm1  ; start restoring sign    lea _EAX,[_EAX+32]
1061          paddw xmm3, xmm4    movdqa [TMP1+16],xmm1
1062    
1063          ; saturates to +2047    dec TMP0
1064          movdqa xmm2, [sse2_2047]    lea TMP1,[TMP1+32]
1065          pminsw xmm0, xmm2    jne .loop
         add eax, 4  
         pminsw xmm3, xmm2  
1066    
1067          pxor xmm0, xmm1 ; finish restoring sign    xor _EAX, _EAX              ; return 0
         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  
1068    
1069      POP_XMM6_XMM7
1070          ret          ret
1071    ENDFUNC
1072    
1073    
1074    %ifidn __OUTPUT_FORMAT__,elf
1075    section ".note.GNU-stack" noalloc noexec nowrite progbits
1076    %endif
1077    

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

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