[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.15, Thu Dec 4 18:30:36 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    TEXT
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                  movq2dq xmm6, mm0                                       ; load into low 8 bytes    movq xmm6, [TMP0 + _EAX*8 - 8]             ; sub
495                  movlhps xmm6, xmm6                                      ; duplicate into high 8 bytes                  movlhps xmm6, xmm6                                      ; duplicate into high 8 bytes
496    
497                  cmp             al, 1                  cmp             al, 1
498                  jz              near .qes2_q1loop    jz near .qes2_q1_routine
499    
500    .qes2_not1:
501      lea TMP0, [mmx_div]
502      movq xmm7, [TMP0 + _EAX*8 - 8]          ; divider
503    
504      xor TMP0, TMP0
505      mov _EAX, prm2      ; data
506    
 .qes2_not1  
                 movq    mm0, [mmx_div + eax*8 - 8]      ; divider  
                 movq2dq xmm7, mm0  
507                  movlhps xmm7, xmm7                  movlhps xmm7, xmm7
508    
509  align 16  ALIGN SECTION_ALIGN
510  .qes2_loop  .qes2_loop:
511                  movdqa  xmm0, [esi + ecx*8]                     ; xmm0 = [1st]    movdqa xmm0, [_EAX + TMP0*8]               ; xmm0 = [1st]
512                  movdqa  xmm3, [esi + ecx*8 + 16]        ; xmm3 = [2nd]    movdqa xmm3, [_EAX + TMP0*8 + 16]          ; xmm3 = [2nd]
513                  pxor    xmm1, xmm1                  pxor    xmm1, xmm1
514                  pxor    xmm4, xmm4                  pxor    xmm4, xmm4
515                  pcmpgtw xmm1, xmm0                  pcmpgtw xmm1, xmm0
# Line 648  Line 528 
528                  pxor    xmm3, xmm4                  pxor    xmm3, xmm4
529                  psubw   xmm0, xmm1                  psubw   xmm0, xmm1
530                  psubw   xmm3, xmm4                  psubw   xmm3, xmm4
531                  movdqa  [edi + ecx*8], xmm0    movdqa [TMP1 + TMP0*8], xmm0
532                  movdqa  [edi + ecx*8 + 16], xmm3    movdqa [TMP1 + TMP0*8 + 16], xmm3
533    
534                  add             ecx, 4    add TMP0, 4
535                  cmp             ecx, 16    cmp TMP0, 16
536                  jnz             .qes2_loop                  jnz             .qes2_loop
537    
538  .qes2_done  .qes2_done:
539                  movdqu  xmm6, [plus_one]    movdqa xmm6, [plus_one]
540                  pmaddwd xmm5, xmm6                  pmaddwd xmm5, xmm6
541                  movhlps xmm6, xmm5                  movhlps xmm6, xmm5
542                  paddd   xmm5, xmm6                  paddd   xmm5, xmm6
# Line 665  Line 545 
545                  movq    mm5, mm0                  movq    mm5, mm0
546                  psrlq   mm5, 32                  psrlq   mm5, 32
547                  paddd   mm0, mm5                  paddd   mm0, mm5
                 movd    eax, mm0                                        ; return sum  
548    
549                  pop             edi    movd eax, mm0         ; return sum
                 pop             esi  
550    
551      POP_XMM6_XMM7
552                  ret                  ret
553    
554  align 16  .qes2_q1_routine:
555  .qes2_q1loop    xor TMP0, TMP0
556                  movdqa  xmm0, [esi + ecx*8]                     ; xmm0 = [1st]    mov _EAX, prm2      ; data
557                  movdqa  xmm3, [esi + ecx*8 + 16]        ; xmm3 = [2nd]  
558    ALIGN SECTION_ALIGN
559    .qes2_q1loop:
560      movdqa xmm0, [_EAX + TMP0*8]        ; xmm0 = [1st]
561      movdqa xmm3, [_EAX + TMP0*8 + 16]   ; xmm3 = [2nd]
562                  pxor    xmm1, xmm1                  pxor    xmm1, xmm1
563                  pxor    xmm4, xmm4                  pxor    xmm4, xmm4
564                  pcmpgtw xmm1, xmm0                  pcmpgtw xmm1, xmm0
# Line 694  Line 577 
577                  pxor    xmm3, xmm4                  pxor    xmm3, xmm4
578                  psubw   xmm0, xmm1                  psubw   xmm0, xmm1
579                  psubw   xmm3, xmm4                  psubw   xmm3, xmm4
580                  movdqa  [edi + ecx*8], xmm0    movdqa [TMP1 + TMP0*8], xmm0
581                  movdqa  [edi + ecx*8 + 16], xmm3    movdqa [TMP1 + TMP0*8 + 16], xmm3
582    
583                  add             ecx,4    add TMP0, 4
584                  cmp             ecx,16    cmp TMP0, 16
585                  jnz             .qes2_q1loop                  jnz             .qes2_q1loop
586                  jmp             .qes2_done                  jmp             .qes2_done
587    ENDFUNC
588    
589    
590  ;===========================================================================  ;-----------------------------------------------------------------------------
591  ;  ;
592  ; void dequant_intra_mmx(int16_t *data,  ; uint32_t dequant_h263_intra_mmx(int16_t *data,
593  ;                                       const int16_t const *coeff,  ;                                       const int16_t const *coeff,
594  ;                                       const uint32_t quant,  ;                                       const uint32_t quant,
595  ;                                       const uint32_t dcscalar);  ;                                 const uint32_t dcscalar,
596    ;                                 const uint16_t *mpeg_matrices);
597  ;  ;
598  ;===========================================================================  ;-----------------------------------------------------------------------------
   
   ; note: we only saturate to +2047 *before* restoring the sign.  
   ; Hence, final clamp really is [-2048,2047]  
599    
600  align ALIGN  ALIGN SECTION_ALIGN
 cglobal dequant_h263_intra_mmx  
601  dequant_h263_intra_mmx:  dequant_h263_intra_mmx:
602    
603    mov    edx, [esp+ 4]        ; data    mov TMP0, prm3                 ; quant
604    mov    ecx, [esp+ 8]        ; coeff    mov _EAX, prm2                 ; coeff
605    mov    eax, [esp+12]        ; quant    pcmpeqw mm0,mm0
606    movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1    lea TMP1, [mmx_quant]
607    movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant    movq mm6, [TMP1 + TMP0*8] ; quant
608    mov eax, -16    shl TMP0,31                    ; quant & 1 ? 0 : - 1
609      movq mm7,mm6
610  align ALIGN    movq mm5,mm0
611  .loop    movd mm1,TMP0d
612    movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]    mov TMP1, prm1                 ; data
613    movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]    psllw mm0,mm1
614    pxor mm1, mm1    paddw mm7,mm7                  ; 2*quant
615      paddw mm6,mm0                  ; quant-1
616      psllw mm5,12
617      mov TMP0,8
618      psrlw mm5,1
619    
620    .loop:
621      movq mm0,[_EAX]
622      pxor mm2,mm2
623    pxor mm4, mm4    pxor mm4, mm4
624    pcmpgtw mm1, mm0  ; sign(c)    pcmpgtw mm2,mm0
625    pcmpgtw mm4, mm3  ; sign(c')    pcmpeqw mm4,mm0
626      pmullw mm0,mm7      ; * 2 * quant
627      movq mm1,[_EAX+8]
628      psubw mm0,mm2
629      pxor mm2,mm6
630      pxor mm3,mm3
631      pandn mm4,mm2
632    pxor mm2, mm2    pxor mm2, mm2
633    pxor mm5, mm5    pcmpgtw mm3,mm1
634    pcmpeqw mm2, mm0  ; c is zero    pcmpeqw mm2,mm1
635    pcmpeqw mm5, mm3  ; c' is zero    pmullw mm1,mm7
636    pandn mm2, mm6    ; offset = isZero ? 0 : quant_add    paddw mm0,mm4
637    pandn mm5, mm6    psubw mm1,mm3
638    pxor mm0, mm1     ; negate if negative    pxor mm3,mm6
639    pxor mm3, mm4     ; negate if negative    pandn mm2,mm3
640    psubw mm0, mm1    paddsw mm0, mm5        ; saturate
641    psubw mm3, mm4    paddw mm1,mm2
642    pmullw mm0, mm7 ; *= 2Q  
643    pmullw mm3, mm7 ; *= 2Q    paddsw mm1, mm5
644    paddw mm0, mm2 ; + offset    psubsw mm0, mm5
645    paddw mm3, mm5 ; + offset    psubsw mm1, mm5
646    paddw mm0, mm1 ; negate back    psubsw mm0, mm5
647    paddw mm3, mm4 ; negate back    psubsw mm1, mm5
648      paddsw mm0, mm5
649      ; saturates to +2047    paddsw mm1, mm5
650    movq mm2, [mmx_32767_minus_2047]  
651    add eax, 2    movq [TMP1],mm0
652    paddsw mm0, mm2    lea _EAX,[_EAX+16]
653    paddsw mm3, mm2    movq [TMP1+8],mm1
654    psubsw mm0, mm2  
655    psubsw mm3, mm2    dec TMP0
656      lea TMP1,[TMP1+16]
657    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  
658    
659      ; deal with DC      ; deal with DC
660      mov _EAX, prm2               ; coeff
661    movd mm0, [ecx]    movd mm1,prm4d                ; dcscalar
662    pmullw mm0, [esp+16]    ; dcscalar    movd mm0,[_EAX]                   ; coeff[0]
663    movq mm2, [mmx_32767_minus_2047]    pmullw mm0,mm1                   ; * dcscalar
664    paddsw mm0, mm2    mov TMP1, prm1               ; data
665    psubsw mm0, mm2    paddsw mm0, mm5                  ; saturate +
666    movq mm3, [mmx_32768_minus_2048]    psubsw mm0, mm5
667    psubsw mm0, mm3    psubsw mm0, mm5                  ; saturate -
668    paddsw mm0, mm3    paddsw mm0, mm5
669    movd eax, mm0    movd eax, mm0
670    mov [edx], ax    mov [TMP1], ax
671    
672      xor _EAX, _EAX                    ; return 0
673    ret    ret
674    ENDFUNC
675    
676  ;===========================================================================  ;-----------------------------------------------------------------------------
677  ;  ;
678  ; void dequant_intra_xmm(int16_t *data,  ; uint32_t dequant_h263_intra_xmm(int16_t *data,
679  ;                                       const int16_t const *coeff,  ;                                       const int16_t const *coeff,
680  ;                                       const uint32_t quant,  ;                                       const uint32_t quant,
681  ;                                       const uint32_t dcscalar);  ;                                 const uint32_t dcscalar,
682    ;                                 const uint16_t *mpeg_matrices);
683  ;  ;
684  ;===========================================================================  ;-----------------------------------------------------------------------------
685    
   ; this is the same as dequant_inter_mmx, except that we're  
   ; saturating using 'pminsw' (saves 2 cycles/loop => ~5% faster)  
686    
687  align ALIGN  ALIGN SECTION_ALIGN
 cglobal dequant_h263_intra_xmm  
688  dequant_h263_intra_xmm:  dequant_h263_intra_xmm:
689    
690    mov    edx, [esp+ 4]        ; data    mov TMP0, prm3                 ; quant
691    mov    ecx, [esp+ 8]        ; coeff    mov _EAX, prm2                 ; coeff
692    mov    eax, [esp+12]        ; quant  
693    movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1    movd mm6,TMP0d                  ; quant
694    movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant    pcmpeqw mm0,mm0
695    mov eax, -16    pshufw mm6,mm6,0               ; all quant
696      shl TMP0,31
697  align ALIGN    movq mm5,mm0
698  .loop    movq mm7,mm6
699    movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]    movd mm1,TMP0d
700    movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]    mov TMP1, prm1                 ; data
701    pxor mm1, mm1    psllw mm0,mm1                  ; quant & 1 ? 0 : - 1
702    pxor mm4, mm4    movq mm4,mm5
703    pcmpgtw mm1, mm0  ; sign(c)    paddw mm7,mm7                  ; quant*2
704    pcmpgtw mm4, mm3  ; sign(c')    paddw mm6,mm0                  ; quant-1
705      psrlw mm4,5                    ; mm4=2047
706      mov TMP0,8
707      pxor mm5,mm4                   ; mm5=-2048
708    
709    .loop:
710      movq mm0,[_EAX]
711    pxor mm2, mm2    pxor mm2, mm2
712    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  
713    
714      ; deal with DC    pcmpgtw mm2,mm0
715      pcmpeqw mm3,mm0     ; if coeff==0...
716      pmullw mm0,mm7      ; * 2 * quant
717      movq mm1,[_EAX+8]
718    
719      psubw mm0,mm2
720      pxor mm2,mm6
721      pandn mm3,mm2       ; ...then data=0
722      pxor mm2,mm2
723      paddw mm0,mm3
724      pxor mm3,mm3
725      pcmpeqw mm2,mm1
726      pcmpgtw mm3,mm1
727      pmullw mm1,mm7
728    
729      pminsw mm0,mm4
730      psubw mm1,mm3
731      pxor mm3,mm6
732      pandn mm2,mm3
733      paddw mm1,mm2
734    
735      pmaxsw mm0,mm5
736      pminsw mm1,mm4
737      movq [TMP1],mm0
738      pmaxsw mm1,mm5
739      lea _EAX,[_EAX+16]
740      movq [TMP1+8],mm1
741    
742      dec TMP0
743      lea TMP1,[TMP1+16]
744      jne .loop
745    
746    movd mm0, [ecx]     ; deal with DC
747    pmullw mm0, [esp+16]    ; dcscalar    mov _EAX, prm2                ; coeff
748    movq mm2, [mmx_32767_minus_2047]    movd mm1,prm4d                 ; dcscalar
749    paddsw mm0, mm2    movd mm0, [_EAX]
750    psubsw mm0, mm2    pmullw mm0, mm1
751    movq mm2, [mmx_32768_minus_2048]    mov TMP1, prm1                ; data
752    psubsw mm0, mm2    pminsw mm0,mm4
753    paddsw mm0, mm2    pmaxsw mm0,mm5
754    movd eax, mm0    movd eax, mm0
755    mov [edx], ax    mov [TMP1], ax
756    
757      xor _EAX, _EAX                ; return 0
758    ret    ret
759    ENDFUNC
760    
761    
762  ;===========================================================================  ;-----------------------------------------------------------------------------
763  ;  ;
764  ; void dequant_intra_sse2(int16_t *data,  ; uint32_t dequant_h263_intra_sse2(int16_t *data,
765  ;                                       const int16_t const *coeff,  ;                                       const int16_t const *coeff,
766  ;                                       const uint32_t quant,  ;                                       const uint32_t quant,
767  ;                                       const uint32_t dcscalar);  ;                                  const uint32_t dcscalar,
768    ;                                  const uint16_t *mpeg_matrices);
769  ;  ;
770  ;===========================================================================  ;-----------------------------------------------------------------------------
771  align ALIGN  
772  cglobal dequant_h263_intra_sse2  ALIGN SECTION_ALIGN
773  dequant_h263_intra_sse2:  dequant_h263_intra_sse2:
774          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  
775    
776  align ALIGN    mov TMP0, prm3                 ; quant
777  .loop    mov _EAX, prm2                 ; coeff
778          movdqa xmm0, [ecx + 8*16 + 8*eax]      ; c  = coeff[i]  
779          movdqa xmm3, [ecx + 8*16 + 8*eax+ 16]    movd xmm6,TMP0d                     ; quant
780          pxor xmm1, xmm1  
781          pxor xmm4, xmm4    shl TMP0,31
782          pcmpgtw xmm1, xmm0  ; sign(c)    pshuflw xmm6,xmm6,0
783          pcmpgtw xmm4, xmm3    pcmpeqw xmm0,xmm0
784      movlhps xmm6,xmm6                 ; all quant
785      movd xmm1,TMP0d
786      movdqa xmm5,xmm0
787      movdqa xmm7,xmm6
788      mov TMP1, prm1                 ; data
789      paddw xmm7,xmm7                   ; quant *2
790      psllw xmm0,xmm1                   ; quant & 1 ? 0 : - 1
791      movdqa xmm4,xmm5
792      paddw xmm6,xmm0                   ; quant-1
793      psrlw xmm4,5                      ; 2047
794      mov TMP0,4
795      pxor xmm5,xmm4                    ; mm5=-2048
796    
797    .loop:
798      movdqa xmm0,[_EAX]
799          pxor xmm2, xmm2          pxor xmm2, xmm2
800          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  
801    
802          pxor xmm0, xmm1    pcmpgtw xmm2,xmm0
803          pxor xmm3, xmm4    pcmpeqw xmm3,xmm0
804          movdqa [edx + 8*16 - 8*4 + 8*eax], xmm0    pmullw xmm0,xmm7      ; * 2 * quant
805          movdqa [edx + 8*16 - 8*4 + 8*eax + 16], xmm3    movdqa xmm1,[_EAX+16]
806          jnz     near .loop  
807      psubw xmm0,xmm2
808      pxor xmm2,xmm6
809      pandn xmm3,xmm2
810      pxor xmm2,xmm2
811      paddw xmm0,xmm3
812      pxor xmm3,xmm3
813      pcmpeqw xmm2,xmm1
814      pcmpgtw xmm3,xmm1
815      pmullw xmm1,xmm7
816    
817      pminsw xmm0,xmm4
818      psubw xmm1,xmm3
819      pxor xmm3,xmm6
820      pandn xmm2,xmm3
821      paddw xmm1,xmm2
822    
823      pmaxsw xmm0,xmm5
824      pminsw xmm1,xmm4
825      movdqa [TMP1],xmm0
826      pmaxsw xmm1,xmm5
827      lea _EAX,[_EAX+32]
828      movdqa [TMP1+16],xmm1
829    
830      dec TMP0
831      lea TMP1,[TMP1+32]
832      jne .loop
833    
834          ; 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  
835    
836          ret    mov _EAX, prm2             ; coeff
837      movsx _EAX,word [_EAX]
838      imul prm4d                 ; dcscalar
839      mov TMP1, prm1             ; data
840      movd xmm0,eax
841      pminsw xmm0,xmm4
842      pmaxsw xmm0,xmm5
843      movd eax,xmm0
844    
845      mov [TMP1], ax
846    
847      xor _EAX, _EAX                  ; return 0
848    
849      POP_XMM6_XMM7
850      ret
851    ENDFUNC
852    
853  ;===========================================================================  ;-----------------------------------------------------------------------------
854  ;  ;
855  ; void dequant_inter_mmx(int16_t * data,  ; uint32t dequant_h263_inter_mmx(int16_t * data,
856  ;                                       const int16_t * const coeff,  ;                                       const int16_t * const coeff,
857  ;                                       const uint32_t quant);  ;                                const uint32_t quant,
858    ;                                const uint16_t *mpeg_matrices);
859  ;  ;
860  ;===========================================================================  ;-----------------------------------------------------------------------------
861    
862  align ALIGN  ALIGN SECTION_ALIGN
 cglobal dequant_h263_inter_mmx  
863  dequant_h263_inter_mmx:  dequant_h263_inter_mmx:
864    
865    mov    edx, [esp+ 4]        ; data    mov TMP0, prm3                 ; quant
866    mov    ecx, [esp+ 8]        ; coeff    mov _EAX, prm2                 ; coeff
867    mov    eax, [esp+12]        ; quant    pcmpeqw mm0,mm0
868    movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1    lea TMP1, [mmx_quant]
869    movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant    movq mm6, [TMP1 + TMP0*8]      ; quant
870    mov eax, -16    shl TMP0,31                    ; odd/even
871      movq mm7,mm6
872  align ALIGN    movd mm1,TMP0d
873  .loop    mov TMP1, prm1                 ; data
874    movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]    movq mm5,mm0
875    movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]    psllw mm0,mm1                  ; quant & 1 ? 0 : - 1
876    pxor mm1, mm1    paddw mm7,mm7                  ; quant*2
877      paddw mm6,mm0                  ; quant & 1 ? quant : quant - 1
878      psllw mm5,12
879      mov TMP0,8
880      psrlw mm5,1                    ; 32767-2047 (32768-2048)
881    
882    .loop:
883      movq mm0,[_EAX]
884    pxor mm4, mm4    pxor mm4, mm4
   pcmpgtw mm1, mm0  ; sign(c)  
   pcmpgtw mm4, mm3  ; sign(c')  
885    pxor mm2, mm2    pxor mm2, mm2
886    pxor mm5, mm5    pcmpeqw mm4,mm0     ; if coeff==0...
887    pcmpeqw mm2, mm0  ; c is zero    pcmpgtw mm2,mm0
888    pcmpeqw mm5, mm3  ; c' is zero    pmullw mm0,mm7      ; * 2 * quant
889    pandn mm2, mm6    ; offset = isZero ? 0 : quant_add    pxor mm3,mm3
890    pandn mm5, mm6    psubw mm0,mm2
891    pxor mm0, mm1     ; negate if negative    movq mm1,[_EAX+8]
892    pxor mm3, mm4     ; negate if negative    pxor mm2,mm6
893    psubw mm0, mm1    pcmpgtw mm3,mm1
894    psubw mm3, mm4    pandn mm4,mm2      ; ... then data==0
895    pmullw mm0, mm7 ; *= 2Q    pmullw mm1,mm7
896    pmullw mm3, mm7 ; *= 2Q    pxor mm2,mm2
897    paddw mm0, mm2 ; + offset    pcmpeqw mm2,mm1
898    paddw mm3, mm5 ; + offset    psubw mm1,mm3
899    paddw mm0, mm1 ; negate back    pxor mm3,mm6
900    paddw mm3, mm4 ; negate back    pandn mm2,mm3
901      paddw mm0,mm4
902      ; saturates to +2047    paddw mm1,mm2
903    movq mm2, [mmx_32767_minus_2047]  
904    add eax, 2    paddsw mm0, mm5        ; saturate
905    paddsw mm0, mm2    paddsw mm1, mm5
906    paddsw mm3, mm2    psubsw mm0, mm5
907    psubsw mm0, mm2    psubsw mm1, mm5
908    psubsw mm3, mm2    psubsw mm0, mm5
909      psubsw mm1, mm5
910    pxor mm0, mm1    paddsw mm0, mm5
911    pxor mm3, mm4    paddsw mm1, mm5
912    movq [edx + 8*eax + 8*16   - 2*8], mm0  
913    movq [edx + 8*eax + 8*16+8 - 2*8], mm3    movq [TMP1],mm0
914    jnz   near .loop    lea _EAX,[_EAX+16]
915      movq [TMP1+8],mm1
916    
917      dec TMP0
918      lea TMP1,[TMP1+16]
919      jne .loop
920    
921      xor _EAX, _EAX              ; return 0
922    ret    ret
923    ENDFUNC
924    
925    
926  ;===========================================================================  ;-----------------------------------------------------------------------------
927  ;  ;
928  ; void dequant_inter_xmm(int16_t * data,  ; uint32_t dequant_h263_inter_xmm(int16_t * data,
929  ;                                       const int16_t * const coeff,  ;                                       const int16_t * const coeff,
930  ;                                       const uint32_t quant);  ;                                 const uint32_t quant,
931    ;                                 const uint16_t *mpeg_matrices);
932  ;  ;
933  ;===========================================================================  ;-----------------------------------------------------------------------------
934    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  
935  dequant_h263_inter_xmm:  dequant_h263_inter_xmm:
936    
937    mov    edx, [esp+ 4]        ; data    mov TMP0, prm3                 ; quant
938    mov    ecx, [esp+ 8]        ; coeff    mov _EAX, prm2                 ; coeff
939    mov    eax, [esp+12]        ; quant    pcmpeqw mm0,mm0
940    movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1    lea TMP1, [mmx_quant]
941    movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant    movq mm6, [TMP1 + TMP0*8]      ; quant
942    mov eax, -16    shl TMP0,31
943      movq mm5,mm0
944  align ALIGN    movd mm1,TMP0d
945  .loop    movq mm7,mm6
946    movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]    psllw mm0,mm1
947    movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]    mov TMP1, prm1                 ; data
948    pxor mm1, mm1    movq mm4,mm5
949    pxor mm4, mm4    paddw mm7,mm7
950    pcmpgtw mm1, mm0  ; sign(c)    paddw mm6,mm0                     ; quant-1
951    pcmpgtw mm4, mm3  ; sign(c')  
952      psrlw mm4,5
953      mov TMP0,8
954      pxor mm5,mm4                      ; mm5=-2048
955    
956    .loop:
957      movq mm0,[_EAX]
958      pxor mm3,mm3
959    pxor mm2, mm2    pxor mm2, mm2
960    pxor mm5, mm5    pcmpeqw mm3,mm0
961    pcmpeqw mm2, mm0  ; c is zero    pcmpgtw mm2,mm0
962    pcmpeqw mm5, mm3  ; c' is zero    pmullw mm0,mm7                    ; * 2 * quant
963    pandn mm2, mm6    ; offset = isZero ? 0 : quant_add    pandn mm3,mm6
964    pandn mm5, mm6    movq mm1,[_EAX+8]
965    pxor mm0, mm1     ; negate if negative    psubw mm0,mm2
966    pxor mm3, mm4     ; negate if negative    pxor mm2,mm3
967    psubw mm0, mm1    pxor mm3,mm3
968    psubw mm3, mm4    paddw mm0,mm2
969    pmullw mm0, mm7 ; *= 2Q    pxor mm2,mm2
970    pmullw mm3, mm7 ; *= 2Q    pcmpgtw mm3,mm1
971    paddw mm0, mm2 ; + offset    pcmpeqw mm2,mm1
972    paddw mm3, mm5 ; + offset    pmullw mm1,mm7
973    paddw mm0, mm1 ; start restoring sign    pandn mm2,mm6
974    paddw mm3, mm4 ; start restoring sign    psubw mm1,mm3
975      pxor mm3,mm2
976        ; saturates to +2047    paddw mm1,mm3
977    movq mm2, [mmx_2047]  
978    pminsw mm0, mm2    pminsw mm0,mm4
979    add eax, 2    pminsw mm1,mm4
980    pminsw mm3, mm2    pmaxsw mm0,mm5
981      pmaxsw mm1,mm5
982    pxor mm0, mm1 ; finish restoring sign  
983    pxor mm3, mm4 ; finish restoring sign    movq [TMP1],mm0
984    movq [edx + 8*eax + 8*16   - 2*8], mm0    lea _EAX,[_EAX+16]
985    movq [edx + 8*eax + 8*16+8 - 2*8], mm3    movq [TMP1+8],mm1
986    jnz   near .loop  
987      dec TMP0
988      lea TMP1,[TMP1+16]
989      jne .loop
990    
991      xor _EAX, _EAX              ; return 0
992    ret    ret
993    ENDFUNC
994    
995    
996  ;===========================================================================  ;-----------------------------------------------------------------------------
997  ;  ;
998  ; void dequant_inter_sse2(int16_t * data,  ; uint32_t dequant_h263_inter_sse2(int16_t * data,
999  ;                                       const int16_t * const coeff,  ;                                       const int16_t * const coeff,
1000  ;                                       const uint32_t quant);  ;                                  const uint32_t quant,
1001    ;                                  const uint16_t *mpeg_matrices);
1002  ;  ;
1003  ;===========================================================================  ;-----------------------------------------------------------------------------
1004  align ALIGN  
1005  cglobal dequant_h263_inter_sse2  ALIGN SECTION_ALIGN
1006  dequant_h263_inter_sse2:  dequant_h263_inter_sse2:
1007          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  
1008    
1009  align ALIGN    mov TMP0, prm3                 ; quant
1010  .loop    mov _EAX, prm2                 ; coeff
         movdqa xmm0, [ecx + 8*16 + 8*eax]  ; c  = coeff[i]  
         movdqa xmm3, [ecx + 8*16 + 8*eax + 16]  
1011    
1012          pxor xmm1, xmm1    lea TMP1, [mmx_quant]
1013          pxor xmm4, xmm4    movq xmm6, [TMP1 + TMP0*8]    ; quant
1014          pcmpgtw xmm1, xmm0  ; sign(c)    inc TMP0
1015          pcmpgtw xmm4, xmm3    pcmpeqw xmm5,xmm5
1016      and TMP0,1
1017      movlhps xmm6,xmm6
1018      movd xmm0,TMP0d
1019      movdqa xmm7,xmm6
1020      pshuflw xmm0,xmm0,0
1021      movdqa xmm4,xmm5
1022      mov TMP1, prm1                 ; data
1023      movlhps xmm0,xmm0
1024      paddw xmm7,xmm7
1025      psubw xmm6,xmm0
1026      psrlw xmm4,5   ; 2047
1027      mov TMP0,4
1028      pxor xmm5,xmm4 ; mm5=-2048
1029    
1030    .loop:
1031      movdqa xmm0,[_EAX]
1032      pxor xmm3,xmm3
1033          pxor xmm2, xmm2          pxor xmm2, xmm2
1034          pxor xmm5, xmm5    pcmpeqw xmm3,xmm0
1035          pcmpeqw xmm2, xmm0  ; c is zero    pcmpgtw xmm2,xmm0
1036          pcmpeqw xmm5, xmm3    pmullw xmm0,xmm7      ; * 2 * quant
1037      pandn xmm3,xmm6
1038      movdqa xmm1,[_EAX+16]
1039      psubw xmm0,xmm2
1040      pxor xmm2,xmm3
1041      pxor xmm3,xmm3
1042      paddw xmm0,xmm2
1043      pxor xmm2,xmm2
1044      pcmpgtw xmm3,xmm1
1045      pcmpeqw xmm2,xmm1
1046      pmullw xmm1,xmm7
1047          pandn xmm2, xmm6          pandn xmm2, xmm6
1048          pandn xmm5, xmm6    psubw xmm1,xmm3
1049          pxor xmm0, xmm1  ; negate if negative    pxor xmm3,xmm2
1050          pxor xmm3, xmm4    paddw xmm1,xmm3
1051          psubw xmm0, xmm1  
1052          psubw xmm3, xmm4    pminsw xmm0,xmm4
1053          pmullw xmm0, xmm7  ; *= 2Q    pminsw xmm1,xmm4
1054          pmullw xmm3, xmm7    pmaxsw xmm0,xmm5
1055          paddw xmm0, xmm2  ; + offset    pmaxsw xmm1,xmm5
1056          paddw xmm3, xmm5  
1057      movdqa [TMP1],xmm0
1058          paddw xmm0, xmm1  ; start restoring sign    lea _EAX,[_EAX+32]
1059          paddw xmm3, xmm4    movdqa [TMP1+16],xmm1
1060    
1061          ; saturates to +2047    dec TMP0
1062          movdqa xmm2, [sse2_2047]    lea TMP1,[TMP1+32]
1063          pminsw xmm0, xmm2    jne .loop
         add eax, 4  
         pminsw xmm3, xmm2  
1064    
1065          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  
1066    
1067      POP_XMM6_XMM7
1068          ret          ret
1069    ENDFUNC
1070    
1071    
1072    %ifidn __OUTPUT_FORMAT__,elf
1073    section ".note.GNU-stack" noalloc noexec nowrite progbits
1074    %endif
1075    

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

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