[svn] / branches / release-1_2-branch / xvidcore / src / quant / x86_asm / quantize_h263_mmx.asm Repository:
ViewVC logotype

Diff of /branches/release-1_2-branch/xvidcore/src/quant/x86_asm/quantize_h263_mmx.asm

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

trunk/xvidcore/src/quant/x86_asm/quantize_h263_mmx.asm revision 1382, Mon Mar 22 22:36:25 2004 UTC branches/release-1_2-branch/xvidcore/src/quant/x86_asm/quantize_h263_mmx.asm revision 1820, Fri Nov 28 16:54:45 2008 UTC
# Line 5  Line 5 
5  ; *  ; *
6  ; *  Copyright(C) 2001-2003 Peter Ross <pross@xvid.org>  ; *  Copyright(C) 2001-2003 Peter Ross <pross@xvid.org>
7  ; *               2002-2003 Pascal Massimino <skal@planet-d.net>  ; *               2002-2003 Pascal Massimino <skal@planet-d.net>
8    ; *               2004      Jean-Marc Bastide <jmtest@voila.fr>
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 20  Line 21 
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA  ; *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23  ; *  ; *
24  ; * $Id: quantize_h263_mmx.asm,v 1.2 2004-03-22 22:36:24 edgomez Exp $  ; * $Id: quantize_h263_mmx.asm,v 1.11 2008-11-26 23:35:50 Isibaar Exp $
25  ; *  ; *
26  ; ****************************************************************************/  ; ****************************************************************************/
27    
28  ; enable dequant saturate [-2048,2047], test purposes only.  ; enable dequant saturate [-2048,2047], test purposes only.
29  %define SATURATE  %define SATURATE
30    
31  BITS 32  %include "nasm.inc"
   
 %macro cglobal 1  
        %ifdef PREFIX  
                 global _%1  
                 %define %1 _%1  
         %else  
                 global %1  
         %endif  
 %endmacro  
32    
33  ;=============================================================================  ;=============================================================================
34  ; Read only Local data  ; Read only Local data
35  ;=============================================================================  ;=============================================================================
36    
37  %ifdef FORMAT_COFF  DATA
 SECTION .rodata data  
 %else  
 SECTION .rodata data align=16  
 %endif  
38    
39  ALIGN 16  ALIGN SECTION_ALIGN
40  plus_one:  plus_one:
41          times 8 dw 1          times 8 dw 1
42    
43  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
44  ;  ;
45    ; quant table
46    ;
47    ;-----------------------------------------------------------------------------
48    
49    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  ALIGN 16  ALIGN SECTION_ALIGN
64  mmx_sub:  mmx_sub:
65  %assign quant 1  %assign quant 1
66  %rep 31  %rep 31
# Line 76  Line 78 
78  ;  ;
79  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
80    
81  ALIGN 16  ALIGN SECTION_ALIGN
82  mmx_div:  mmx_div:
83  %assign quant 1  %assign quant 1
84  %rep 31  %rep 31
# Line 84  Line 86 
86          %assign quant quant+1          %assign quant quant+1
87  %endrep  %endrep
88    
 ;-----------------------------------------------------------------------------  
 ;  
 ; add by (odd(Q) ? Q : Q - 1) table  
 ;  
 ;-----------------------------------------------------------------------------  
   
 ALIGN 16  
 mmx_add:  
 %assign quant 1  
 %rep 31  
         %if quant % 2 != 0  
         times 4 dw  quant  
         %else  
         times 4 dw quant - 1  
         %endif  
         %assign quant quant+1  
 %endrep  
   
 ;-----------------------------------------------------------------------------  
 ;  
 ; multiple by 2Q table  
 ;  
 ;-----------------------------------------------------------------------------  
   
 ALIGN 16  
 mmx_mul:  
 %assign quant 1  
 %rep 31  
         times 4 dw  quant*2  
         %assign quant quant+1  
 %endrep  
   
 ;-----------------------------------------------------------------------------  
 ;  
 ; 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)  
   
   
89  ;=============================================================================  ;=============================================================================
90  ; Code  ; Code
91  ;=============================================================================  ;=============================================================================
92    
93  SECTION .text  SECTION .rotext align=SECTION_ALIGN
94    
95  cglobal quant_h263_intra_mmx  cglobal quant_h263_intra_mmx
96  cglobal quant_h263_intra_sse2  cglobal quant_h263_intra_sse2
# Line 165  Line 113 
113  ;  ;
114  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
115    
116  ALIGN 16  ALIGN SECTION_ALIGN
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      movq mm7, [TMP1+TMP0 * 8 - 8]
133  ALIGN 16  %ifdef ARCH_IS_X86_64
134  .loop  %ifdef WINDOWS
135    movq mm0, [esi + 8*ecx]           ; mm0 = [1st]    mov TMP1, prm2
136    movq mm3, [esi + 8*ecx + 8]  %endif
137    pxor mm1, mm1                     ; mm1 = 0  %endif
138    pxor mm4, mm4                     ;    cdq
139    pcmpgtw mm1, mm0                  ; mm1 = (0 > mm0)    idiv prm4d         ; dcscalar
140    pcmpgtw mm4, mm3                  ;  %ifdef ARCH_IS_X86_64
141    pxor mm0, mm1                     ; mm0 = |mm0|  %ifdef WINDOWS
142    pxor mm3, mm4                     ;    mov prm2, TMP1
143    psubw mm0, mm1                    ; displace  %endif
144    psubw mm3, mm4                    ;  %endif
145    pmulhw mm0, mm7                   ; mm0 = (mm0 / 2Q) >> 16    cmp TMP0, 1
146    pmulhw mm3, mm7                   ;    mov TMP1, prm1     ; coeff
147    pxor mm0, mm1                     ; mm0 *= sign(mm0)    je .low
148    pxor mm3, mm4                     ;  
149    psubw mm0, mm1                    ; undisplace    mov TMP0, prm2     ; data
150    psubw mm3, mm4                    ;    push _EAX          ; DC
151    movq [edi + 8*ecx], mm0    mov _EAX, TMP0
   movq [edi + 8*ecx + 8], mm3  
   
   add ecx, 2  
   cmp ecx, 16  
   jnz .loop  
152    
153  .done    mov TMP0,4
154    
155      ; caclulate  data[0] // (int32_t)dcscalar)  .loop:
156    mov ecx, [esp + 12 + 16]      ; dcscalar    movq mm0, [_EAX]           ; data
157    mov edx, ecx    pxor mm4,mm4
158    movsx eax, word [esi]         ; data[0]    movq mm1, [_EAX + 8]
159    shr edx, 1                    ; edx = dcscalar /2    pcmpgtw mm4,mm0           ; (data<0)
160    cmp eax, 0    pxor mm5,mm5
161    jg .gtzero    pmulhw mm0,mm7            ; /(2*quant)
162      pcmpgtw mm5,mm1
163    sub eax, edx    movq mm2, [_EAX+16]
164    jmp short .mul    psubw mm0,mm4             ;  +(data<0)
165      pmulhw mm1,mm7
166  .gtzero    pxor mm4,mm4
167    add eax, edx    movq mm3,[_EAX+24]
168  .mul    pcmpgtw mm4,mm2
169    cdq ; expand eax -> edx:eax    psubw mm1,mm5
170    idiv ecx          ; eax = edx:eax / dcscalar    pmulhw mm2,mm7
171    mov [edi], ax     ; coeff[0] = ax    pxor mm5,mm5
172      pcmpgtw mm5,mm3
173    xor eax, eax      ; return(0);    pmulhw mm3,mm7
174    pop edi    psubw mm2,mm4
175    pop esi    psubw mm3,mm5
176    pop ecx    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 16  
 .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  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
# Line 272  Line 245 
245  ;  ;
246  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
247    
248  ALIGN 16  ALIGN SECTION_ALIGN
249  quant_h263_intra_sse2:  quant_h263_intra_sse2:
250    
251    push esi    mov _EAX, prm2     ; data
   push edi  
252    
253    mov edi, [esp + 8 + 4]                ; coeff    movsx _EAX, word [_EAX]      ; data[0]
   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    .loop_low:
329  .qas2_gtzero    movdqa xmm0, [_EAX]
   add eax, edx  
   
 .qas2_mul  
   cdq  
   idiv ecx  
   
   mov [edi], ax  
   
   xor eax, eax      ; return(0);  
   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    
367      ret
368    ENDFUNC
369    
370  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
371  ;  ;
# Line 379  Line 376 
376  ;  ;
377  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
378    
379  ALIGN 16  ALIGN SECTION_ALIGN
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 8    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 422  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
432    
433    movd eax, mm0     ; return sum    movd eax, mm0     ; return sum
   pop edi  
   pop esi  
   pop ecx  
434    
435    ret    ret
436    
437  ALIGN 8  .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 464  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    
# Line 484  Line 481 
481  ;  ;
482  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
483    
484  ALIGN 16  ALIGN SECTION_ALIGN
485  quant_h263_inter_sse2:  quant_h263_inter_sse2:
486    
487    push esi    mov TMP1, prm1      ; coeff
488    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  
489    
490    pxor xmm5, xmm5                           ; sum    pxor xmm5, xmm5                           ; sum
491    
492    movq mm0, [mmx_sub + eax*8 - 8]           ; sub    lea TMP0, [mmx_sub]
493      movq mm0, [TMP0 + _EAX*8 - 8]             ; sub
494    movq2dq xmm6, mm0                         ; load into low 8 bytes    movq2dq xmm6, mm0                         ; load into low 8 bytes
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 mm0, [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  
507    movq2dq xmm7, mm0    movq2dq xmm7, mm0
508    movlhps xmm7, xmm7    movlhps xmm7, xmm7
509    
510  ALIGN 16  ALIGN SECTION_ALIGN
511  .qes2_loop  .qes2_loop:
512    movdqa xmm0, [esi + ecx*8]                ; xmm0 = [1st]    movdqa xmm0, [_EAX + TMP0*8]               ; xmm0 = [1st]
513    movdqa xmm3, [esi + ecx*8 + 16]           ; xmm3 = [2nd]    movdqa xmm3, [_EAX + TMP0*8 + 16]          ; xmm3 = [2nd]
514    pxor xmm1, xmm1    pxor xmm1, xmm1
515    pxor xmm4, xmm4    pxor xmm4, xmm4
516    pcmpgtw xmm1, xmm0    pcmpgtw xmm1, xmm0
# Line 532  Line 529 
529    pxor xmm3, xmm4    pxor xmm3, xmm4
530    psubw xmm0, xmm1    psubw xmm0, xmm1
531    psubw xmm3, xmm4    psubw xmm3, xmm4
532    movdqa [edi + ecx*8], xmm0    movdqa [TMP1 + TMP0*8], xmm0
533    movdqa [edi + ecx*8 + 16], xmm3    movdqa [TMP1 + TMP0*8 + 16], xmm3
534    
535    add ecx, 4    add TMP0, 4
536    cmp ecx, 16    cmp TMP0, 16
537    jnz .qes2_loop    jnz .qes2_loop
538    
539  .qes2_done  .qes2_done:
540    movdqu xmm6, [plus_one]    movdqu xmm6, [plus_one]
541    pmaddwd xmm5, xmm6    pmaddwd xmm5, xmm6
542    movhlps xmm6, xmm5    movhlps xmm6, xmm5
# Line 552  Line 549 
549    
550    movd eax, mm0         ; return sum    movd eax, mm0         ; return sum
551    
   pop edi  
   pop esi  
   
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 579  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  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
# Line 598  Line 597 
597  ;  ;
598  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
599    
600    ; note: we only saturate to +2047 *before* restoring the sign.  ALIGN SECTION_ALIGN
   ; Hence, final clamp really is [-2048,2047]  
   
 ALIGN 16  
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 16    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    movd mm0, [ecx]    mov _EAX, prm2               ; coeff
661    pmullw mm0, [esp+16]          ; dcscalar    movd mm1,prm4d                ; dcscalar
662    movq mm2, [mmx_32767_minus_2047]    movd mm0,[_EAX]                   ; coeff[0]
663    paddsw mm0, mm2    pmullw mm0,mm1                   ; * dcscalar
664    psubsw mm0, mm2    mov TMP1, prm1               ; data
665    movq mm3, [mmx_32768_minus_2048]    paddsw mm0, mm5                  ; saturate +
666    psubsw mm0, mm3    psubsw mm0, mm5
667    paddsw mm0, mm3    psubsw mm0, mm5                  ; saturate -
668      paddsw mm0, mm5
669    movd eax, mm0    movd eax, mm0
670    mov [edx], ax    mov [TMP1], ax
671    
672    xor eax, eax              ; return(0);    xor _EAX, _EAX                    ; return 0
673    ret    ret
674    ENDFUNC
675    
676  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
677  ;  ;
# Line 675  Line 683 
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 16  ALIGN SECTION_ALIGN
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 16    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
713    pcmpeqw mm2, mm0                  ; c is zero  
714    pcmpeqw mm5, mm3                  ; c' is zero    pcmpgtw mm2,mm0
715    pandn mm2, mm6                    ; offset = isZero ? 0 : quant_add    pcmpeqw mm3,mm0     ; if coeff==0...
716    pandn mm5, mm6    pmullw mm0,mm7      ; * 2 * quant
717    pxor mm0, mm1                     ; negate if negative    movq mm1,[_EAX+8]
718    pxor mm3, mm4                     ; negate if negative  
719    psubw mm0, mm1    psubw mm0,mm2
720    psubw mm3, mm4    pxor mm2,mm6
721    pmullw mm0, mm7                   ; *= 2Q    pandn mm3,mm2       ; ...then data=0
722    pmullw mm3, mm7                   ; *= 2Q    pxor mm2,mm2
723    paddw mm0, mm2                    ; + offset    paddw mm0,mm3
724    paddw mm3, mm5                    ; + offset    pxor mm3,mm3
725    paddw mm0, mm1                    ; negate back    pcmpeqw mm2,mm1
726    paddw mm3, mm4                    ; negate back    pcmpgtw mm3,mm1
727      pmullw mm1,mm7
728     ; saturates to +2047  
729    movq mm2, [mmx_2047]    pminsw mm0,mm4
730    pminsw mm0, mm2    psubw mm1,mm3
731    add eax, 2    pxor mm3,mm6
732    pminsw mm3, mm2    pandn mm2,mm3
733      paddw mm1,mm2
734    pxor mm0, mm1  
735    pxor mm3, mm4    pmaxsw mm0,mm5
736    movq [edx + 8*eax + 8*16   - 2*8], mm0    pminsw mm1,mm4
737    movq [edx + 8*eax + 8*16+8 - 2*8], mm3    movq [TMP1],mm0
738    jnz near .loop    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      ; deal with DC      ; deal with DC
747    movd mm0, [ecx]    mov _EAX, prm2                ; coeff
748    pmullw mm0, [esp+16]    ; dcscalar    movd mm1,prm4d                 ; dcscalar
749    movq mm2, [mmx_32767_minus_2047]    movd mm0, [_EAX]
750    paddsw mm0, mm2    pmullw mm0, mm1
751    psubsw mm0, mm2    mov TMP1, prm1                ; data
752    movq mm2, [mmx_32768_minus_2048]    pminsw mm0,mm4
753    psubsw mm0, mm2    pmaxsw mm0,mm5
   paddsw mm0, mm2  
754    movd eax, mm0    movd eax, mm0
755    mov [edx], ax    mov [TMP1], ax
756    
757    xor eax, eax    xor _EAX, _EAX                ; return 0
758    ret    ret
759    ENDFUNC
760    
761    
762  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
# Line 751  Line 769 
769  ;  ;
770  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
771    
772  ALIGN 16  ALIGN SECTION_ALIGN
773  dequant_h263_intra_sse2:  dequant_h263_intra_sse2:
   mov edx, [esp+ 4]        ; data  
   mov ecx, [esp+ 8]        ; coeff  
   mov eax, [esp+12]        ; quant  
   movq mm6, [mmx_add + eax * 8 - 8]  
   movq mm7, [mmx_mul + eax * 8 - 8]  
   movq2dq xmm6, mm6  
   movq2dq xmm7, mm7  
   movlhps xmm6, xmm6  
   movlhps xmm7, xmm7  
   mov eax, -16  
774    
775  ALIGN 16    mov TMP0, prm3                 ; quant
776  .loop    mov _EAX, prm2                 ; coeff
777    movdqa xmm0, [ecx + 8*16 + 8*eax]      ; c  = coeff[i]  
778    movdqa xmm3, [ecx + 8*16 + 8*eax+ 16]    movd xmm6,TMP0d                     ; quant
779    pxor xmm1, xmm1  
780    pxor xmm4, xmm4    shl TMP0,31
781    pcmpgtw xmm1, xmm0    ; sign(c)    pshuflw xmm6,xmm6,0
782    pcmpgtw xmm4, xmm3    pcmpeqw xmm0,xmm0
783      movlhps xmm6,xmm6                 ; all quant
784      movd xmm1,TMP0d
785      movdqa xmm5,xmm0
786      movdqa xmm7,xmm6
787      mov TMP1, prm1                 ; data
788      paddw xmm7,xmm7                   ; quant *2
789      psllw xmm0,xmm1                   ; quant & 1 ? 0 : - 1
790      movdqa xmm4,xmm5
791      paddw xmm6,xmm0                   ; quant-1
792      psrlw xmm4,5                      ; 2047
793      mov TMP0,4
794      pxor xmm5,xmm4                    ; mm5=-2048
795    
796    .loop:
797      movdqa xmm0,[_EAX]
798    pxor xmm2, xmm2    pxor xmm2, xmm2
799    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  
800    
801    pxor xmm0, xmm1    pcmpgtw xmm2,xmm0
802    pxor xmm3, xmm4    pcmpeqw xmm3,xmm0
803    movdqa [edx + 8*16 - 8*4 + 8*eax], xmm0    pmullw xmm0,xmm7      ; * 2 * quant
804    movdqa [edx + 8*16 - 8*4 + 8*eax + 16], xmm3    movdqa xmm1,[_EAX+16]
805    jnz near .loop  
806      psubw xmm0,xmm2
807      pxor xmm2,xmm6
808      pandn xmm3,xmm2
809      pxor xmm2,xmm2
810      paddw xmm0,xmm3
811      pxor xmm3,xmm3
812      pcmpeqw xmm2,xmm1
813      pcmpgtw xmm3,xmm1
814      pmullw xmm1,xmm7
815    
816      pminsw xmm0,xmm4
817      psubw xmm1,xmm3
818      pxor xmm3,xmm6
819      pandn xmm2,xmm3
820      paddw xmm1,xmm2
821    
822      pmaxsw xmm0,xmm5
823      pminsw xmm1,xmm4
824      movdqa [TMP1],xmm0
825      pmaxsw xmm1,xmm5
826      lea _EAX,[_EAX+32]
827      movdqa [TMP1+16],xmm1
828    
829      dec TMP0
830      lea TMP1,[TMP1+32]
831      jne .loop
832    
833   ; 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  
834    
835    xor eax, eax    mov _EAX, prm2             ; coeff
836      movsx _EAX,word [_EAX]
837      imul prm4d                 ; dcscalar
838      mov TMP1, prm1             ; data
839      movd xmm0,eax
840      pminsw xmm0,xmm4
841      pmaxsw xmm0,xmm5
842      movd eax,xmm0
843    
844      mov [TMP1], ax
845    
846      xor _EAX, _EAX                  ; return 0
847    ret    ret
848    ENDFUNC
849    
850  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
851  ;  ;
# Line 825  Line 856 
856  ;  ;
857  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
858    
859  ALIGN 16  ALIGN SECTION_ALIGN
860  dequant_h263_inter_mmx:  dequant_h263_inter_mmx:
861    
862    mov edx, [esp+ 4]        ; data    mov TMP0, prm3                 ; quant
863    mov ecx, [esp+ 8]        ; coeff    mov _EAX, prm2                 ; coeff
864    mov eax, [esp+12]        ; quant    pcmpeqw mm0,mm0
865    movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1    lea TMP1, [mmx_quant]
866    movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant    movq mm6, [TMP1 + TMP0*8]      ; quant
867    mov eax, -16    shl TMP0,31                    ; odd/even
868      movq mm7,mm6
869  ALIGN 16    movd mm1,TMP0d
870  .loop    mov TMP1, prm1                 ; data
871    movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]    movq mm5,mm0
872    movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]    psllw mm0,mm1                  ; quant & 1 ? 0 : - 1
873    pxor mm1, mm1    paddw mm7,mm7                  ; quant*2
874      paddw mm6,mm0                  ; quant & 1 ? quant : quant - 1
875      psllw mm5,12
876      mov TMP0,8
877      psrlw mm5,1                    ; 32767-2047 (32768-2048)
878    
879    .loop:
880      movq mm0,[_EAX]
881    pxor mm4, mm4    pxor mm4, mm4
   pcmpgtw mm1, mm0  ; sign(c)  
   pcmpgtw mm4, mm3  ; sign(c')  
882    pxor mm2, mm2    pxor mm2, mm2
883    pxor mm5, mm5    pcmpeqw mm4,mm0     ; if coeff==0...
884    pcmpeqw mm2, mm0  ; c is zero    pcmpgtw mm2,mm0
885    pcmpeqw mm5, mm3  ; c' is zero    pmullw mm0,mm7      ; * 2 * quant
886    pandn mm2, mm6    ; offset = isZero ? 0 : quant_add    pxor mm3,mm3
887    pandn mm5, mm6    psubw mm0,mm2
888    pxor mm0, mm1     ; negate if negative    movq mm1,[_EAX+8]
889    pxor mm3, mm4     ; negate if negative    pxor mm2,mm6
890    psubw mm0, mm1    pcmpgtw mm3,mm1
891    psubw mm3, mm4    pandn mm4,mm2      ; ... then data==0
892    pmullw mm0, mm7   ; *= 2Q    pmullw mm1,mm7
893    pmullw mm3, mm7   ; *= 2Q    pxor mm2,mm2
894    paddw mm0, mm2    ; + offset    pcmpeqw mm2,mm1
895    paddw mm3, mm5    ; + offset    psubw mm1,mm3
896    paddw mm0, mm1    ; negate back    pxor mm3,mm6
897    paddw mm3, mm4    ; negate back    pandn mm2,mm3
898    ; saturates to +2047    paddw mm0,mm4
899    movq mm2, [mmx_32767_minus_2047]    paddw mm1,mm2
900    add eax, 2  
901    paddsw mm0, mm2    paddsw mm0, mm5        ; saturate
902    paddsw mm3, mm2    paddsw mm1, mm5
903    psubsw mm0, mm2    psubsw mm0, mm5
904    psubsw mm3, mm2    psubsw mm1, mm5
905      psubsw mm0, mm5
906    pxor mm0, mm1    psubsw mm1, mm5
907    pxor mm3, mm4    paddsw mm0, mm5
908    movq [edx + 8*eax + 8*16   - 2*8], mm0    paddsw mm1, mm5
909    movq [edx + 8*eax + 8*16+8 - 2*8], mm3  
910    jnz near .loop    movq [TMP1],mm0
911      lea _EAX,[_EAX+16]
912      movq [TMP1+8],mm1
913    
914      dec TMP0
915      lea TMP1,[TMP1+16]
916      jne .loop
917    
918    xor eax, eax    xor _EAX, _EAX              ; return 0
919    ret    ret
920    ENDFUNC
921    
922    
923  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
924  ;  ;
# Line 884  Line 928 
928  ;                                 const uint16_t *mpeg_matrices);  ;                                 const uint16_t *mpeg_matrices);
929  ;  ;
930  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
931    ALIGN SECTION_ALIGN
   ; this is the same as dequant_inter_mmx,  
   ; except that we're saturating using 'pminsw' (saves 2 cycles/loop)  
   
 ALIGN 16  
932  dequant_h263_inter_xmm:  dequant_h263_inter_xmm:
933    
934    mov edx, [esp+ 4]        ; data    mov TMP0, prm3                 ; quant
935    mov ecx, [esp+ 8]        ; coeff    mov _EAX, prm2                 ; coeff
936    mov eax, [esp+12]        ; quant    pcmpeqw mm0,mm0
937    movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1    lea TMP1, [mmx_quant]
938    movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant    movq mm6, [TMP1 + TMP0*8]      ; quant
939    mov eax, -16    shl TMP0,31
940      movq mm5,mm0
941  ALIGN 16    movd mm1,TMP0d
942  .loop    movq mm7,mm6
943    movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]    psllw mm0,mm1
944    movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]    mov TMP1, prm1                 ; data
945    pxor mm1, mm1    movq mm4,mm5
946    pxor mm4, mm4    paddw mm7,mm7
947    pcmpgtw mm1, mm0  ; sign(c)    paddw mm6,mm0                     ; quant-1
948    pcmpgtw mm4, mm3  ; sign(c')  
949      psrlw mm4,5
950      mov TMP0,8
951      pxor mm5,mm4                      ; mm5=-2048
952    
953    .loop:
954      movq mm0,[_EAX]
955      pxor mm3,mm3
956    pxor mm2, mm2    pxor mm2, mm2
957    pxor mm5, mm5    pcmpeqw mm3,mm0
958    pcmpeqw mm2, mm0  ; c is zero    pcmpgtw mm2,mm0
959    pcmpeqw mm5, mm3  ; c' is zero    pmullw mm0,mm7                    ; * 2 * quant
960    pandn mm2, mm6    ; offset = isZero ? 0 : quant_add    pandn mm3,mm6
961    pandn mm5, mm6    movq mm1,[_EAX+8]
962    pxor mm0, mm1     ; negate if negative    psubw mm0,mm2
963    pxor mm3, mm4     ; negate if negative    pxor mm2,mm3
964    psubw mm0, mm1    pxor mm3,mm3
965    psubw mm3, mm4    paddw mm0,mm2
966    pmullw mm0, mm7   ; *= 2Q    pxor mm2,mm2
967    pmullw mm3, mm7   ; *= 2Q    pcmpgtw mm3,mm1
968    paddw mm0, mm2    ; + offset    pcmpeqw mm2,mm1
969    paddw mm3, mm5    ; + offset    pmullw mm1,mm7
970    paddw mm0, mm1    ; start restoring sign    pandn mm2,mm6
971    paddw mm3, mm4    ; start restoring sign    psubw mm1,mm3
972                              ; saturates to +2047    pxor mm3,mm2
973    movq mm2, [mmx_2047]    paddw mm1,mm3
974    pminsw mm0, mm2  
975    add eax, 2    pminsw mm0,mm4
976    pminsw mm3, mm2    pminsw mm1,mm4
977      pmaxsw mm0,mm5
978    pxor mm0, mm1 ; finish restoring sign    pmaxsw mm1,mm5
979    pxor mm3, mm4 ; finish restoring sign  
980    movq [edx + 8*eax + 8*16   - 2*8], mm0    movq [TMP1],mm0
981    movq [edx + 8*eax + 8*16+8 - 2*8], mm3    lea _EAX,[_EAX+16]
982    jnz near .loop    movq [TMP1+8],mm1
983    
984      dec TMP0
985      lea TMP1,[TMP1+16]
986      jne .loop
987    
988    xor eax, eax    xor _EAX, _EAX              ; return 0
989    ret    ret
990    ENDFUNC
991    
992    
993  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
994  ;  ;
# Line 946  Line 999 
999  ;  ;
1000  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
1001    
1002  ALIGN 16  ALIGN SECTION_ALIGN
1003  dequant_h263_inter_sse2:  dequant_h263_inter_sse2:
   mov edx, [esp + 4]    ; data  
   mov ecx, [esp + 8]    ; coeff  
   mov eax, [esp + 12]   ; quant  
   movq mm6, [mmx_add + eax * 8 - 8]  
   movq mm7, [mmx_mul + eax * 8 - 8]  
   movq2dq xmm6, mm6  
   movq2dq xmm7, mm7  
   movlhps xmm6, xmm6  
   movlhps xmm7, xmm7  
   mov eax, -16  
1004    
1005  ALIGN 16    mov TMP0, prm3                 ; quant
1006  .loop    mov _EAX, prm2                 ; coeff
   movdqa xmm0, [ecx + 8*16 + 8*eax]  ; c  = coeff[i]  
   movdqa xmm3, [ecx + 8*16 + 8*eax + 16]  
1007    
1008    pxor xmm1, xmm1    lea TMP1, [mmx_quant]
1009    pxor xmm4, xmm4    movq xmm6, [TMP1 + TMP0*8]    ; quant
1010    pcmpgtw xmm1, xmm0    ; sign(c)    inc TMP0
1011    pcmpgtw xmm4, xmm3    pcmpeqw xmm5,xmm5
1012      and TMP0,1
1013      movlhps xmm6,xmm6
1014      movd xmm0,TMP0d
1015      movdqa xmm7,xmm6
1016      pshuflw xmm0,xmm0,0
1017      movdqa xmm4,xmm5
1018      mov TMP1, prm1                 ; data
1019      movlhps xmm0,xmm0
1020      paddw xmm7,xmm7
1021      psubw xmm6,xmm0
1022      psrlw xmm4,5   ; 2047
1023      mov TMP0,4
1024      pxor xmm5,xmm4 ; mm5=-2048
1025    
1026    .loop:
1027      movdqa xmm0,[_EAX]
1028      pxor xmm3,xmm3
1029    pxor xmm2, xmm2    pxor xmm2, xmm2
1030    pxor xmm5, xmm5    pcmpeqw xmm3,xmm0
1031    pcmpeqw xmm2, xmm0    ; c is zero    pcmpgtw xmm2,xmm0
1032    pcmpeqw xmm5, xmm3    pmullw xmm0,xmm7      ; * 2 * quant
1033      pandn xmm3,xmm6
1034      movdqa xmm1,[_EAX+16]
1035      psubw xmm0,xmm2
1036      pxor xmm2,xmm3
1037      pxor xmm3,xmm3
1038      paddw xmm0,xmm2
1039      pxor xmm2,xmm2
1040      pcmpgtw xmm3,xmm1
1041      pcmpeqw xmm2,xmm1
1042      pmullw xmm1,xmm7
1043    pandn xmm2, xmm6    pandn xmm2, xmm6
1044    pandn xmm5, xmm6    psubw xmm1,xmm3
1045    pxor xmm0, xmm1       ; negate if negative    pxor xmm3,xmm2
1046    pxor xmm3, xmm4    paddw xmm1,xmm3
1047    psubw xmm0, xmm1  
1048    psubw xmm3, xmm4    pminsw xmm0,xmm4
1049    pmullw xmm0, xmm7     ; *= 2Q    pminsw xmm1,xmm4
1050    pmullw xmm3, xmm7    pmaxsw xmm0,xmm5
1051    paddw xmm0, xmm2      ; + offset    pmaxsw xmm1,xmm5
1052    paddw xmm3, xmm5  
1053      movdqa [TMP1],xmm0
1054    paddw xmm0, xmm1      ; start restoring sign    lea _EAX,[_EAX+32]
1055    paddw xmm3, xmm4    movdqa [TMP1+16],xmm1
1056    
1057   ; saturates to +2047    dec TMP0
1058    movdqa xmm2, [sse2_2047]    lea TMP1,[TMP1+32]
1059    pminsw xmm0, xmm2    jne .loop
   add eax, 4  
   pminsw xmm3, xmm2  
1060    
1061    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  
   
   xor eax, eax  
1062    ret    ret
1063    ENDFUNC
1064    
1065    
1066    %ifidn __OUTPUT_FORMAT__,elf
1067    section ".note.GNU-stack" noalloc noexec nowrite progbits
1068    %endif
1069    

Legend:
Removed from v.1382  
changed lines
  Added in v.1820

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