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

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

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

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

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

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