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

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

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

revision 1.1, Tue Oct 7 13:02:35 2003 UTC revision 1.1.2.4, Mon Nov 3 15:51:50 2003 UTC
# Line 0  Line 1 
1    ;/*****************************************************************************
2    ; *
3    ; *  XVID MPEG-4 VIDEO CODEC
4    ; *  - MPEG4 Quantization H263 implementation / MMX optimized -
5    ; *
6    ; *  Copyright(C) 2001-2003 Peter Ross <pross@xvid.org>
7    ; *               2002-2003 Pascal Massimino <skal@planet-d.net>
8    ; *
9    ; *  This program is free software ; you can redistribute it and/or modify
10    ; *  it under the terms of the GNU General Public License as published by
11    ; *  the Free Software Foundation ; either version 2 of the License, or
12    ; *  (at your option) any later version.
13    ; *
14    ; *  This program is distributed in the hope that it will be useful,
15    ; *  but WITHOUT ANY WARRANTY ; without even the implied warranty of
16    ; *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    ; *  GNU General Public License for more details.
18    ; *
19    ; *  You should have received a copy of the GNU General Public License
20    ; *  along with this program ; if not, write to the Free Software
21    ; *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
22    ; *
23    ; * $Id$
24    ; *
25    ; ****************************************************************************/
26    
27    ; enable dequant saturate [-2048,2047], test purposes only.
28    %define SATURATE
29    
30    BITS 32
31    
32    %macro cglobal 1
33           %ifdef PREFIX
34                    global _%1
35                    %define %1 _%1
36            %else
37                    global %1
38            %endif
39    %endmacro
40    
41    ;=============================================================================
42    ; Read only Local data
43    ;=============================================================================
44    
45    %ifdef FORMAT_COFF
46    SECTION .rodata data
47    %else
48    SECTION .rodata data align=16
49    %endif
50    
51    ALIGN 16
52    plus_one:
53            times 8 dw 1
54    
55    ;-----------------------------------------------------------------------------
56    ;
57    ; subtract by Q/2 table
58    ;
59    ;-----------------------------------------------------------------------------
60    
61    ALIGN 16
62    mmx_sub:
63    %assign quant 1
64    %rep 31
65            times 4 dw  quant / 2
66            %assign quant quant+1
67    %endrep
68    
69    ;-----------------------------------------------------------------------------
70    ;
71    ; divide by 2Q table
72    ;
73    ; use a shift of 16 to take full advantage of _pmulhw_
74    ; for q=1, _pmulhw_ will overflow so it is treated seperately
75    ; (3dnow2 provides _pmulhuw_ which wont cause overflow)
76    ;
77    ;-----------------------------------------------------------------------------
78    
79    ALIGN 16
80    mmx_div:
81    %assign quant 1
82    %rep 31
83            times 4 dw  (1<<16) / (quant*2) + 1
84            %assign quant quant+1
85    %endrep
86    
87    ;-----------------------------------------------------------------------------
88    ;
89    ; add by (odd(Q) ? Q : Q - 1) table
90    ;
91    ;-----------------------------------------------------------------------------
92    
93    ALIGN 16
94    mmx_add:
95    %assign quant 1
96    %rep 31
97            %if quant % 2 != 0
98            times 4 dw  quant
99            %else
100            times 4 dw quant - 1
101            %endif
102            %assign quant quant+1
103    %endrep
104    
105    ;-----------------------------------------------------------------------------
106    ;
107    ; multiple by 2Q table
108    ;
109    ;-----------------------------------------------------------------------------
110    
111    ALIGN 16
112    mmx_mul:
113    %assign quant 1
114    %rep 31
115            times 4 dw  quant*2
116            %assign quant quant+1
117    %endrep
118    
119    ;-----------------------------------------------------------------------------
120    ;
121    ; saturation limits
122    ;
123    ;-----------------------------------------------------------------------------
124    
125    ALIGN 16
126    sse2_2047:
127            times 8 dw 2047
128    
129    ALIGN 16
130    mmx_2047:
131            times 4 dw 2047
132    
133    ALIGN 8
134    mmx_32768_minus_2048:
135            times 4 dw (32768-2048)
136    
137    mmx_32767_minus_2047:
138            times 4 dw (32767-2047)
139    
140    
141    ;=============================================================================
142    ; Code
143    ;=============================================================================
144    
145    SECTION .text
146    
147    cglobal quant_h263_intra_mmx
148    cglobal quant_h263_intra_sse2
149    cglobal quant_h263_inter_mmx
150    cglobal quant_h263_inter_sse2
151    cglobal dequant_h263_intra_mmx
152    cglobal dequant_h263_intra_xmm
153    cglobal dequant_h263_intra_sse2
154    cglobal dequant_h263_inter_mmx
155    cglobal dequant_h263_inter_xmm
156    cglobal dequant_h263_inter_sse2
157    
158    ;-----------------------------------------------------------------------------
159    ;
160    ; uint32_t quant_h263_intra_mmx(int16_t * coeff,
161    ;                               const int16_t const * data,
162    ;                               const uint32_t quant,
163    ;                               const uint32_t dcscalar);
164    ;
165    ;-----------------------------------------------------------------------------
166    
167    ALIGN 16
168    quant_h263_intra_mmx:
169    
170      push ecx
171      push esi
172      push edi
173    
174      mov edi, [esp + 12 + 4]     ; coeff
175      mov esi, [esp + 12 + 8]     ; data
176      mov eax, [esp + 12 + 12]    ; quant
177    
178      xor ecx, ecx
179      cmp al, 1
180      jz .q1loop
181    
182      movq mm7, [mmx_div + eax * 8 - 8]
183    
184    ALIGN 16
185    .loop
186      movq mm0, [esi + 8*ecx]           ; mm0 = [1st]
187      movq mm3, [esi + 8*ecx + 8]
188      pxor mm1, mm1                     ; mm1 = 0
189      pxor mm4, mm4                     ;
190      pcmpgtw mm1, mm0                  ; mm1 = (0 > mm0)
191      pcmpgtw mm4, mm3                  ;
192      pxor mm0, mm1                     ; mm0 = |mm0|
193      pxor mm3, mm4                     ;
194      psubw mm0, mm1                    ; displace
195      psubw mm3, mm4                    ;
196      pmulhw mm0, mm7                   ; mm0 = (mm0 / 2Q) >> 16
197      pmulhw mm3, mm7                   ;
198      pxor mm0, mm1                     ; mm0 *= sign(mm0)
199      pxor mm3, mm4                     ;
200      psubw mm0, mm1                    ; undisplace
201      psubw mm3, mm4                    ;
202      movq [edi + 8*ecx], mm0
203      movq [edi + 8*ecx + 8], mm3
204    
205      add ecx, 2
206      cmp ecx, 16
207      jnz .loop
208    
209    .done
210    
211        ; caclulate  data[0] // (int32_t)dcscalar)
212      mov ecx, [esp + 12 + 16]      ; dcscalar
213      mov edx, ecx
214      movsx eax, word [esi]         ; data[0]
215      shr edx, 1                    ; edx = dcscalar /2
216      cmp eax, 0
217      jg .gtzero
218    
219      sub eax, edx
220      jmp short .mul
221    
222    .gtzero
223      add eax, edx
224    .mul
225      cdq ; expand eax -> edx:eax
226      idiv ecx          ; eax = edx:eax / dcscalar
227      mov [edi], ax     ; coeff[0] = ax
228    
229      xor eax, eax      ; return(0);
230      pop edi
231      pop esi
232      pop ecx
233    
234      ret
235    
236    ALIGN 16
237    .q1loop
238      movq mm0, [esi + 8*ecx]           ; mm0 = [1st]
239      movq mm3, [esi + 8*ecx + 8]
240      pxor mm1, mm1                     ; mm1 = 0
241      pxor mm4, mm4                     ;
242      pcmpgtw mm1, mm0                  ; mm1 = (0 > mm0)
243      pcmpgtw mm4, mm3                  ;
244      pxor mm0, mm1                     ; mm0 = |mm0|
245      pxor mm3, mm4                     ;
246      psubw mm0, mm1                    ; displace
247      psubw mm3, mm4                    ;
248      psrlw mm0, 1                      ; mm0 >>= 1   (/2)
249      psrlw mm3, 1                      ;
250      pxor mm0, mm1                     ; mm0 *= sign(mm0)
251      pxor mm3, mm4
252      psubw mm0, mm1                    ; undisplace
253      psubw mm3, mm4                    ;
254      movq [edi + 8*ecx], mm0
255      movq [edi + 8*ecx + 8], mm3
256    
257      add ecx, 2
258      cmp ecx, 16
259      jnz .q1loop
260      jmp short .done
261    
262    
263    
264    ;-----------------------------------------------------------------------------
265    ;
266    ; uint32_t quant_h263_intra_sse2(int16_t * coeff,
267    ;                                const int16_t const * data,
268    ;                                const uint32_t quant,
269    ;                                const uint32_t dcscalar);
270    ;
271    ;-----------------------------------------------------------------------------
272    
273    ALIGN 16
274    quant_h263_intra_sse2:
275    
276      push esi
277      push edi
278    
279      mov edi, [esp + 8 + 4]                ; coeff
280      mov esi, [esp + 8 + 8]                ; data
281      mov eax, [esp + 8 + 12]               ; quant
282    
283      xor ecx, ecx
284      cmp al, 1
285      jz near .qas2_q1loop
286    
287    .qas2_not1
288      movq mm7, [mmx_div + eax*8 - 8]
289      movq2dq xmm7, mm7
290      movlhps xmm7, xmm7
291    
292    ALIGN 16
293    .qas2_loop
294      movdqa xmm0, [esi + ecx*8]                ; xmm0 = [1st]
295      movdqa xmm3, [esi + ecx*8 + 16]           ; xmm3 = [2nd]
296      pxor xmm1, xmm1
297      pxor xmm4, xmm4
298      pcmpgtw xmm1, xmm0
299      pcmpgtw xmm4, xmm3
300      pxor xmm0, xmm1
301      pxor xmm3, xmm4
302      psubw xmm0, xmm1
303      psubw xmm3, xmm4
304      pmulhw xmm0, xmm7
305      pmulhw xmm3, xmm7
306      pxor xmm0, xmm1
307      pxor xmm3, xmm4
308      psubw xmm0, xmm1
309      psubw xmm3, xmm4
310      movdqa [edi + ecx*8], xmm0
311      movdqa [edi + ecx*8 + 16], xmm3
312    
313      add ecx, 4
314      cmp ecx, 16
315      jnz .qas2_loop
316    
317    .qas2_done
318      mov ecx, [esp + 8 + 16]   ; dcscalar
319      mov edx, ecx
320      movsx eax, word [esi]
321      shr edx, 1
322      cmp eax, 0
323      jg .qas2_gtzero
324    
325      sub eax, edx
326      jmp short .qas2_mul
327    
328    .qas2_gtzero
329      add eax, edx
330    
331    .qas2_mul
332      cdq
333      idiv ecx
334    
335      mov [edi], ax
336    
337      xor eax, eax      ; return(0);
338      pop edi
339      pop esi
340    
341      ret
342    
343    ALIGN 16
344    .qas2_q1loop
345      movdqa xmm0, [esi + ecx*8]         ; xmm0 = [1st]
346      movdqa xmm3, [esi + ecx*8 + 16]    ; xmm3 = [2nd]
347      pxor xmm1, xmm1
348      pxor xmm4, xmm4
349      pcmpgtw xmm1, xmm0
350      pcmpgtw xmm4, xmm3
351      pxor xmm0, xmm1
352      pxor xmm3, xmm4
353      psubw xmm0, xmm1
354      psubw xmm3, xmm4
355      psrlw xmm0, 1
356      psrlw xmm3, 1
357      pxor xmm0, xmm1
358      pxor xmm3, xmm4
359      psubw xmm0, xmm1
360      psubw xmm3, xmm4
361      movdqa [edi + ecx*8], xmm0
362      movdqa [edi + ecx*8 + 16], xmm3
363    
364      add ecx, 4
365      cmp ecx, 16
366      jnz .qas2_q1loop
367      jmp near .qas2_done
368    
369    
370    
371    ;-----------------------------------------------------------------------------
372    ;
373    ; uint32_t quant_h263_inter_mmx(int16_t * coeff,
374    ;                               const int16_t const * data,
375    ;                               const uint32_t quant);
376    ;
377    ;-----------------------------------------------------------------------------
378    
379    ALIGN 16
380    quant_h263_inter_mmx:
381    
382      push ecx
383      push esi
384      push edi
385    
386      mov edi, [esp + 12 + 4]           ; coeff
387      mov esi, [esp + 12 + 8]           ; data
388      mov eax, [esp + 12 + 12]          ; quant
389    
390      xor ecx, ecx
391    
392      pxor mm5, mm5                     ; sum
393      movq mm6, [mmx_sub + eax * 8 - 8] ; sub
394    
395      cmp al, 1
396      jz .q1loop
397    
398      movq mm7, [mmx_div + eax * 8 - 8] ; divider
399    
400    ALIGN 8
401    .loop
402      movq mm0, [esi + 8*ecx]           ; mm0 = [1st]
403      movq mm3, [esi + 8*ecx + 8]
404      pxor mm1, mm1                     ; mm1 = 0
405      pxor mm4, mm4                     ;
406      pcmpgtw mm1, mm0                  ; mm1 = (0 > mm0)
407      pcmpgtw mm4, mm3                  ;
408      pxor mm0, mm1                     ; mm0 = |mm0|
409      pxor mm3, mm4                     ;
410      psubw mm0, mm1                    ; displace
411      psubw mm3, mm4                    ;
412      psubusw mm0, mm6                  ; mm0 -= sub (unsigned, dont go < 0)
413      psubusw mm3, mm6                  ;
414      pmulhw mm0, mm7                   ; mm0 = (mm0 / 2Q) >> 16
415      pmulhw mm3, mm7                   ;
416      paddw mm5, mm0                    ; sum += mm0
417      pxor mm0, mm1                     ; mm0 *= sign(mm0)
418      paddw mm5, mm3                    ;
419      pxor mm3, mm4                     ;
420      psubw mm0, mm1                    ; undisplace
421      psubw mm3, mm4
422      movq [edi + 8*ecx], mm0
423      movq [edi + 8*ecx + 8], mm3
424    
425      add ecx, 2
426      cmp ecx, 16
427      jnz .loop
428    
429    .done
430      pmaddwd mm5, [plus_one]
431      movq mm0, mm5
432      psrlq mm5, 32
433      paddd mm0, mm5
434    
435      movd eax, mm0     ; return sum
436      pop edi
437      pop esi
438      pop ecx
439    
440      ret
441    
442    ALIGN 8
443    .q1loop
444      movq mm0, [esi + 8*ecx]           ; mm0 = [1st]
445      movq mm3, [esi + 8*ecx+ 8]        ;
446      pxor mm1, mm1                     ; mm1 = 0
447      pxor mm4, mm4                     ;
448      pcmpgtw mm1, mm0                  ; mm1 = (0 > mm0)
449      pcmpgtw mm4, mm3                  ;
450      pxor mm0, mm1                     ; mm0 = |mm0|
451      pxor mm3, mm4                     ;
452      psubw mm0, mm1                    ; displace
453      psubw mm3, mm4                    ;
454      psubusw mm0, mm6                  ; mm0 -= sub (unsigned, dont go < 0)
455      psubusw mm3, mm6                  ;
456      psrlw mm0, 1                      ; mm0 >>= 1   (/2)
457      psrlw mm3, 1                      ;
458      paddw mm5, mm0                    ; sum += mm0
459      pxor mm0, mm1                     ; mm0 *= sign(mm0)
460      paddw mm5, mm3                    ;
461      pxor mm3, mm4                     ;
462      psubw mm0, mm1                    ; undisplace
463      psubw mm3, mm4
464      movq [edi + 8*ecx], mm0
465      movq [edi + 8*ecx + 8], mm3
466    
467      add ecx, 2
468      cmp ecx, 16
469      jnz .q1loop
470    
471      jmp .done
472    
473    
474    
475    ;-----------------------------------------------------------------------------
476    ;
477    ; uint32_t quant_h263_inter_sse2(int16_t * coeff,
478    ;                                const int16_t const * data,
479    ;                                const uint32_t quant);
480    ;
481    ;-----------------------------------------------------------------------------
482    
483    ALIGN 16
484    quant_h263_inter_sse2:
485    
486      push esi
487      push edi
488    
489      mov edi, [esp + 8 + 4]      ; coeff
490      mov esi, [esp + 8 + 8]      ; data
491      mov eax, [esp + 8 + 12]     ; quant
492    
493      xor ecx, ecx
494    
495      pxor xmm5, xmm5                           ; sum
496    
497      movq mm0, [mmx_sub + eax*8 - 8]           ; sub
498      movq2dq xmm6, mm0                         ; load into low 8 bytes
499      movlhps xmm6, xmm6                        ; duplicate into high 8 bytes
500    
501      cmp al, 1
502      jz near .qes2_q1loop
503    
504    .qes2_not1
505      movq mm0, [mmx_div + eax*8 - 8]           ; divider
506      movq2dq xmm7, mm0
507      movlhps xmm7, xmm7
508    
509    ALIGN 16
510    .qes2_loop
511      movdqa xmm0, [esi + ecx*8]                ; xmm0 = [1st]
512      movdqa xmm3, [esi + ecx*8 + 16]           ; xmm3 = [2nd]
513      pxor xmm1, xmm1
514      pxor xmm4, xmm4
515      pcmpgtw xmm1, xmm0
516      pcmpgtw xmm4, xmm3
517      pxor xmm0, xmm1
518      pxor xmm3, xmm4
519      psubw xmm0, xmm1
520      psubw xmm3, xmm4
521      psubusw xmm0, xmm6
522      psubusw xmm3, xmm6
523      pmulhw xmm0, xmm7
524      pmulhw xmm3, xmm7
525      paddw xmm5, xmm0
526      pxor xmm0, xmm1
527      paddw xmm5, xmm3
528      pxor xmm3, xmm4
529      psubw xmm0, xmm1
530      psubw xmm3, xmm4
531      movdqa [edi + ecx*8], xmm0
532      movdqa [edi + ecx*8 + 16], xmm3
533    
534      add ecx, 4
535      cmp ecx, 16
536      jnz .qes2_loop
537    
538    .qes2_done
539      movdqu xmm6, [plus_one]
540      pmaddwd xmm5, xmm6
541      movhlps xmm6, xmm5
542      paddd xmm5, xmm6
543      movdq2q mm0, xmm5
544    
545      movq mm5, mm0
546      psrlq mm5, 32
547      paddd mm0, mm5
548    
549      movd eax, mm0         ; return sum
550    
551      pop edi
552      pop esi
553    
554      ret
555    
556    ALIGN 16
557    .qes2_q1loop
558      movdqa xmm0, [esi + ecx*8]        ; xmm0 = [1st]
559      movdqa xmm3, [esi + ecx*8 + 16]   ; xmm3 = [2nd]
560      pxor xmm1, xmm1
561      pxor xmm4, xmm4
562      pcmpgtw xmm1, xmm0
563      pcmpgtw xmm4, xmm3
564      pxor xmm0, xmm1
565      pxor xmm3, xmm4
566      psubw xmm0, xmm1
567      psubw xmm3, xmm4
568      psubusw xmm0, xmm6
569      psubusw xmm3, xmm6
570      psrlw xmm0, 1
571      psrlw xmm3, 1
572      paddw xmm5, xmm0
573      pxor xmm0, xmm1
574      paddw xmm5, xmm3
575      pxor xmm3, xmm4
576      psubw xmm0, xmm1
577      psubw xmm3, xmm4
578      movdqa [edi + ecx*8], xmm0
579      movdqa [edi + ecx*8 + 16], xmm3
580    
581      add ecx, 4
582      cmp ecx, 16
583      jnz .qes2_q1loop
584      jmp .qes2_done
585    
586    
587    ;-----------------------------------------------------------------------------
588    ;
589    ; uint32_t dequant_h263_intra_mmx(int16_t *data,
590    ;                                 const int16_t const *coeff,
591    ;                                 const uint32_t quant,
592    ;                                 const uint32_t dcscalar);
593    ;
594    ;-----------------------------------------------------------------------------
595    
596      ; note: we only saturate to +2047 *before* restoring the sign.
597      ; Hence, final clamp really is [-2048,2047]
598    
599    ALIGN 16
600    dequant_h263_intra_mmx:
601    
602      mov edx, [esp+ 4]                 ; data
603      mov ecx, [esp+ 8]                 ; coeff
604      mov eax, [esp+12]                 ; quant
605      movq mm6, [mmx_add + eax*8 - 8]   ; quant or quant-1
606      movq mm7, [mmx_mul + eax*8 - 8]   ; 2*quant
607      mov eax, -16
608    
609    ALIGN 16
610    .loop
611      movq mm0, [ecx+8*eax+8*16]        ; c  = coeff[i]
612      movq mm3, [ecx+8*eax+8*16 + 8]    ; c' = coeff[i+1]
613      pxor mm1, mm1
614      pxor mm4, mm4
615      pcmpgtw mm1, mm0                  ; sign(c)
616      pcmpgtw mm4, mm3                  ; sign(c')
617      pxor mm2, mm2
618      pxor mm5, mm5
619      pcmpeqw mm2, mm0                  ; c is zero
620      pcmpeqw mm5, mm3                  ; c' is zero
621      pandn mm2, mm6                    ; offset = isZero ? 0 : quant_add
622      pandn mm5, mm6
623      pxor mm0, mm1                     ; negate if negative
624      pxor mm3, mm4                     ; negate if negative
625      psubw mm0, mm1
626      psubw mm3, mm4
627      pmullw mm0, mm7                   ; *= 2Q
628      pmullw mm3, mm7                   ; *= 2Q
629      paddw mm0, mm2                    ; + offset
630      paddw mm3, mm5                    ; + offset
631      paddw mm0, mm1                    ; negate back
632      paddw mm3, mm4                    ; negate back
633    
634      ; saturates to +2047
635      movq mm2, [mmx_32767_minus_2047]
636      add eax, 2
637      paddsw mm0, mm2
638      paddsw mm3, mm2
639      psubsw mm0, mm2
640      psubsw mm3, mm2
641    
642      pxor mm0, mm1
643      pxor mm3, mm4
644      movq [edx + 8*eax + 8*16   - 2*8], mm0
645      movq [edx + 8*eax + 8*16+8 - 2*8], mm3
646      jnz near .loop
647    
648     ; deal with DC
649      movd mm0, [ecx]
650      pmullw mm0, [esp+16]          ; dcscalar
651      movq mm2, [mmx_32767_minus_2047]
652      paddsw mm0, mm2
653      psubsw mm0, mm2
654      movq mm3, [mmx_32768_minus_2048]
655      psubsw mm0, mm3
656      paddsw mm0, mm3
657      movd eax, mm0
658      mov [edx], ax
659    
660      xor eax, eax              ; return(0);
661      ret
662    
663    ;-----------------------------------------------------------------------------
664    ;
665    ; uint32_t dequant_h263_intra_xmm(int16_t *data,
666    ;                                 const int16_t const *coeff,
667    ;                                 const uint32_t quant,
668    ;                                 const uint32_t dcscalar);
669    ;
670    ;-----------------------------------------------------------------------------
671    
672      ; this is the same as dequant_inter_mmx, except that we're
673      ; saturating using 'pminsw' (saves 2 cycles/loop => ~5% faster)
674    
675    ALIGN 16
676    dequant_h263_intra_xmm:
677    
678      mov edx, [esp+ 4]                 ; data
679      mov ecx, [esp+ 8]                 ; coeff
680      mov eax, [esp+12]                 ; quant
681      movq mm6, [mmx_add + eax*8 - 8]   ; quant or quant-1
682      movq mm7, [mmx_mul + eax*8 - 8]   ; 2*quant
683      mov eax, -16
684    
685    ALIGN 16
686    .loop
687      movq mm0, [ecx+8*eax+8*16]        ; c  = coeff[i]
688      movq mm3, [ecx+8*eax+8*16 + 8]    ; c' = coeff[i+1]
689      pxor mm1, mm1
690      pxor mm4, mm4
691      pcmpgtw mm1, mm0                  ; sign(c)
692      pcmpgtw mm4, mm3                  ; sign(c')
693      pxor mm2, mm2
694      pxor mm5, mm5
695      pcmpeqw mm2, mm0                  ; c is zero
696      pcmpeqw mm5, mm3                  ; c' is zero
697      pandn mm2, mm6                    ; offset = isZero ? 0 : quant_add
698      pandn mm5, mm6
699      pxor mm0, mm1                     ; negate if negative
700      pxor mm3, mm4                     ; negate if negative
701      psubw mm0, mm1
702      psubw mm3, mm4
703      pmullw mm0, mm7                   ; *= 2Q
704      pmullw mm3, mm7                   ; *= 2Q
705      paddw mm0, mm2                    ; + offset
706      paddw mm3, mm5                    ; + offset
707      paddw mm0, mm1                    ; negate back
708      paddw mm3, mm4                    ; negate back
709    
710       ; saturates to +2047
711      movq mm2, [mmx_2047]
712      pminsw mm0, mm2
713      add eax, 2
714      pminsw mm3, mm2
715    
716      pxor mm0, mm1
717      pxor mm3, mm4
718      movq [edx + 8*eax + 8*16   - 2*8], mm0
719      movq [edx + 8*eax + 8*16+8 - 2*8], mm3
720      jnz near .loop
721    
722        ; deal with DC
723      movd mm0, [ecx]
724      pmullw mm0, [esp+16]    ; dcscalar
725      movq mm2, [mmx_32767_minus_2047]
726      paddsw mm0, mm2
727      psubsw mm0, mm2
728      movq mm2, [mmx_32768_minus_2048]
729      psubsw mm0, mm2
730      paddsw mm0, mm2
731      movd eax, mm0
732      mov [edx], ax
733    
734      xor eax, eax
735      ret
736    
737    
738    ;-----------------------------------------------------------------------------
739    ;
740    ; uint32_t dequant_h263_intra_sse2(int16_t *data,
741    ;                                  const int16_t const *coeff,
742    ;                                  const uint32_t quant,
743    ;                                  const uint32_t dcscalar);
744    ;
745    ;-----------------------------------------------------------------------------
746    
747    ALIGN 16
748    dequant_h263_intra_sse2:
749      mov edx, [esp+ 4]        ; data
750      mov ecx, [esp+ 8]        ; coeff
751      mov eax, [esp+12]        ; quant
752      movq mm6, [mmx_add + eax * 8 - 8]
753      movq mm7, [mmx_mul + eax * 8 - 8]
754      movq2dq xmm6, mm6
755      movq2dq xmm7, mm7
756      movlhps xmm6, xmm6
757      movlhps xmm7, xmm7
758      mov eax, -16
759    
760    ALIGN 16
761    .loop
762      movdqa xmm0, [ecx + 8*16 + 8*eax]      ; c  = coeff[i]
763      movdqa xmm3, [ecx + 8*16 + 8*eax+ 16]
764      pxor xmm1, xmm1
765      pxor xmm4, xmm4
766      pcmpgtw xmm1, xmm0    ; sign(c)
767      pcmpgtw xmm4, xmm3
768      pxor xmm2, xmm2
769      pxor xmm5, xmm5
770      pcmpeqw xmm2, xmm0    ; c is zero
771      pcmpeqw xmm5, xmm3
772      pandn xmm2, xmm6      ; offset = isZero ? 0 : quant_add
773      pandn xmm5, xmm6
774      pxor xmm0, xmm1       ; negate if negative
775      pxor xmm3, xmm4
776      psubw xmm0, xmm1
777      psubw xmm3, xmm4
778      pmullw xmm0, xmm7     ; *= 2Q
779      pmullw xmm3, xmm7
780      paddw xmm0, xmm2      ; + offset
781      paddw xmm3, xmm5
782      paddw xmm0, xmm1      ; negate back
783      paddw xmm3, xmm4
784    
785        ; saturates to +2047
786      movdqa xmm2, [sse2_2047]
787      pminsw xmm0, xmm2
788      add eax, 4
789      pminsw xmm3, xmm2
790    
791      pxor xmm0, xmm1
792      pxor xmm3, xmm4
793      movdqa [edx + 8*16 - 8*4 + 8*eax], xmm0
794      movdqa [edx + 8*16 - 8*4 + 8*eax + 16], xmm3
795      jnz near .loop
796    
797     ; deal with DC
798      movd mm0, [ecx]
799      pmullw mm0, [esp+16]    ; dcscalar
800      movq mm2, [mmx_32767_minus_2047]
801      paddsw mm0, mm2
802      psubsw mm0, mm2
803      movq mm2, [mmx_32768_minus_2048]
804      psubsw mm0, mm2
805      paddsw mm0, mm2
806      movd eax, mm0
807      mov [edx], ax
808    
809      xor eax, eax
810      ret
811    
812    ;-----------------------------------------------------------------------------
813    ;
814    ; uint32t dequant_h263_inter_mmx(int16_t * data,
815    ;                                const int16_t * const coeff,
816    ;                                const uint32_t quant);
817    ;
818    ;-----------------------------------------------------------------------------
819    
820    ALIGN 16
821    dequant_h263_inter_mmx:
822    
823      mov edx, [esp+ 4]        ; data
824      mov ecx, [esp+ 8]        ; coeff
825      mov eax, [esp+12]        ; quant
826      movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1
827      movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant
828      mov eax, -16
829    
830    ALIGN 16
831    .loop
832      movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]
833      movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]
834      pxor mm1, mm1
835      pxor mm4, mm4
836      pcmpgtw mm1, mm0  ; sign(c)
837      pcmpgtw mm4, mm3  ; sign(c')
838      pxor mm2, mm2
839      pxor mm5, mm5
840      pcmpeqw mm2, mm0  ; c is zero
841      pcmpeqw mm5, mm3  ; c' is zero
842      pandn mm2, mm6    ; offset = isZero ? 0 : quant_add
843      pandn mm5, mm6
844      pxor mm0, mm1     ; negate if negative
845      pxor mm3, mm4     ; negate if negative
846      psubw mm0, mm1
847      psubw mm3, mm4
848      pmullw mm0, mm7   ; *= 2Q
849      pmullw mm3, mm7   ; *= 2Q
850      paddw mm0, mm2    ; + offset
851      paddw mm3, mm5    ; + offset
852      paddw mm0, mm1    ; negate back
853      paddw mm3, mm4    ; negate back
854      ; saturates to +2047
855      movq mm2, [mmx_32767_minus_2047]
856      add eax, 2
857      paddsw mm0, mm2
858      paddsw mm3, mm2
859      psubsw mm0, mm2
860      psubsw mm3, mm2
861    
862      pxor mm0, mm1
863      pxor mm3, mm4
864      movq [edx + 8*eax + 8*16   - 2*8], mm0
865      movq [edx + 8*eax + 8*16+8 - 2*8], mm3
866      jnz near .loop
867    
868      xor eax, eax
869      ret
870    
871    ;-----------------------------------------------------------------------------
872    ;
873    ; uint32_t dequant_h263_inter_xmm(int16_t * data,
874    ;                                 const int16_t * const coeff,
875    ;                                 const uint32_t quant);
876    ;
877    ;-----------------------------------------------------------------------------
878    
879      ; this is the same as dequant_inter_mmx,
880      ; except that we're saturating using 'pminsw' (saves 2 cycles/loop)
881    
882    ALIGN 16
883    dequant_h263_inter_xmm:
884    
885      mov edx, [esp+ 4]        ; data
886      mov ecx, [esp+ 8]        ; coeff
887      mov eax, [esp+12]        ; quant
888      movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1
889      movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant
890      mov eax, -16
891    
892    ALIGN 16
893    .loop
894      movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]
895      movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]
896      pxor mm1, mm1
897      pxor mm4, mm4
898      pcmpgtw mm1, mm0  ; sign(c)
899      pcmpgtw mm4, mm3  ; sign(c')
900      pxor mm2, mm2
901      pxor mm5, mm5
902      pcmpeqw mm2, mm0  ; c is zero
903      pcmpeqw mm5, mm3  ; c' is zero
904      pandn mm2, mm6    ; offset = isZero ? 0 : quant_add
905      pandn mm5, mm6
906      pxor mm0, mm1     ; negate if negative
907      pxor mm3, mm4     ; negate if negative
908      psubw mm0, mm1
909      psubw mm3, mm4
910      pmullw mm0, mm7   ; *= 2Q
911      pmullw mm3, mm7   ; *= 2Q
912      paddw mm0, mm2    ; + offset
913      paddw mm3, mm5    ; + offset
914      paddw mm0, mm1    ; start restoring sign
915      paddw mm3, mm4    ; start restoring sign
916                                ; saturates to +2047
917      movq mm2, [mmx_2047]
918      pminsw mm0, mm2
919      add eax, 2
920      pminsw mm3, mm2
921    
922      pxor mm0, mm1 ; finish restoring sign
923      pxor mm3, mm4 ; finish restoring sign
924      movq [edx + 8*eax + 8*16   - 2*8], mm0
925      movq [edx + 8*eax + 8*16+8 - 2*8], mm3
926      jnz near .loop
927    
928      xor eax, eax
929      ret
930    
931    ;-----------------------------------------------------------------------------
932    ;
933    ; uint32_t dequant_h263_inter_sse2(int16_t * data,
934    ;                                  const int16_t * const coeff,
935    ;                                  const uint32_t quant);
936    ;
937    ;-----------------------------------------------------------------------------
938    
939    ALIGN 16
940    dequant_h263_inter_sse2:
941      mov edx, [esp + 4]    ; data
942      mov ecx, [esp + 8]    ; coeff
943      mov eax, [esp + 12]   ; quant
944      movq mm6, [mmx_add + eax * 8 - 8]
945      movq mm7, [mmx_mul + eax * 8 - 8]
946      movq2dq xmm6, mm6
947      movq2dq xmm7, mm7
948      movlhps xmm6, xmm6
949      movlhps xmm7, xmm7
950      mov eax, -16
951    
952    ALIGN 16
953    .loop
954      movdqa xmm0, [ecx + 8*16 + 8*eax]  ; c  = coeff[i]
955      movdqa xmm3, [ecx + 8*16 + 8*eax + 16]
956    
957      pxor xmm1, xmm1
958      pxor xmm4, xmm4
959      pcmpgtw xmm1, xmm0    ; sign(c)
960      pcmpgtw xmm4, xmm3
961      pxor xmm2, xmm2
962      pxor xmm5, xmm5
963      pcmpeqw xmm2, xmm0    ; c is zero
964      pcmpeqw xmm5, xmm3
965      pandn xmm2, xmm6
966      pandn xmm5, xmm6
967      pxor xmm0, xmm1       ; negate if negative
968      pxor xmm3, xmm4
969      psubw xmm0, xmm1
970      psubw xmm3, xmm4
971      pmullw xmm0, xmm7     ; *= 2Q
972      pmullw xmm3, xmm7
973      paddw xmm0, xmm2      ; + offset
974      paddw xmm3, xmm5
975    
976      paddw xmm0, xmm1      ; start restoring sign
977      paddw xmm3, xmm4
978    
979     ; saturates to +2047
980      movdqa xmm2, [sse2_2047]
981      pminsw xmm0, xmm2
982      add eax, 4
983      pminsw xmm3, xmm2
984    
985      pxor xmm0, xmm1 ; finish restoring sign
986      pxor xmm3, xmm4
987      movdqa [edx + 8*16 - 8*4 + 8*eax], xmm0
988      movdqa [edx + 8*16 - 8*4 + 8*eax + 16], xmm3
989      jnz near .loop
990    
991      xor eax, eax
992      ret

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.1.2.4

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