[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 1424, Mon Apr 12 15:49:56 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.3 2004-04-12 15:49:56 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  
133    
134    xor ecx, ecx    mov esi, [esp + 4 + 8]     ; data
   cmp al, 1  
   jz .q1loop  
135    
136    movq mm7, [mmx_div + eax * 8 - 8]    movsx eax, word [esi]      ; data[0]
137    
138  ALIGN 16    mov ecx,[esp + 4 + 16]         ; dcscalar
139  .loop    mov edx,eax
140    movq mm0, [esi + 8*ecx]           ; mm0 = [1st]    sar ecx,1
141    movq mm3, [esi + 8*ecx + 8]    add eax,ecx
142    pxor mm1, mm1                     ; mm1 = 0    sub edx,ecx
143    pxor mm4, mm4                     ;    cmovl eax,edx             ; +/- dcscalar/2
144    pcmpgtw mm1, mm0                  ; mm1 = (0 > mm0)    mov ecx, [esp + 4 + 12]    ; quant
145    pcmpgtw mm4, mm3                  ;    cdq
146    pxor mm0, mm1                     ; mm0 = |mm0|    idiv dword [esp + 4 + 16]  ; dcscalar
147    pxor mm3, mm4                     ;    cmp ecx, 1
148    psubw mm0, mm1                    ; displace    mov edx, [esp + 4 + 4]     ; coeff
149    psubw mm3, mm4                    ;    je .low
   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  
150    
151    add ecx, 2    movq mm7, [mmx_div+ecx * 8 - 8]
152    cmp ecx, 16    mov ecx,4
   jnz .loop  
153    
154  .done  .loop
155      movq mm0, [esi]           ; data
156      pxor mm4,mm4
157      movq mm1, [esi + 8]
158      pcmpgtw mm4,mm0           ; (data<0)
159      pxor mm5,mm5
160      pmulhw mm0,mm7            ; /(2*quant)
161      pcmpgtw mm5,mm1
162      movq mm2, [esi+16]
163      psubw mm0,mm4             ;  +(data<0)
164      pmulhw mm1,mm7
165      pxor mm4,mm4
166      movq mm3,[esi+24]
167      pcmpgtw mm4,mm2
168      psubw mm1,mm5
169      pmulhw mm2,mm7
170      pxor mm5,mm5
171      pcmpgtw mm5,mm3
172      pmulhw mm3,mm7
173      psubw mm2,mm4
174      psubw mm3,mm5
175      movq [edx], mm0
176      lea esi, [esi+32]
177      movq [edx + 8], mm1
178      movq [edx + 16], mm2
179      movq [edx + 24], mm3
180    
181      dec ecx
182      lea edx, [edx+32]
183      jne .loop
184      jmp .end
185    
186    .low
187      movd mm7,ecx
188      mov ecx,4
189    .loop_low
190      movq mm0, [esi]
191      pxor mm4,mm4
192      movq mm1, [esi + 8]
193      pcmpgtw mm4,mm0
194      pxor mm5,mm5
195      psubw mm0,mm4
196      pcmpgtw mm5,mm1
197      psraw mm0,mm7
198      psubw mm1,mm5
199      movq mm2,[esi+16]
200      pxor mm4,mm4
201      psraw mm1,mm7
202      pcmpgtw mm4,mm2
203      pxor mm5,mm5
204      psubw mm2,mm4
205      movq mm3,[esi+24]
206      pcmpgtw mm5,mm3
207      psraw mm2,mm7
208      psubw mm3,mm5
209      movq [edx], mm0
210      psraw mm3,mm7
211      movq [edx + 8], mm1
212      movq [edx+16],mm2
213      lea esi, [esi+32]
214      movq [edx+24],mm3
215    
216      dec ecx
217      lea edx, [edx+32]
218      jne .loop_low
219    
220      ; caclulate  data[0] // (int32_t)dcscalar)  .end
221    mov ecx, [esp + 12 + 16]      ; dcscalar    mov edx, [esp + 4 + 4]     ; coeff
222    mov edx, ecx    mov [edx],ax
223    movsx eax, word [esi]         ; data[0]    xor eax,eax                ; return 0
   shr edx, 1                    ; edx = dcscalar /2  
   cmp eax, 0  
   jg .gtzero  
   
   sub eax, edx  
   jmp short .mul  
   
 .gtzero  
   add eax, edx  
 .mul  
   cdq ; expand eax -> edx:eax  
   idiv ecx          ; eax = edx:eax / dcscalar  
   mov [edi], ax     ; coeff[0] = ax  
224    
   xor eax, eax      ; return(0);  
   pop edi  
225    pop esi    pop esi
   pop ecx  
   
226    ret    ret
227    
 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  
   
   
228    
229  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
230  ;  ;
# Line 276  Line 240 
240  quant_h263_intra_sse2:  quant_h263_intra_sse2:
241    
242    push esi    push esi
   push edi  
243    
244    mov edi, [esp + 8 + 4]                ; coeff    mov esi, [esp + 4 + 8]     ; data
   mov esi, [esp + 8 + 8]                ; data  
   mov eax, [esp + 8 + 12]               ; quant  
245    
246    xor ecx, ecx    movsx eax, word [esi]      ; data[0]
247    cmp al, 1  
248    jz near .qas2_q1loop    mov ecx,[esp + 4 + 16]     ; dcscalar
249      mov edx,eax
250      sar ecx,1
251      add eax,ecx
252      sub edx,ecx
253      cmovl eax,edx              ; +/- dcscalar/2
254      mov ecx, [esp + 4 + 12]    ; quant
255      cdq
256      idiv dword [esp + 4 + 16]  ; dcscalar
257      cmp ecx, 1
258      mov edx, [esp + 4 + 4]     ; coeff
259      movq xmm7, [mmx_div+ecx * 8 - 8]
260      je .low
261    
262  .qas2_not1    mov ecx,2
   movq mm7, [mmx_div + eax*8 - 8]  
   movq2dq xmm7, mm7  
263    movlhps xmm7, xmm7    movlhps xmm7, xmm7
264    
265  ALIGN 16  .loop
266  .qas2_loop    movdqa xmm0, [esi]
   movdqa xmm0, [esi + ecx*8]                ; xmm0 = [1st]  
   movdqa xmm3, [esi + ecx*8 + 16]           ; xmm3 = [2nd]  
   pxor xmm1, xmm1  
267    pxor xmm4, xmm4    pxor xmm4, xmm4
268    pcmpgtw xmm1, xmm0    movdqa xmm1, [esi + 16]
269    pcmpgtw xmm4, xmm3    pcmpgtw xmm4,xmm0
270    pxor xmm0, xmm1    pxor xmm5,xmm5
   pxor xmm3, xmm4  
   psubw xmm0, xmm1  
   psubw xmm3, xmm4  
271    pmulhw xmm0, xmm7    pmulhw xmm0, xmm7
272      pcmpgtw xmm5,xmm1
273      movdqa xmm2, [esi+32]
274      psubw xmm0,xmm4
275      pmulhw xmm1,xmm7
276      pxor xmm4,xmm4
277      movdqa xmm3,[esi+48]
278      pcmpgtw xmm4,xmm2
279      psubw xmm1,xmm5
280      pmulhw xmm2,xmm7
281      pxor xmm5,xmm5
282      pcmpgtw xmm5,xmm3
283    pmulhw xmm3, xmm7    pmulhw xmm3, xmm7
284    pxor xmm0, xmm1    psubw xmm2,xmm4
285    pxor xmm3, xmm4    psubw xmm3,xmm5
286    psubw xmm0, xmm1    movdqa [edx], xmm0
287    psubw xmm3, xmm4    lea esi, [esi+64]
288    movdqa [edi + ecx*8], xmm0    movdqa [edx + 16], xmm1
289    movdqa [edi + ecx*8 + 16], xmm3    movdqa [edx + 32], xmm2
290      movdqa [edx + 48], xmm3
291    add ecx, 4  
292    cmp ecx, 16    dec ecx
293    jnz .qas2_loop    lea edx, [edx+64]
294      jne .loop
295  .qas2_done    jmp .end
296    mov ecx, [esp + 8 + 16]   ; dcscalar  
297    mov edx, ecx  .low
298    movsx eax, word [esi]    movd xmm7,ecx
299    shr edx, 1    mov ecx,2
300    cmp eax, 0  .loop_low
301    jg .qas2_gtzero    movdqa xmm0, [esi]
302      pxor xmm4,xmm4
303    sub eax, edx    movdqa xmm1, [esi + 16]
304    jmp short .qas2_mul    pcmpgtw xmm4,xmm0
305      pxor xmm5,xmm5
306  .qas2_gtzero    psubw xmm0,xmm4
307    add eax, edx    pcmpgtw xmm5,xmm1
308      psraw xmm0,xmm7
309  .qas2_mul    psubw xmm1,xmm5
310    cdq    movdqa xmm2,[esi+32]
311    idiv ecx    pxor xmm4,xmm4
312      psraw xmm1,xmm7
313      pcmpgtw xmm4,xmm2
314      pxor xmm5,xmm5
315      psubw xmm2,xmm4
316      movdqa xmm3,[esi+48]
317      pcmpgtw xmm5,xmm3
318      psraw xmm2,xmm7
319      psubw xmm3,xmm5
320      movdqa [edx], xmm0
321      psraw xmm3,xmm7
322      movdqa [edx+16], xmm1
323      movdqa [edx+32],xmm2
324      lea esi, [esi+64]
325      movdqa [edx+48],xmm3
326    
327      dec ecx
328      lea edx, [edx+64]
329      jne .loop_low
330    
331    mov [edi], ax  .end
332      mov edx, [esp + 4 + 4]     ; coeff
333      mov [edx],ax
334      xor eax,eax                ; return 0
335    
   xor eax, eax      ; return(0);  
   pop edi  
336    pop esi    pop esi
   
337    ret    ret
338    
 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  
   
   
   
339  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
340  ;  ;
341  ; uint32_t quant_h263_inter_mmx(int16_t * coeff,  ; uint32_t quant_h263_inter_mmx(int16_t * coeff,
# Line 598  Line 564 
564  ;  ;
565  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
566    
   ; note: we only saturate to +2047 *before* restoring the sign.  
   ; Hence, final clamp really is [-2048,2047]  
   
567  ALIGN 16  ALIGN 16
568  dequant_h263_intra_mmx:  dequant_h263_intra_mmx:
569    
570      mov ecx, [esp+12]                 ; quant
571      mov eax, [esp+ 8]                 ; coeff
572      pcmpeqw mm0,mm0
573      movq mm6, [mmx_quant + ecx*8]     ; quant
574      shl ecx,31                        ; quant & 1 ? 0 : - 1
575      movq mm7,mm6
576      movq mm5,mm0
577      movd mm1,ecx
578    mov edx, [esp+ 4]                 ; data    mov edx, [esp+ 4]                 ; data
579    mov ecx, [esp+ 8]                 ; coeff    psllw mm0,mm1
580    mov eax, [esp+12]                 ; quant    paddw mm7,mm7                     ; 2*quant
581    movq mm6, [mmx_add + eax*8 - 8]   ; quant or quant-1    paddw mm6,mm0                     ; quant-1
582    movq mm7, [mmx_mul + eax*8 - 8]   ; 2*quant    psllw mm5,12
583    mov eax, -16    mov ecx,8
584      psrlw mm5,1
585    
586  ALIGN 16  .loop:
587  .loop    movq mm0,[eax]
588    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  
589    pxor mm4, mm4    pxor mm4, mm4
590    pcmpgtw mm1, mm0                  ; sign(c)    pcmpgtw mm2,mm0
591    pcmpgtw mm4, mm3                  ; sign(c')    pcmpeqw mm4,mm0
592      pmullw mm0,mm7      ; * 2 * quant
593      movq mm1,[eax+8]
594      psubw mm0,mm2
595      pxor mm2,mm6
596      pxor mm3,mm3
597      pandn mm4,mm2
598    pxor mm2, mm2    pxor mm2, mm2
599    pxor mm5, mm5    pcmpgtw mm3,mm1
600    pcmpeqw mm2, mm0                  ; c is zero    pcmpeqw mm2,mm1
601    pcmpeqw mm5, mm3                  ; c' is zero    pmullw mm1,mm7
602    pandn mm2, mm6                    ; offset = isZero ? 0 : quant_add    paddw mm0,mm4
603    pandn mm5, mm6    psubw mm1,mm3
604    pxor mm0, mm1                     ; negate if negative    pxor mm3,mm6
605    pxor mm3, mm4                     ; negate if negative    pandn mm2,mm3
606    psubw mm0, mm1    paddsw mm0, mm5        ; saturate
607    psubw mm3, mm4    paddw mm1,mm2
608    pmullw mm0, mm7                   ; *= 2Q  
609    pmullw mm3, mm7                   ; *= 2Q    paddsw mm1, mm5
610    paddw mm0, mm2                    ; + offset    psubsw mm0, mm5
611    paddw mm3, mm5                    ; + offset    psubsw mm1, mm5
612    paddw mm0, mm1                    ; negate back    psubsw mm0, mm5
613    paddw mm3, mm4                    ; negate back    psubsw mm1, mm5
614      paddsw mm0, mm5
615    ; saturates to +2047    paddsw mm1, mm5
616    movq mm2, [mmx_32767_minus_2047]  
617    add eax, 2    movq [edx],mm0
618    paddsw mm0, mm2    lea eax,[eax+16]
619    paddsw mm3, mm2    movq [edx+8],mm1
620    psubsw mm0, mm2  
621    psubsw mm3, mm2    dec ecx
622      lea edx,[edx+16]
623    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  
624    
625   ; deal with DC   ; deal with DC
626    movd mm0, [ecx]    mov eax, [esp+ 8]                ; coeff
627    pmullw mm0, [esp+16]          ; dcscalar    movsx eax,word [eax]
628    movq mm2, [mmx_32767_minus_2047]    mov ecx,2047
629    paddsw mm0, mm2    imul dword [esp+16]              ; dcscalar
630    psubsw mm0, mm2    mov edx, [esp+ 4]                ; data
631    movq mm3, [mmx_32768_minus_2048]    cmp eax,ecx
632    psubsw mm0, mm3    cmovg eax,ecx
633    paddsw mm0, mm3    not ecx
634    movd eax, mm0    cmp eax,ecx
635      cmovl eax,ecx
636    
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      mov edx, [esp+ 4]                 ; data
715      movd mm0, [eax]
716    pmullw mm0, [esp+16]    ; dcscalar    pmullw mm0, [esp+16]    ; dcscalar
717    movq mm2, [mmx_32767_minus_2047]    pminsw mm0,mm4
718    paddsw mm0, mm2    pmaxsw mm0,mm5
   psubsw mm0, mm2  
   movq mm2, [mmx_32768_minus_2048]  
   psubsw mm0, mm2  
   paddsw mm0, mm2  
719    movd eax, mm0    movd eax, mm0
720    mov [edx], ax    mov [edx], ax
721    
722    xor eax, eax    xor eax, eax                      ; return 0
723    ret    ret
724    
725    
# Line 753  Line 735 
735    
736  ALIGN 16  ALIGN 16
737  dequant_h263_intra_sse2:  dequant_h263_intra_sse2:
738    
739      mov ecx, [esp+12]                 ; quant
740      mov eax, [esp+ 8]                 ; coeff
741    
742      movd xmm6,ecx                     ; quant
743    ;  shr ecx,1
744      shl ecx,31
745      pshuflw xmm6,xmm6,0
746      pcmpeqw xmm0,xmm0
747      movlhps xmm6,xmm6                 ; all quant
748      movd xmm1,ecx
749      movdqa xmm5,xmm0
750      movdqa xmm7,xmm6
751    mov edx, [esp+ 4]        ; data    mov edx, [esp+ 4]        ; data
752    mov ecx, [esp+ 8]        ; coeff    paddw xmm7,xmm7                   ; quant *2
753    mov eax, [esp+12]        ; quant    psllw xmm0,xmm1                   ; quant & 1 ? 0 : - 1
754    movq mm6, [mmx_add + eax * 8 - 8]    movdqa xmm4,xmm5
755    movq mm7, [mmx_mul + eax * 8 - 8]    paddw xmm6,xmm0                   ; quant-1
756    movq2dq xmm6, mm6    psrlw xmm4,5                      ; 2047
757    movq2dq xmm7, mm7    mov ecx,4
758    movlhps xmm6, xmm6    pxor xmm5,xmm4                    ; mm5=-2048
   movlhps xmm7, xmm7  
   mov eax, -16  
759    
760  ALIGN 16  .loop:
761  .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  
762    pxor xmm2, xmm2    pxor xmm2, xmm2
763    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  
764    
765    pxor xmm0, xmm1    pcmpgtw xmm2,xmm0
766    pxor xmm3, xmm4    pcmpeqw xmm3,xmm0
767    movdqa [edx + 8*16 - 8*4 + 8*eax], xmm0    pmullw xmm0,xmm7      ; * 2 * quant
768    movdqa [edx + 8*16 - 8*4 + 8*eax + 16], xmm3    movdqa xmm1,[eax+16]
769    jnz near .loop  
770      psubw xmm0,xmm2
771      pxor xmm2,xmm6
772      pandn xmm3,xmm2
773      pxor xmm2,xmm2
774      paddw xmm0,xmm3
775      pxor xmm3,xmm3
776      pcmpeqw xmm2,xmm1
777      pcmpgtw xmm3,xmm1
778      pmullw xmm1,xmm7
779    
780      pminsw xmm0,xmm4
781      psubw xmm1,xmm3
782      pxor xmm3,xmm6
783      pandn xmm2,xmm3
784      paddw xmm1,xmm2
785    
786      pmaxsw xmm0,xmm5
787      pminsw xmm1,xmm4
788      movdqa [edx],xmm0
789      pmaxsw xmm1,xmm5
790      lea eax,[eax+32]
791      movdqa [edx+16],xmm1
792    
793      dec ecx
794      lea edx,[edx+32]
795      jne .loop
796    
797   ; deal with DC   ; deal with DC
798    movd mm0, [ecx]  
799    pmullw mm0, [esp+16]    ; dcscalar    mov eax, [esp+ 8]             ; coeff
800    movq mm2, [mmx_32767_minus_2047]    movsx eax,word [eax]
801    paddsw mm0, mm2    imul dword [esp+16]            ; dcscalar
802    psubsw mm0, mm2    mov edx, [esp+ 4]              ; data
803    movq mm2, [mmx_32768_minus_2048]    movd xmm0,eax
804    psubsw mm0, mm2    pminsw xmm0,xmm4
805    paddsw mm0, mm2    pmaxsw xmm0,xmm5
806    movd eax, mm0    movd eax,xmm0
807    
808    mov [edx], ax    mov [edx], ax
809    
810    xor eax, eax    xor eax, eax              ; return 0
811    ret    ret
812    
813  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
# Line 828  Line 822 
822  ALIGN 16  ALIGN 16
823  dequant_h263_inter_mmx:  dequant_h263_inter_mmx:
824    
825      mov ecx, [esp+12]                 ; quant
826      mov eax, [esp+ 8]                 ; coeff
827      pcmpeqw mm0,mm0
828      movq mm6, [mmx_quant + ecx*8]     ; quant
829      shl ecx,31                        ; odd/even
830      movq mm7,mm6
831      movd mm1,ecx
832    mov edx, [esp+ 4]        ; data    mov edx, [esp+ 4]        ; data
833    mov ecx, [esp+ 8]        ; coeff    movq mm5,mm0
834    mov eax, [esp+12]        ; quant    psllw mm0,mm1                     ; quant & 1 ? 0 : - 1
835    movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1    paddw mm7,mm7                     ; quant*2
836    movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant    paddw mm6,mm0                     ; quant & 1 ? quant : quant - 1
837    mov eax, -16    psllw mm5,12
838      mov ecx,8
839      psrlw mm5,1                       ; 32767-2047 (32768-2048)
840    
841  ALIGN 16  .loop:
842  .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  
843    pxor mm4, mm4    pxor mm4, mm4
   pcmpgtw mm1, mm0  ; sign(c)  
   pcmpgtw mm4, mm3  ; sign(c')  
844    pxor mm2, mm2    pxor mm2, mm2
845    pxor mm5, mm5    pcmpeqw mm4,mm0     ; if coeff==0...
846    pcmpeqw mm2, mm0  ; c is zero    pcmpgtw mm2,mm0
847    pcmpeqw mm5, mm3  ; c' is zero    pmullw mm0,mm7      ; * 2 * quant
848    pandn mm2, mm6    ; offset = isZero ? 0 : quant_add    pxor mm3,mm3
849    pandn mm5, mm6    psubw mm0,mm2
850    pxor mm0, mm1     ; negate if negative    movq mm1,[eax+8]
851    pxor mm3, mm4     ; negate if negative    pxor mm2,mm6
852    psubw mm0, mm1    pcmpgtw mm3,mm1
853    psubw mm3, mm4    pandn mm4,mm2      ; ... then data==0
854    pmullw mm0, mm7   ; *= 2Q    pmullw mm1,mm7
855    pmullw mm3, mm7   ; *= 2Q    pxor mm2,mm2
856    paddw mm0, mm2    ; + offset    pcmpeqw mm2,mm1
857    paddw mm3, mm5    ; + offset    psubw mm1,mm3
858    paddw mm0, mm1    ; negate back    pxor mm3,mm6
859    paddw mm3, mm4    ; negate back    pandn mm2,mm3
860    ; saturates to +2047    paddw mm0,mm4
861    movq mm2, [mmx_32767_minus_2047]    paddw mm1,mm2
862    add eax, 2  
863    paddsw mm0, mm2    paddsw mm0, mm5        ; saturate
864    paddsw mm3, mm2    paddsw mm1, mm5
865    psubsw mm0, mm2    psubsw mm0, mm5
866    psubsw mm3, mm2    psubsw mm1, mm5
867      psubsw mm0, mm5
868    pxor mm0, mm1    psubsw mm1, mm5
869    pxor mm3, mm4    paddsw mm0, mm5
870    movq [edx + 8*eax + 8*16   - 2*8], mm0    paddsw mm1, mm5
871    movq [edx + 8*eax + 8*16+8 - 2*8], mm3  
872    jnz near .loop    movq [edx],mm0
873      lea eax,[eax+16]
874      movq [edx+8],mm1
875    
876      dec ecx
877      lea edx,[edx+16]
878      jne .loop
879    
880    xor eax, eax    xor eax, eax              ; return 0
881    ret    ret
882    
883    
884  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
885  ;  ;
886  ; uint32_t dequant_h263_inter_xmm(int16_t * data,  ; uint32_t dequant_h263_inter_xmm(int16_t * data,
# Line 884  Line 889 
889  ;                                 const uint16_t *mpeg_matrices);  ;                                 const uint16_t *mpeg_matrices);
890  ;  ;
891  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
   
   ; this is the same as dequant_inter_mmx,  
   ; except that we're saturating using 'pminsw' (saves 2 cycles/loop)  
   
892  ALIGN 16  ALIGN 16
893  dequant_h263_inter_xmm:  dequant_h263_inter_xmm:
894    
895      mov ecx, [esp+12]                 ; quant
896      mov eax, [esp+ 8]                 ; coeff
897      pcmpeqw mm0,mm0
898      movq mm6, [mmx_quant + ecx*8]     ; quant
899      shl ecx,31
900      movq mm5,mm0
901      movd mm1,ecx
902      movq mm7,mm6
903      psllw mm0,mm1
904    mov edx, [esp+ 4]        ; data    mov edx, [esp+ 4]        ; data
905    mov ecx, [esp+ 8]        ; coeff    movq mm4,mm5
906    mov eax, [esp+12]        ; quant    paddw mm7,mm7
907    movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1    paddw mm6,mm0                     ; quant-1
908    movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant  
909    mov eax, -16    psrlw mm4,5
910      mov ecx,8
911  ALIGN 16    pxor mm5,mm4                      ; mm5=-2048
912  .loop  
913    movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]  .loop:
914    movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]    movq mm0,[eax]
915    pxor mm1, mm1    pxor mm3,mm3
   pxor mm4, mm4  
   pcmpgtw mm1, mm0  ; sign(c)  
   pcmpgtw mm4, mm3  ; sign(c')  
916    pxor mm2, mm2    pxor mm2, mm2
917    pxor mm5, mm5    pcmpeqw mm3,mm0
918    pcmpeqw mm2, mm0  ; c is zero    pcmpgtw mm2,mm0
919    pcmpeqw mm5, mm3  ; c' is zero    pmullw mm0,mm7                    ; * 2 * quant
920    pandn mm2, mm6    ; offset = isZero ? 0 : quant_add    pandn mm3,mm6
921    pandn mm5, mm6    movq mm1,[eax+8]
922    pxor mm0, mm1     ; negate if negative    psubw mm0,mm2
923    pxor mm3, mm4     ; negate if negative    pxor mm2,mm3
924    psubw mm0, mm1    pxor mm3,mm3
925    psubw mm3, mm4    paddw mm0,mm2
926    pmullw mm0, mm7   ; *= 2Q    pxor mm2,mm2
927    pmullw mm3, mm7   ; *= 2Q    pcmpgtw mm3,mm1
928    paddw mm0, mm2    ; + offset    pcmpeqw mm2,mm1
929    paddw mm3, mm5    ; + offset    pmullw mm1,mm7
930    paddw mm0, mm1    ; start restoring sign    pandn mm2,mm6
931    paddw mm3, mm4    ; start restoring sign    psubw mm1,mm3
932                              ; saturates to +2047    pxor mm3,mm2
933    movq mm2, [mmx_2047]    paddw mm1,mm3
934    pminsw mm0, mm2  
935    add eax, 2    pminsw mm0,mm4
936    pminsw mm3, mm2    pminsw mm1,mm4
937      pmaxsw mm0,mm5
938    pxor mm0, mm1 ; finish restoring sign    pmaxsw mm1,mm5
939    pxor mm3, mm4 ; finish restoring sign  
940    movq [edx + 8*eax + 8*16   - 2*8], mm0    movq [edx],mm0
941    movq [edx + 8*eax + 8*16+8 - 2*8], mm3    lea eax,[eax+16]
942    jnz near .loop    movq [edx+8],mm1
943    
944      dec ecx
945      lea edx,[edx+16]
946      jne .loop
947    
948    xor eax, eax    xor eax, eax              ; return 0
949    ret    ret
950    
951    
952  ;-----------------------------------------------------------------------------  ;-----------------------------------------------------------------------------
953  ;  ;
954  ; uint32_t dequant_h263_inter_sse2(int16_t * data,  ; uint32_t dequant_h263_inter_sse2(int16_t * data,
# Line 948  Line 960 
960    
961  ALIGN 16  ALIGN 16
962  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  
963    
964  ALIGN 16    mov ecx, [esp+12]                 ; quant
965  .loop    mov eax, [esp+ 8]                 ; coeff
   movdqa xmm0, [ecx + 8*16 + 8*eax]  ; c  = coeff[i]  
   movdqa xmm3, [ecx + 8*16 + 8*eax + 16]  
966    
967    pxor xmm1, xmm1    movq xmm6, [mmx_quant + ecx*8]    ; quant
968    pxor xmm4, xmm4    inc ecx
969    pcmpgtw xmm1, xmm0    ; sign(c)    pcmpeqw xmm5,xmm5
970    pcmpgtw xmm4, xmm3    and ecx,1
971      movlhps xmm6,xmm6
972      movd xmm0,ecx
973      movdqa xmm7,xmm6
974      pshuflw xmm0,xmm0,0
975      movdqa xmm4,xmm5
976      mov edx, [esp+ 4]                 ; data
977      movlhps xmm0,xmm0
978      paddw xmm7,xmm7
979      psubw xmm6,xmm0
980      psrlw xmm4,5   ; 2047
981      mov ecx,4
982      pxor xmm5,xmm4 ; mm5=-2048
983    
984    .loop:
985      movdqa xmm0,[eax]
986      pxor xmm3,xmm3
987    pxor xmm2, xmm2    pxor xmm2, xmm2
988    pxor xmm5, xmm5    pcmpeqw xmm3,xmm0
989    pcmpeqw xmm2, xmm0    ; c is zero    pcmpgtw xmm2,xmm0
990    pcmpeqw xmm5, xmm3    pmullw xmm0,xmm7      ; * 2 * quant
991      pandn xmm3,xmm6
992      movdqa xmm1,[eax+16]
993      psubw xmm0,xmm2
994      pxor xmm2,xmm3
995      pxor xmm3,xmm3
996      paddw xmm0,xmm2
997      pxor xmm2,xmm2
998      pcmpgtw xmm3,xmm1
999      pcmpeqw xmm2,xmm1
1000      pmullw xmm1,xmm7
1001    pandn xmm2, xmm6    pandn xmm2, xmm6
1002    pandn xmm5, xmm6    psubw xmm1,xmm3
1003    pxor xmm0, xmm1       ; negate if negative    pxor xmm3,xmm2
1004    pxor xmm3, xmm4    paddw xmm1,xmm3
1005    psubw xmm0, xmm1  
1006    psubw xmm3, xmm4    pminsw xmm0,xmm4
1007    pmullw xmm0, xmm7     ; *= 2Q    pminsw xmm1,xmm4
1008    pmullw xmm3, xmm7    pmaxsw xmm0,xmm5
1009    paddw xmm0, xmm2      ; + offset    pmaxsw xmm1,xmm5
1010    paddw xmm3, xmm5  
1011      movdqa [edx],xmm0
1012    paddw xmm0, xmm1      ; start restoring sign    lea eax,[eax+32]
1013    paddw xmm3, xmm4    movdqa [edx+16],xmm1
1014    
1015   ; saturates to +2047    dec ecx
1016    movdqa xmm2, [sse2_2047]    lea edx,[edx+32]
1017    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  
1018    
1019    xor eax, eax    xor eax, eax              ; return 0
1020    ret    ret
1021    

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

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