[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.2, Mon Mar 22 22:36:24 2004 UTC revision 1.7, Sun Aug 29 10:02:38 2004 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 31  Line 32 
32    
33  %macro cglobal 1  %macro cglobal 1
34         %ifdef PREFIX         %ifdef PREFIX
35                    %ifdef MARK_FUNCS
36                            global _%1:function %1.endfunc-%1
37                            %define %1 _%1:function %1.endfunc-%1
38                    %else
39                  global _%1                  global _%1
40                  %define %1 _%1                  %define %1 _%1
41                    %endif
42            %else
43                    %ifdef MARK_FUNCS
44                            global %1:function %1.endfunc-%1
45          %else          %else
46                  global %1                  global %1
47          %endif          %endif
48            %endif
49  %endmacro  %endmacro
50    
51  ;=============================================================================  ;=============================================================================
# Line 43  Line 53 
53  ;=============================================================================  ;=============================================================================
54    
55  %ifdef FORMAT_COFF  %ifdef FORMAT_COFF
56  SECTION .rodata data  SECTION .rodata
57  %else  %else
58  SECTION .rodata data align=16  SECTION .rodata align=16
59  %endif  %endif
60    
61  ALIGN 16  ALIGN 16
# Line 54  Line 64 
64    
65  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
66  ;  ;
67  ; subtract by Q/2 table  ; quant table
68  ;  ;
69  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
70    
71  ALIGN 16  ALIGN 16
72  mmx_sub:  mmx_quant:
73  %assign quant 1  %assign quant 0
74  %rep 31  %rep 32
75          times 4 dw  quant / 2          times 4 dw quant
76          %assign quant quant+1          %assign quant quant+1
77  %endrep  %endrep
78    
79  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
80  ;  ;
81  ; divide by 2Q table  ; subtract by Q/2 table
 ;  
 ; use a shift of 16 to take full advantage of _pmulhw_  
 ; for q=1, _pmulhw_ will overflow so it is treated seperately  
 ; (3dnow2 provides _pmulhuw_ which wont cause overflow)  
82  ;  ;
83  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
84    
85  ALIGN 16  ALIGN 16
86  mmx_div:  mmx_sub:
87  %assign quant 1  %assign quant 1
88  %rep 31  %rep 31
89          times 4 dw  (1<<16) / (quant*2) + 1          times 4 dw  quant / 2
90          %assign quant quant+1          %assign quant quant+1
91  %endrep  %endrep
92    
93  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
94  ;  ;
95  ; add by (odd(Q) ? Q : Q - 1) table  ; divide by 2Q 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  
   
 ;-----------------------------------------------------------------------------  
96  ;  ;
97  ; multiple by 2Q table  ; use a shift of 16 to take full advantage of _pmulhw_
98    ; for q=1, _pmulhw_ will overflow so it is treated seperately
99    ; (3dnow2 provides _pmulhuw_ which wont cause overflow)
100  ;  ;
101  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
102    
103  ALIGN 16  ALIGN 16
104  mmx_mul:  mmx_div:
105  %assign quant 1  %assign quant 1
106  %rep 31  %rep 31
107          times 4 dw  quant*2          times 4 dw  (1<<16) / (quant*2) + 1
108          %assign quant quant+1          %assign quant quant+1
109  %endrep  %endrep
110    
 ;-----------------------------------------------------------------------------  
 ;  
 ; 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)  
   
   
111  ;=============================================================================  ;=============================================================================
112  ; Code  ; Code
113  ;=============================================================================  ;=============================================================================
# Line 168  Line 138 
138  ALIGN 16  ALIGN 16
139  quant_h263_intra_mmx:  quant_h263_intra_mmx:
140    
   push ecx  
141    push esi    push esi
   push edi  
   
   mov edi, [esp + 12 + 4]     ; coeff  
   mov esi, [esp + 12 + 8]     ; data  
   mov eax, [esp + 12 + 12]    ; quant  
   
   xor ecx, ecx  
   cmp al, 1  
   jz .q1loop  
   
   movq mm7, [mmx_div + eax * 8 - 8]  
   
 ALIGN 16  
 .loop  
   movq mm0, [esi + 8*ecx]           ; mm0 = [1st]  
   movq mm3, [esi + 8*ecx + 8]  
   pxor mm1, mm1                     ; mm1 = 0  
   pxor mm4, mm4                     ;  
   pcmpgtw mm1, mm0                  ; mm1 = (0 > mm0)  
   pcmpgtw mm4, mm3                  ;  
   pxor mm0, mm1                     ; mm0 = |mm0|  
   pxor mm3, mm4                     ;  
   psubw mm0, mm1                    ; displace  
   psubw mm3, mm4                    ;  
   pmulhw mm0, mm7                   ; mm0 = (mm0 / 2Q) >> 16  
   pmulhw mm3, mm7                   ;  
   pxor mm0, mm1                     ; mm0 *= sign(mm0)  
   pxor mm3, mm4                     ;  
   psubw mm0, mm1                    ; undisplace  
   psubw mm3, mm4                    ;  
   movq [edi + 8*ecx], mm0  
   movq [edi + 8*ecx + 8], mm3  
142    
143    add ecx, 2    mov esi, [esp + 4 + 8]     ; data
144    cmp ecx, 16    mov ecx,[esp + 4 + 16]     ; dcscalar
   jnz .loop  
   
 .done  
   
     ; caclulate  data[0] // (int32_t)dcscalar)  
   mov ecx, [esp + 12 + 16]      ; dcscalar  
   mov edx, ecx  
145    movsx eax, word [esi]         ; data[0]    movsx eax, word [esi]         ; data[0]
   shr edx, 1                    ; edx = dcscalar /2  
   cmp eax, 0  
   jg .gtzero  
146    
147      sar ecx,1                  ; dcscalar /2
148      mov edx,eax
149      sar edx,31                 ; sgn(data[0])
150      xor ecx,edx                ; *sgn(data[0])
151    sub eax, edx    sub eax, edx
152    jmp short .mul    add eax,ecx                ; + (dcscalar/2)*sgn(data[0])
153    
154  .gtzero    mov ecx, [esp + 4 + 12]    ; quant
155    add eax, edx    cdq
156  .mul    idiv dword [esp + 4 + 16]  ; dcscalar
157    cdq ; expand eax -> edx:eax    cmp ecx, 1
158    idiv ecx          ; eax = edx:eax / dcscalar    mov edx, [esp + 4 + 4]     ; coeff
159    mov [edi], ax     ; coeff[0] = ax    je .low
   
   xor eax, eax      ; return(0);  
   pop edi  
   pop esi  
   pop ecx  
160    
161    ret    movq mm7, [mmx_div+ecx * 8 - 8]
162      mov ecx,4
163    
164  ALIGN 16  .loop
165  .q1loop    movq mm0, [esi]           ; data
166    movq mm0, [esi + 8*ecx]           ; mm0 = [1st]    pxor mm4,mm4
167    movq mm3, [esi + 8*ecx + 8]    movq mm1, [esi + 8]
168    pxor mm1, mm1                     ; mm1 = 0    pcmpgtw mm4,mm0           ; (data<0)
169    pxor mm4, mm4                     ;    pxor mm5,mm5
170    pcmpgtw mm1, mm0                  ; mm1 = (0 > mm0)    pmulhw mm0,mm7            ; /(2*quant)
171    pcmpgtw mm4, mm3                  ;    pcmpgtw mm5,mm1
172    pxor mm0, mm1                     ; mm0 = |mm0|    movq mm2, [esi+16]
173    pxor mm3, mm4                     ;    psubw mm0,mm4             ;  +(data<0)
174    psubw mm0, mm1                    ; displace    pmulhw mm1,mm7
175    psubw mm3, mm4                    ;    pxor mm4,mm4
176    psrlw mm0, 1                      ; mm0 >>= 1   (/2)    movq mm3,[esi+24]
177    psrlw mm3, 1                      ;    pcmpgtw mm4,mm2
178    pxor mm0, mm1                     ; mm0 *= sign(mm0)    psubw mm1,mm5
179    pxor mm3, mm4    pmulhw mm2,mm7
180    psubw mm0, mm1                    ; undisplace    pxor mm5,mm5
181    psubw mm3, mm4                    ;    pcmpgtw mm5,mm3
182    movq [edi + 8*ecx], mm0    pmulhw mm3,mm7
183    movq [edi + 8*ecx + 8], mm3    psubw mm2,mm4
184      psubw mm3,mm5
185      movq [edx], mm0
186      lea esi, [esi+32]
187      movq [edx + 8], mm1
188      movq [edx + 16], mm2
189      movq [edx + 24], mm3
190    
191      dec ecx
192      lea edx, [edx+32]
193      jne .loop
194      jmp .end
195    
196    .low
197      movd mm7,ecx
198      mov ecx,4
199    .loop_low
200      movq mm0, [esi]
201      pxor mm4,mm4
202      movq mm1, [esi + 8]
203      pcmpgtw mm4,mm0
204      pxor mm5,mm5
205      psubw mm0,mm4
206      pcmpgtw mm5,mm1
207      psraw mm0,mm7
208      psubw mm1,mm5
209      movq mm2,[esi+16]
210      pxor mm4,mm4
211      psraw mm1,mm7
212      pcmpgtw mm4,mm2
213      pxor mm5,mm5
214      psubw mm2,mm4
215      movq mm3,[esi+24]
216      pcmpgtw mm5,mm3
217      psraw mm2,mm7
218      psubw mm3,mm5
219      movq [edx], mm0
220      psraw mm3,mm7
221      movq [edx + 8], mm1
222      movq [edx+16],mm2
223      lea esi, [esi+32]
224      movq [edx+24],mm3
225    
226      dec ecx
227      lea edx, [edx+32]
228      jne .loop_low
229    
230    add ecx, 2  .end
231    cmp ecx, 16    mov edx, [esp + 4 + 4]     ; coeff
232    jnz .q1loop    mov [edx],ax
233    jmp short .done    xor eax,eax                ; return 0
234    
235      pop esi
236      ret
237    .endfunc
238    
239    
240  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
# Line 276  Line 251 
251  quant_h263_intra_sse2:  quant_h263_intra_sse2:
252    
253    push esi    push esi
   push edi  
254    
255    mov edi, [esp + 8 + 4]                ; coeff    mov esi, [esp + 4 + 8]     ; data
   mov esi, [esp + 8 + 8]                ; data  
   mov eax, [esp + 8 + 12]               ; quant  
256    
257    xor ecx, ecx    movsx eax, word [esi]      ; data[0]
   cmp al, 1  
   jz near .qas2_q1loop  
258    
259  .qas2_not1    mov ecx,[esp + 4 + 16]     ; dcscalar
260    movq mm7, [mmx_div + eax*8 - 8]    mov edx,eax
261    movq2dq xmm7, mm7    sar ecx,1
262      add eax,ecx
263      sub edx,ecx
264      cmovl eax,edx              ; +/- dcscalar/2
265      mov ecx, [esp + 4 + 12]    ; quant
266      cdq
267      idiv dword [esp + 4 + 16]  ; dcscalar
268      cmp ecx, 1
269      mov edx, [esp + 4 + 4]     ; coeff
270      movq xmm7, [mmx_div+ecx * 8 - 8]
271      je .low
272    
273      mov ecx,2
274    movlhps xmm7, xmm7    movlhps xmm7, xmm7
275    
276  ALIGN 16  .loop
277  .qas2_loop    movdqa xmm0, [esi]
   movdqa xmm0, [esi + ecx*8]                ; xmm0 = [1st]  
   movdqa xmm3, [esi + ecx*8 + 16]           ; xmm3 = [2nd]  
   pxor xmm1, xmm1  
278    pxor xmm4, xmm4    pxor xmm4, xmm4
279    pcmpgtw xmm1, xmm0    movdqa xmm1, [esi + 16]
280    pcmpgtw xmm4, xmm3    pcmpgtw xmm4,xmm0
281    pxor xmm0, xmm1    pxor xmm5,xmm5
   pxor xmm3, xmm4  
   psubw xmm0, xmm1  
   psubw xmm3, xmm4  
282    pmulhw xmm0, xmm7    pmulhw xmm0, xmm7
283      pcmpgtw xmm5,xmm1
284      movdqa xmm2, [esi+32]
285      psubw xmm0,xmm4
286      pmulhw xmm1,xmm7
287      pxor xmm4,xmm4
288      movdqa xmm3,[esi+48]
289      pcmpgtw xmm4,xmm2
290      psubw xmm1,xmm5
291      pmulhw xmm2,xmm7
292      pxor xmm5,xmm5
293      pcmpgtw xmm5,xmm3
294    pmulhw xmm3, xmm7    pmulhw xmm3, xmm7
295    pxor xmm0, xmm1    psubw xmm2,xmm4
296    pxor xmm3, xmm4    psubw xmm3,xmm5
297    psubw xmm0, xmm1    movdqa [edx], xmm0
298    psubw xmm3, xmm4    lea esi, [esi+64]
299    movdqa [edi + ecx*8], xmm0    movdqa [edx + 16], xmm1
300    movdqa [edi + ecx*8 + 16], xmm3    movdqa [edx + 32], xmm2
301      movdqa [edx + 48], xmm3
302    add ecx, 4  
303    cmp ecx, 16    dec ecx
304    jnz .qas2_loop    lea edx, [edx+64]
305      jne .loop
306  .qas2_done    jmp .end
307    mov ecx, [esp + 8 + 16]   ; dcscalar  
308    mov edx, ecx  .low
309    movsx eax, word [esi]    movd xmm7,ecx
310    shr edx, 1    mov ecx,2
311    cmp eax, 0  .loop_low
312    jg .qas2_gtzero    movdqa xmm0, [esi]
313      pxor xmm4,xmm4
314    sub eax, edx    movdqa xmm1, [esi + 16]
315    jmp short .qas2_mul    pcmpgtw xmm4,xmm0
316      pxor xmm5,xmm5
317  .qas2_gtzero    psubw xmm0,xmm4
318    add eax, edx    pcmpgtw xmm5,xmm1
319      psraw xmm0,xmm7
320  .qas2_mul    psubw xmm1,xmm5
321    cdq    movdqa xmm2,[esi+32]
322    idiv ecx    pxor xmm4,xmm4
323      psraw xmm1,xmm7
324      pcmpgtw xmm4,xmm2
325      pxor xmm5,xmm5
326      psubw xmm2,xmm4
327      movdqa xmm3,[esi+48]
328      pcmpgtw xmm5,xmm3
329      psraw xmm2,xmm7
330      psubw xmm3,xmm5
331      movdqa [edx], xmm0
332      psraw xmm3,xmm7
333      movdqa [edx+16], xmm1
334      movdqa [edx+32],xmm2
335      lea esi, [esi+64]
336      movdqa [edx+48],xmm3
337    
338      dec ecx
339      lea edx, [edx+64]
340      jne .loop_low
341    
342    mov [edi], ax  .end
343      mov edx, [esp + 4 + 4]     ; coeff
344      mov [edx],ax
345      xor eax,eax                ; return 0
346    
   xor eax, eax      ; return(0);  
   pop edi  
347    pop esi    pop esi
   
348    ret    ret
349    .endfunc
 ALIGN 16  
 .qas2_q1loop  
   movdqa xmm0, [esi + ecx*8]         ; xmm0 = [1st]  
   movdqa xmm3, [esi + ecx*8 + 16]    ; xmm3 = [2nd]  
   pxor xmm1, xmm1  
   pxor xmm4, xmm4  
   pcmpgtw xmm1, xmm0  
   pcmpgtw xmm4, xmm3  
   pxor xmm0, xmm1  
   pxor xmm3, xmm4  
   psubw xmm0, xmm1  
   psubw xmm3, xmm4  
   psrlw xmm0, 1  
   psrlw xmm3, 1  
   pxor xmm0, xmm1  
   pxor xmm3, xmm4  
   psubw xmm0, xmm1  
   psubw xmm3, xmm4  
   movdqa [edi + ecx*8], xmm0  
   movdqa [edi + ecx*8 + 16], xmm3  
   
   add ecx, 4  
   cmp ecx, 16  
   jnz .qas2_q1loop  
   jmp near .qas2_done  
   
   
350    
351  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
352  ;  ;
# Line 472  Line 450 
450    jnz .q1loop    jnz .q1loop
451    
452    jmp .done    jmp .done
453    .endfunc
454    
455    
456    
# Line 586  Line 565 
565    cmp ecx, 16    cmp ecx, 16
566    jnz .qes2_q1loop    jnz .qes2_q1loop
567    jmp .qes2_done    jmp .qes2_done
568    .endfunc
569    
570    
571  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
# Line 598  Line 578 
578  ;  ;
579  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
580    
   ; note: we only saturate to +2047 *before* restoring the sign.  
   ; Hence, final clamp really is [-2048,2047]  
   
581  ALIGN 16  ALIGN 16
582  dequant_h263_intra_mmx:  dequant_h263_intra_mmx:
583    
584      mov ecx, [esp+12]                 ; quant
585      mov eax, [esp+ 8]                 ; coeff
586      pcmpeqw mm0,mm0
587      movq mm6, [mmx_quant + ecx*8]     ; quant
588      shl ecx,31                        ; quant & 1 ? 0 : - 1
589      movq mm7,mm6
590      movq mm5,mm0
591      movd mm1,ecx
592    mov edx, [esp+ 4]                 ; data    mov edx, [esp+ 4]                 ; data
593    mov ecx, [esp+ 8]                 ; coeff    psllw mm0,mm1
594    mov eax, [esp+12]                 ; quant    paddw mm7,mm7                     ; 2*quant
595    movq mm6, [mmx_add + eax*8 - 8]   ; quant or quant-1    paddw mm6,mm0                     ; quant-1
596    movq mm7, [mmx_mul + eax*8 - 8]   ; 2*quant    psllw mm5,12
597    mov eax, -16    mov ecx,8
598      psrlw mm5,1
599    
600  ALIGN 16  .loop:
601  .loop    movq mm0,[eax]
602    movq mm0, [ecx+8*eax+8*16]        ; c  = coeff[i]    pxor mm2,mm2
   movq mm3, [ecx+8*eax+8*16 + 8]    ; c' = coeff[i+1]  
   pxor mm1, mm1  
603    pxor mm4, mm4    pxor mm4, mm4
604    pcmpgtw mm1, mm0                  ; sign(c)    pcmpgtw mm2,mm0
605    pcmpgtw mm4, mm3                  ; sign(c')    pcmpeqw mm4,mm0
606      pmullw mm0,mm7      ; * 2 * quant
607      movq mm1,[eax+8]
608      psubw mm0,mm2
609      pxor mm2,mm6
610      pxor mm3,mm3
611      pandn mm4,mm2
612    pxor mm2, mm2    pxor mm2, mm2
613    pxor mm5, mm5    pcmpgtw mm3,mm1
614    pcmpeqw mm2, mm0                  ; c is zero    pcmpeqw mm2,mm1
615    pcmpeqw mm5, mm3                  ; c' is zero    pmullw mm1,mm7
616    pandn mm2, mm6                    ; offset = isZero ? 0 : quant_add    paddw mm0,mm4
617    pandn mm5, mm6    psubw mm1,mm3
618    pxor mm0, mm1                     ; negate if negative    pxor mm3,mm6
619    pxor mm3, mm4                     ; negate if negative    pandn mm2,mm3
620    psubw mm0, mm1    paddsw mm0, mm5        ; saturate
621    psubw mm3, mm4    paddw mm1,mm2
622    pmullw mm0, mm7                   ; *= 2Q  
623    pmullw mm3, mm7                   ; *= 2Q    paddsw mm1, mm5
624    paddw mm0, mm2                    ; + offset    psubsw mm0, mm5
625    paddw mm3, mm5                    ; + offset    psubsw mm1, mm5
626    paddw mm0, mm1                    ; negate back    psubsw mm0, mm5
627    paddw mm3, mm4                    ; negate back    psubsw mm1, mm5
628      paddsw mm0, mm5
629    ; saturates to +2047    paddsw mm1, mm5
630    movq mm2, [mmx_32767_minus_2047]  
631    add eax, 2    movq [edx],mm0
632    paddsw mm0, mm2    lea eax,[eax+16]
633    paddsw mm3, mm2    movq [edx+8],mm1
634    psubsw mm0, mm2  
635    psubsw mm3, mm2    dec ecx
636      lea edx,[edx+16]
637    pxor mm0, mm1    jne .loop
   pxor mm3, mm4  
   movq [edx + 8*eax + 8*16   - 2*8], mm0  
   movq [edx + 8*eax + 8*16+8 - 2*8], mm3  
   jnz near .loop  
638    
639   ; deal with DC   ; deal with DC
640    movd mm0, [ecx]    mov eax, [esp+ 8]                ; coeff
641    pmullw mm0, [esp+16]          ; dcscalar    movd mm1,[esp+16]                ; dcscalar
642    movq mm2, [mmx_32767_minus_2047]    movd mm0,[eax]                   ; coeff[0]
643    paddsw mm0, mm2    pmullw mm0,mm1                   ; * dcscalar
644    psubsw mm0, mm2    mov edx, [esp+ 4]                ; data
645    movq mm3, [mmx_32768_minus_2048]    paddsw mm0, mm5                  ; saturate +
646    psubsw mm0, mm3    psubsw mm0, mm5
647    paddsw mm0, mm3    psubsw mm0, mm5                  ; saturate -
648      paddsw mm0, mm5
649    movd eax, mm0    movd eax, mm0
650    mov [edx], ax    mov [edx], ax
651    
652    xor eax, eax              ; return(0);    xor eax, eax                    ; return 0
653    ret    ret
654    .endfunc
655    
656  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
657  ;  ;
# Line 675  Line 663 
663  ;  ;
664  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
665    
   ; this is the same as dequant_inter_mmx, except that we're  
   ; saturating using 'pminsw' (saves 2 cycles/loop => ~5% faster)  
666    
667  ALIGN 16  ALIGN 16
668  dequant_h263_intra_xmm:  dequant_h263_intra_xmm:
669    
670      mov ecx, [esp+12]                 ; quant
671      mov eax, [esp+ 8]                 ; coeff
672    
673      movd mm6,ecx                      ; quant
674      pcmpeqw mm0,mm0
675      pshufw mm6,mm6,0                  ; all quant
676      shl ecx,31
677      movq mm5,mm0
678      movq mm7,mm6
679      movd mm1,ecx
680    mov edx, [esp+ 4]                 ; data    mov edx, [esp+ 4]                 ; data
681    mov ecx, [esp+ 8]                 ; coeff    psllw mm0,mm1                     ; quant & 1 ? 0 : - 1
682    mov eax, [esp+12]                 ; quant    movq mm4,mm5
683    movq mm6, [mmx_add + eax*8 - 8]   ; quant or quant-1    paddw mm7,mm7                     ; quant*2
684    movq mm7, [mmx_mul + eax*8 - 8]   ; 2*quant    paddw mm6,mm0                     ; quant-1
685    mov eax, -16    psrlw mm4,5                       ; mm4=2047
686      mov ecx,8
687      pxor mm5,mm4                      ; mm5=-2048
688    
689  ALIGN 16  .loop:
690  .loop    movq mm0,[eax]
   movq mm0, [ecx+8*eax+8*16]        ; c  = coeff[i]  
   movq mm3, [ecx+8*eax+8*16 + 8]    ; c' = coeff[i+1]  
   pxor mm1, mm1  
   pxor mm4, mm4  
   pcmpgtw mm1, mm0                  ; sign(c)  
   pcmpgtw mm4, mm3                  ; sign(c')  
691    pxor mm2, mm2    pxor mm2, mm2
692    pxor mm5, mm5    pxor mm3,mm3
693    pcmpeqw mm2, mm0                  ; c is zero  
694    pcmpeqw mm5, mm3                  ; c' is zero    pcmpgtw mm2,mm0
695    pandn mm2, mm6                    ; offset = isZero ? 0 : quant_add    pcmpeqw mm3,mm0     ; if coeff==0...
696    pandn mm5, mm6    pmullw mm0,mm7      ; * 2 * quant
697    pxor mm0, mm1                     ; negate if negative    movq mm1,[eax+8]
698    pxor mm3, mm4                     ; negate if negative  
699    psubw mm0, mm1    psubw mm0,mm2
700    psubw mm3, mm4    pxor mm2,mm6
701    pmullw mm0, mm7                   ; *= 2Q    pandn mm3,mm2       ; ...then data=0
702    pmullw mm3, mm7                   ; *= 2Q    pxor mm2,mm2
703    paddw mm0, mm2                    ; + offset    paddw mm0,mm3
704    paddw mm3, mm5                    ; + offset    pxor mm3,mm3
705    paddw mm0, mm1                    ; negate back    pcmpeqw mm2,mm1
706    paddw mm3, mm4                    ; negate back    pcmpgtw mm3,mm1
707      pmullw mm1,mm7
708     ; saturates to +2047  
709    movq mm2, [mmx_2047]    pminsw mm0,mm4
710    pminsw mm0, mm2    psubw mm1,mm3
711    add eax, 2    pxor mm3,mm6
712    pminsw mm3, mm2    pandn mm2,mm3
713      paddw mm1,mm2
714    pxor mm0, mm1  
715    pxor mm3, mm4    pmaxsw mm0,mm5
716    movq [edx + 8*eax + 8*16   - 2*8], mm0    pminsw mm1,mm4
717    movq [edx + 8*eax + 8*16+8 - 2*8], mm3    movq [edx],mm0
718    jnz near .loop    pmaxsw mm1,mm5
719      lea eax,[eax+16]
720      movq [edx+8],mm1
721    
722      dec ecx
723      lea edx,[edx+16]
724      jne .loop
725    
726      ; deal with DC      ; deal with DC
727    movd mm0, [ecx]    mov eax, [esp+ 8]                 ; coeff
728    pmullw mm0, [esp+16]    ; dcscalar    movd mm1,[esp+16]                 ; dcscalar
729    movq mm2, [mmx_32767_minus_2047]    movd mm0, [eax]
730    paddsw mm0, mm2    pmullw mm0, mm1
731    psubsw mm0, mm2    mov edx, [esp+ 4]                 ; data
732    movq mm2, [mmx_32768_minus_2048]    pminsw mm0,mm4
733    psubsw mm0, mm2    pmaxsw mm0,mm5
   paddsw mm0, mm2  
734    movd eax, mm0    movd eax, mm0
735    mov [edx], ax    mov [edx], ax
736    
737    xor eax, eax    xor eax, eax                      ; return 0
738    ret    ret
739    .endfunc
740    
741    
742  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
# Line 753  Line 751 
751    
752  ALIGN 16  ALIGN 16
753  dequant_h263_intra_sse2:  dequant_h263_intra_sse2:
754    
755      mov ecx, [esp+12]                 ; quant
756      mov eax, [esp+ 8]                 ; coeff
757    
758      movd xmm6,ecx                     ; quant
759    
760      shl ecx,31
761      pshuflw xmm6,xmm6,0
762      pcmpeqw xmm0,xmm0
763      movlhps xmm6,xmm6                 ; all quant
764      movd xmm1,ecx
765      movdqa xmm5,xmm0
766      movdqa xmm7,xmm6
767    mov edx, [esp+ 4]        ; data    mov edx, [esp+ 4]        ; data
768    mov ecx, [esp+ 8]        ; coeff    paddw xmm7,xmm7                   ; quant *2
769    mov eax, [esp+12]        ; quant    psllw xmm0,xmm1                   ; quant & 1 ? 0 : - 1
770    movq mm6, [mmx_add + eax * 8 - 8]    movdqa xmm4,xmm5
771    movq mm7, [mmx_mul + eax * 8 - 8]    paddw xmm6,xmm0                   ; quant-1
772    movq2dq xmm6, mm6    psrlw xmm4,5                      ; 2047
773    movq2dq xmm7, mm7    mov ecx,4
774    movlhps xmm6, xmm6    pxor xmm5,xmm4                    ; mm5=-2048
   movlhps xmm7, xmm7  
   mov eax, -16  
775    
776  ALIGN 16  .loop:
777  .loop    movdqa xmm0,[eax]
   movdqa xmm0, [ecx + 8*16 + 8*eax]      ; c  = coeff[i]  
   movdqa xmm3, [ecx + 8*16 + 8*eax+ 16]  
   pxor xmm1, xmm1  
   pxor xmm4, xmm4  
   pcmpgtw xmm1, xmm0    ; sign(c)  
   pcmpgtw xmm4, xmm3  
778    pxor xmm2, xmm2    pxor xmm2, xmm2
779    pxor xmm5, xmm5    pxor xmm3,xmm3
   pcmpeqw xmm2, xmm0    ; c is zero  
   pcmpeqw xmm5, xmm3  
   pandn xmm2, xmm6      ; offset = isZero ? 0 : quant_add  
   pandn xmm5, xmm6  
   pxor xmm0, xmm1       ; negate if negative  
   pxor xmm3, xmm4  
   psubw xmm0, xmm1  
   psubw xmm3, xmm4  
   pmullw xmm0, xmm7     ; *= 2Q  
   pmullw xmm3, xmm7  
   paddw xmm0, xmm2      ; + offset  
   paddw xmm3, xmm5  
   paddw xmm0, xmm1      ; negate back  
   paddw xmm3, xmm4  
   
     ; saturates to +2047  
   movdqa xmm2, [sse2_2047]  
   pminsw xmm0, xmm2  
   add eax, 4  
   pminsw xmm3, xmm2  
780    
781    pxor xmm0, xmm1    pcmpgtw xmm2,xmm0
782    pxor xmm3, xmm4    pcmpeqw xmm3,xmm0
783    movdqa [edx + 8*16 - 8*4 + 8*eax], xmm0    pmullw xmm0,xmm7      ; * 2 * quant
784    movdqa [edx + 8*16 - 8*4 + 8*eax + 16], xmm3    movdqa xmm1,[eax+16]
785    jnz near .loop  
786      psubw xmm0,xmm2
787      pxor xmm2,xmm6
788      pandn xmm3,xmm2
789      pxor xmm2,xmm2
790      paddw xmm0,xmm3
791      pxor xmm3,xmm3
792      pcmpeqw xmm2,xmm1
793      pcmpgtw xmm3,xmm1
794      pmullw xmm1,xmm7
795    
796      pminsw xmm0,xmm4
797      psubw xmm1,xmm3
798      pxor xmm3,xmm6
799      pandn xmm2,xmm3
800      paddw xmm1,xmm2
801    
802      pmaxsw xmm0,xmm5
803      pminsw xmm1,xmm4
804      movdqa [edx],xmm0
805      pmaxsw xmm1,xmm5
806      lea eax,[eax+32]
807      movdqa [edx+16],xmm1
808    
809      dec ecx
810      lea edx,[edx+32]
811      jne .loop
812    
813   ; deal with DC   ; deal with DC
814    movd mm0, [ecx]  
815    pmullw mm0, [esp+16]    ; dcscalar    mov eax, [esp+ 8]             ; coeff
816    movq mm2, [mmx_32767_minus_2047]    movsx eax,word [eax]
817    paddsw mm0, mm2    imul dword [esp+16]           ; dcscalar
818    psubsw mm0, mm2    mov edx, [esp+ 4]             ; data
819    movq mm2, [mmx_32768_minus_2048]    movd xmm0,eax
820    psubsw mm0, mm2    pminsw xmm0,xmm4
821    paddsw mm0, mm2    pmaxsw xmm0,xmm5
822    movd eax, mm0    movd eax,xmm0
823    
824    mov [edx], ax    mov [edx], ax
825    
826    xor eax, eax    xor eax, eax                  ; return 0
827    ret    ret
828    .endfunc
829    
830  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
831  ;  ;
# Line 828  Line 839 
839  ALIGN 16  ALIGN 16
840  dequant_h263_inter_mmx:  dequant_h263_inter_mmx:
841    
842      mov ecx, [esp+12]                 ; quant
843      mov eax, [esp+ 8]                 ; coeff
844      pcmpeqw mm0,mm0
845      movq mm6, [mmx_quant + ecx*8]     ; quant
846      shl ecx,31                        ; odd/even
847      movq mm7,mm6
848      movd mm1,ecx
849    mov edx, [esp+ 4]        ; data    mov edx, [esp+ 4]        ; data
850    mov ecx, [esp+ 8]        ; coeff    movq mm5,mm0
851    mov eax, [esp+12]        ; quant    psllw mm0,mm1                     ; quant & 1 ? 0 : - 1
852    movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1    paddw mm7,mm7                     ; quant*2
853    movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant    paddw mm6,mm0                     ; quant & 1 ? quant : quant - 1
854    mov eax, -16    psllw mm5,12
855      mov ecx,8
856      psrlw mm5,1                       ; 32767-2047 (32768-2048)
857    
858  ALIGN 16  .loop:
859  .loop    movq mm0,[eax]
   movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]  
   movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]  
   pxor mm1, mm1  
860    pxor mm4, mm4    pxor mm4, mm4
   pcmpgtw mm1, mm0  ; sign(c)  
   pcmpgtw mm4, mm3  ; sign(c')  
861    pxor mm2, mm2    pxor mm2, mm2
862    pxor mm5, mm5    pcmpeqw mm4,mm0     ; if coeff==0...
863    pcmpeqw mm2, mm0  ; c is zero    pcmpgtw mm2,mm0
864    pcmpeqw mm5, mm3  ; c' is zero    pmullw mm0,mm7      ; * 2 * quant
865    pandn mm2, mm6    ; offset = isZero ? 0 : quant_add    pxor mm3,mm3
866    pandn mm5, mm6    psubw mm0,mm2
867    pxor mm0, mm1     ; negate if negative    movq mm1,[eax+8]
868    pxor mm3, mm4     ; negate if negative    pxor mm2,mm6
869    psubw mm0, mm1    pcmpgtw mm3,mm1
870    psubw mm3, mm4    pandn mm4,mm2      ; ... then data==0
871    pmullw mm0, mm7   ; *= 2Q    pmullw mm1,mm7
872    pmullw mm3, mm7   ; *= 2Q    pxor mm2,mm2
873    paddw mm0, mm2    ; + offset    pcmpeqw mm2,mm1
874    paddw mm3, mm5    ; + offset    psubw mm1,mm3
875    paddw mm0, mm1    ; negate back    pxor mm3,mm6
876    paddw mm3, mm4    ; negate back    pandn mm2,mm3
877    ; saturates to +2047    paddw mm0,mm4
878    movq mm2, [mmx_32767_minus_2047]    paddw mm1,mm2
879    add eax, 2  
880    paddsw mm0, mm2    paddsw mm0, mm5        ; saturate
881    paddsw mm3, mm2    paddsw mm1, mm5
882    psubsw mm0, mm2    psubsw mm0, mm5
883    psubsw mm3, mm2    psubsw mm1, mm5
884      psubsw mm0, mm5
885    pxor mm0, mm1    psubsw mm1, mm5
886    pxor mm3, mm4    paddsw mm0, mm5
887    movq [edx + 8*eax + 8*16   - 2*8], mm0    paddsw mm1, mm5
888    movq [edx + 8*eax + 8*16+8 - 2*8], mm3  
889    jnz near .loop    movq [edx],mm0
890      lea eax,[eax+16]
891      movq [edx+8],mm1
892    
893      dec ecx
894      lea edx,[edx+16]
895      jne .loop
896    
897    xor eax, eax    xor eax, eax              ; return 0
898    ret    ret
899    .endfunc
900    
901    
902  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
903  ;  ;
# Line 884  Line 907 
907  ;                                 const uint16_t *mpeg_matrices);  ;                                 const uint16_t *mpeg_matrices);
908  ;  ;
909  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
   
   ; this is the same as dequant_inter_mmx,  
   ; except that we're saturating using 'pminsw' (saves 2 cycles/loop)  
   
910  ALIGN 16  ALIGN 16
911  dequant_h263_inter_xmm:  dequant_h263_inter_xmm:
912    
913      mov ecx, [esp+12]                 ; quant
914      mov eax, [esp+ 8]                 ; coeff
915      pcmpeqw mm0,mm0
916      movq mm6, [mmx_quant + ecx*8]     ; quant
917      shl ecx,31
918      movq mm5,mm0
919      movd mm1,ecx
920      movq mm7,mm6
921      psllw mm0,mm1
922    mov edx, [esp+ 4]        ; data    mov edx, [esp+ 4]        ; data
923    mov ecx, [esp+ 8]        ; coeff    movq mm4,mm5
924    mov eax, [esp+12]        ; quant    paddw mm7,mm7
925    movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1    paddw mm6,mm0                     ; quant-1
926    movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant  
927    mov eax, -16    psrlw mm4,5
928      mov ecx,8
929  ALIGN 16    pxor mm5,mm4                      ; mm5=-2048
930  .loop  
931    movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]  .loop:
932    movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]    movq mm0,[eax]
933    pxor mm1, mm1    pxor mm3,mm3
   pxor mm4, mm4  
   pcmpgtw mm1, mm0  ; sign(c)  
   pcmpgtw mm4, mm3  ; sign(c')  
934    pxor mm2, mm2    pxor mm2, mm2
935    pxor mm5, mm5    pcmpeqw mm3,mm0
936    pcmpeqw mm2, mm0  ; c is zero    pcmpgtw mm2,mm0
937    pcmpeqw mm5, mm3  ; c' is zero    pmullw mm0,mm7                    ; * 2 * quant
938    pandn mm2, mm6    ; offset = isZero ? 0 : quant_add    pandn mm3,mm6
939    pandn mm5, mm6    movq mm1,[eax+8]
940    pxor mm0, mm1     ; negate if negative    psubw mm0,mm2
941    pxor mm3, mm4     ; negate if negative    pxor mm2,mm3
942    psubw mm0, mm1    pxor mm3,mm3
943    psubw mm3, mm4    paddw mm0,mm2
944    pmullw mm0, mm7   ; *= 2Q    pxor mm2,mm2
945    pmullw mm3, mm7   ; *= 2Q    pcmpgtw mm3,mm1
946    paddw mm0, mm2    ; + offset    pcmpeqw mm2,mm1
947    paddw mm3, mm5    ; + offset    pmullw mm1,mm7
948    paddw mm0, mm1    ; start restoring sign    pandn mm2,mm6
949    paddw mm3, mm4    ; start restoring sign    psubw mm1,mm3
950                              ; saturates to +2047    pxor mm3,mm2
951    movq mm2, [mmx_2047]    paddw mm1,mm3
952    pminsw mm0, mm2  
953    add eax, 2    pminsw mm0,mm4
954    pminsw mm3, mm2    pminsw mm1,mm4
955      pmaxsw mm0,mm5
956    pxor mm0, mm1 ; finish restoring sign    pmaxsw mm1,mm5
957    pxor mm3, mm4 ; finish restoring sign  
958    movq [edx + 8*eax + 8*16   - 2*8], mm0    movq [edx],mm0
959    movq [edx + 8*eax + 8*16+8 - 2*8], mm3    lea eax,[eax+16]
960    jnz near .loop    movq [edx+8],mm1
961    
962      dec ecx
963      lea edx,[edx+16]
964      jne .loop
965    
966    xor eax, eax    xor eax, eax              ; return 0
967    ret    ret
968    .endfunc
969    
970    
971  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
972  ;  ;
# Line 948  Line 979 
979    
980  ALIGN 16  ALIGN 16
981  dequant_h263_inter_sse2:  dequant_h263_inter_sse2:
   mov edx, [esp + 4]    ; data  
   mov ecx, [esp + 8]    ; coeff  
   mov eax, [esp + 12]   ; quant  
   movq mm6, [mmx_add + eax * 8 - 8]  
   movq mm7, [mmx_mul + eax * 8 - 8]  
   movq2dq xmm6, mm6  
   movq2dq xmm7, mm7  
   movlhps xmm6, xmm6  
   movlhps xmm7, xmm7  
   mov eax, -16  
982    
983  ALIGN 16    mov ecx, [esp+12]                 ; quant
984  .loop    mov eax, [esp+ 8]                 ; coeff
   movdqa xmm0, [ecx + 8*16 + 8*eax]  ; c  = coeff[i]  
   movdqa xmm3, [ecx + 8*16 + 8*eax + 16]  
985    
986    pxor xmm1, xmm1    movq xmm6, [mmx_quant + ecx*8]    ; quant
987    pxor xmm4, xmm4    inc ecx
988    pcmpgtw xmm1, xmm0    ; sign(c)    pcmpeqw xmm5,xmm5
989    pcmpgtw xmm4, xmm3    and ecx,1
990      movlhps xmm6,xmm6
991      movd xmm0,ecx
992      movdqa xmm7,xmm6
993      pshuflw xmm0,xmm0,0
994      movdqa xmm4,xmm5
995      mov edx, [esp+ 4]                 ; data
996      movlhps xmm0,xmm0
997      paddw xmm7,xmm7
998      psubw xmm6,xmm0
999      psrlw xmm4,5   ; 2047
1000      mov ecx,4
1001      pxor xmm5,xmm4 ; mm5=-2048
1002    
1003    .loop:
1004      movdqa xmm0,[eax]
1005      pxor xmm3,xmm3
1006    pxor xmm2, xmm2    pxor xmm2, xmm2
1007    pxor xmm5, xmm5    pcmpeqw xmm3,xmm0
1008    pcmpeqw xmm2, xmm0    ; c is zero    pcmpgtw xmm2,xmm0
1009    pcmpeqw xmm5, xmm3    pmullw xmm0,xmm7      ; * 2 * quant
1010      pandn xmm3,xmm6
1011      movdqa xmm1,[eax+16]
1012      psubw xmm0,xmm2
1013      pxor xmm2,xmm3
1014      pxor xmm3,xmm3
1015      paddw xmm0,xmm2
1016      pxor xmm2,xmm2
1017      pcmpgtw xmm3,xmm1
1018      pcmpeqw xmm2,xmm1
1019      pmullw xmm1,xmm7
1020    pandn xmm2, xmm6    pandn xmm2, xmm6
1021    pandn xmm5, xmm6    psubw xmm1,xmm3
1022    pxor xmm0, xmm1       ; negate if negative    pxor xmm3,xmm2
1023    pxor xmm3, xmm4    paddw xmm1,xmm3
1024    psubw xmm0, xmm1  
1025    psubw xmm3, xmm4    pminsw xmm0,xmm4
1026    pmullw xmm0, xmm7     ; *= 2Q    pminsw xmm1,xmm4
1027    pmullw xmm3, xmm7    pmaxsw xmm0,xmm5
1028    paddw xmm0, xmm2      ; + offset    pmaxsw xmm1,xmm5
1029    paddw xmm3, xmm5  
1030      movdqa [edx],xmm0
1031    paddw xmm0, xmm1      ; start restoring sign    lea eax,[eax+32]
1032    paddw xmm3, xmm4    movdqa [edx+16],xmm1
1033    
1034   ; saturates to +2047    dec ecx
1035    movdqa xmm2, [sse2_2047]    lea edx,[edx+32]
1036    pminsw xmm0, xmm2    jne .loop
   add eax, 4  
   pminsw xmm3, xmm2  
   
   pxor xmm0, xmm1 ; finish restoring sign  
   pxor xmm3, xmm4  
   movdqa [edx + 8*16 - 8*4 + 8*eax], xmm0  
   movdqa [edx + 8*16 - 8*4 + 8*eax + 16], xmm3  
   jnz near .loop  
1037    
1038    xor eax, eax    xor eax, eax              ; return 0
1039    ret    ret
1040    .endfunc
1041    

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.7

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