[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.2, Mon Mar 22 22:36:24 2004 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    ;                               const uint16_t *mpeg_matrices);
165    ;
166    ;-----------------------------------------------------------------------------
167    
168    ALIGN 16
169    quant_h263_intra_mmx:
170    
171      push ecx
172      push esi
173      push edi
174    
175      mov edi, [esp + 12 + 4]     ; coeff
176      mov esi, [esp + 12 + 8]     ; data
177      mov eax, [esp + 12 + 12]    ; quant
178    
179      xor ecx, ecx
180      cmp al, 1
181      jz .q1loop
182    
183      movq mm7, [mmx_div + eax * 8 - 8]
184    
185    ALIGN 16
186    .loop
187      movq mm0, [esi + 8*ecx]           ; mm0 = [1st]
188      movq mm3, [esi + 8*ecx + 8]
189      pxor mm1, mm1                     ; mm1 = 0
190      pxor mm4, mm4                     ;
191      pcmpgtw mm1, mm0                  ; mm1 = (0 > mm0)
192      pcmpgtw mm4, mm3                  ;
193      pxor mm0, mm1                     ; mm0 = |mm0|
194      pxor mm3, mm4                     ;
195      psubw mm0, mm1                    ; displace
196      psubw mm3, mm4                    ;
197      pmulhw mm0, mm7                   ; mm0 = (mm0 / 2Q) >> 16
198      pmulhw mm3, mm7                   ;
199      pxor mm0, mm1                     ; mm0 *= sign(mm0)
200      pxor mm3, mm4                     ;
201      psubw mm0, mm1                    ; undisplace
202      psubw mm3, mm4                    ;
203      movq [edi + 8*ecx], mm0
204      movq [edi + 8*ecx + 8], mm3
205    
206      add ecx, 2
207      cmp ecx, 16
208      jnz .loop
209    
210    .done
211    
212        ; caclulate  data[0] // (int32_t)dcscalar)
213      mov ecx, [esp + 12 + 16]      ; dcscalar
214      mov edx, ecx
215      movsx eax, word [esi]         ; data[0]
216      shr edx, 1                    ; edx = dcscalar /2
217      cmp eax, 0
218      jg .gtzero
219    
220      sub eax, edx
221      jmp short .mul
222    
223    .gtzero
224      add eax, edx
225    .mul
226      cdq ; expand eax -> edx:eax
227      idiv ecx          ; eax = edx:eax / dcscalar
228      mov [edi], ax     ; coeff[0] = ax
229    
230      xor eax, eax      ; return(0);
231      pop edi
232      pop esi
233      pop ecx
234    
235      ret
236    
237    ALIGN 16
238    .q1loop
239      movq mm0, [esi + 8*ecx]           ; mm0 = [1st]
240      movq mm3, [esi + 8*ecx + 8]
241      pxor mm1, mm1                     ; mm1 = 0
242      pxor mm4, mm4                     ;
243      pcmpgtw mm1, mm0                  ; mm1 = (0 > mm0)
244      pcmpgtw mm4, mm3                  ;
245      pxor mm0, mm1                     ; mm0 = |mm0|
246      pxor mm3, mm4                     ;
247      psubw mm0, mm1                    ; displace
248      psubw mm3, mm4                    ;
249      psrlw mm0, 1                      ; mm0 >>= 1   (/2)
250      psrlw mm3, 1                      ;
251      pxor mm0, mm1                     ; mm0 *= sign(mm0)
252      pxor mm3, mm4
253      psubw mm0, mm1                    ; undisplace
254      psubw mm3, mm4                    ;
255      movq [edi + 8*ecx], mm0
256      movq [edi + 8*ecx + 8], mm3
257    
258      add ecx, 2
259      cmp ecx, 16
260      jnz .q1loop
261      jmp short .done
262    
263    
264    
265    ;-----------------------------------------------------------------------------
266    ;
267    ; uint32_t quant_h263_intra_sse2(int16_t * coeff,
268    ;                                const int16_t const * data,
269    ;                                const uint32_t quant,
270    ;                                const uint32_t dcscalar,
271    ;                                const uint16_t *mpeg_matrices);
272    ;
273    ;-----------------------------------------------------------------------------
274    
275    ALIGN 16
276    quant_h263_intra_sse2:
277    
278      push esi
279      push edi
280    
281      mov edi, [esp + 8 + 4]                ; coeff
282      mov esi, [esp + 8 + 8]                ; data
283      mov eax, [esp + 8 + 12]               ; quant
284    
285      xor ecx, ecx
286      cmp al, 1
287      jz near .qas2_q1loop
288    
289    .qas2_not1
290      movq mm7, [mmx_div + eax*8 - 8]
291      movq2dq xmm7, mm7
292      movlhps xmm7, xmm7
293    
294    ALIGN 16
295    .qas2_loop
296      movdqa xmm0, [esi + ecx*8]                ; xmm0 = [1st]
297      movdqa xmm3, [esi + ecx*8 + 16]           ; xmm3 = [2nd]
298      pxor xmm1, xmm1
299      pxor xmm4, xmm4
300      pcmpgtw xmm1, xmm0
301      pcmpgtw xmm4, xmm3
302      pxor xmm0, xmm1
303      pxor xmm3, xmm4
304      psubw xmm0, xmm1
305      psubw xmm3, xmm4
306      pmulhw xmm0, xmm7
307      pmulhw xmm3, xmm7
308      pxor xmm0, xmm1
309      pxor xmm3, xmm4
310      psubw xmm0, xmm1
311      psubw xmm3, xmm4
312      movdqa [edi + ecx*8], xmm0
313      movdqa [edi + ecx*8 + 16], xmm3
314    
315      add ecx, 4
316      cmp ecx, 16
317      jnz .qas2_loop
318    
319    .qas2_done
320      mov ecx, [esp + 8 + 16]   ; dcscalar
321      mov edx, ecx
322      movsx eax, word [esi]
323      shr edx, 1
324      cmp eax, 0
325      jg .qas2_gtzero
326    
327      sub eax, edx
328      jmp short .qas2_mul
329    
330    .qas2_gtzero
331      add eax, edx
332    
333    .qas2_mul
334      cdq
335      idiv ecx
336    
337      mov [edi], ax
338    
339      xor eax, eax      ; return(0);
340      pop edi
341      pop esi
342    
343      ret
344    
345    ALIGN 16
346    .qas2_q1loop
347      movdqa xmm0, [esi + ecx*8]         ; xmm0 = [1st]
348      movdqa xmm3, [esi + ecx*8 + 16]    ; xmm3 = [2nd]
349      pxor xmm1, xmm1
350      pxor xmm4, xmm4
351      pcmpgtw xmm1, xmm0
352      pcmpgtw xmm4, xmm3
353      pxor xmm0, xmm1
354      pxor xmm3, xmm4
355      psubw xmm0, xmm1
356      psubw xmm3, xmm4
357      psrlw xmm0, 1
358      psrlw xmm3, 1
359      pxor xmm0, xmm1
360      pxor xmm3, xmm4
361      psubw xmm0, xmm1
362      psubw xmm3, xmm4
363      movdqa [edi + ecx*8], xmm0
364      movdqa [edi + ecx*8 + 16], xmm3
365    
366      add ecx, 4
367      cmp ecx, 16
368      jnz .qas2_q1loop
369      jmp near .qas2_done
370    
371    
372    
373    ;-----------------------------------------------------------------------------
374    ;
375    ; uint32_t quant_h263_inter_mmx(int16_t * coeff,
376    ;                               const int16_t const * data,
377    ;                               const uint32_t quant,
378    ;                               const uint16_t *mpeg_matrices);
379    ;
380    ;-----------------------------------------------------------------------------
381    
382    ALIGN 16
383    quant_h263_inter_mmx:
384    
385      push ecx
386      push esi
387      push edi
388    
389      mov edi, [esp + 12 + 4]           ; coeff
390      mov esi, [esp + 12 + 8]           ; data
391      mov eax, [esp + 12 + 12]          ; quant
392    
393      xor ecx, ecx
394    
395      pxor mm5, mm5                     ; sum
396      movq mm6, [mmx_sub + eax * 8 - 8] ; sub
397    
398      cmp al, 1
399      jz .q1loop
400    
401      movq mm7, [mmx_div + eax * 8 - 8] ; divider
402    
403    ALIGN 8
404    .loop
405      movq mm0, [esi + 8*ecx]           ; mm0 = [1st]
406      movq mm3, [esi + 8*ecx + 8]
407      pxor mm1, mm1                     ; mm1 = 0
408      pxor mm4, mm4                     ;
409      pcmpgtw mm1, mm0                  ; mm1 = (0 > mm0)
410      pcmpgtw mm4, mm3                  ;
411      pxor mm0, mm1                     ; mm0 = |mm0|
412      pxor mm3, mm4                     ;
413      psubw mm0, mm1                    ; displace
414      psubw mm3, mm4                    ;
415      psubusw mm0, mm6                  ; mm0 -= sub (unsigned, dont go < 0)
416      psubusw mm3, mm6                  ;
417      pmulhw mm0, mm7                   ; mm0 = (mm0 / 2Q) >> 16
418      pmulhw mm3, mm7                   ;
419      paddw mm5, mm0                    ; sum += mm0
420      pxor mm0, mm1                     ; mm0 *= sign(mm0)
421      paddw mm5, mm3                    ;
422      pxor mm3, mm4                     ;
423      psubw mm0, mm1                    ; undisplace
424      psubw mm3, mm4
425      movq [edi + 8*ecx], mm0
426      movq [edi + 8*ecx + 8], mm3
427    
428      add ecx, 2
429      cmp ecx, 16
430      jnz .loop
431    
432    .done
433      pmaddwd mm5, [plus_one]
434      movq mm0, mm5
435      psrlq mm5, 32
436      paddd mm0, mm5
437    
438      movd eax, mm0     ; return sum
439      pop edi
440      pop esi
441      pop ecx
442    
443      ret
444    
445    ALIGN 8
446    .q1loop
447      movq mm0, [esi + 8*ecx]           ; mm0 = [1st]
448      movq mm3, [esi + 8*ecx+ 8]        ;
449      pxor mm1, mm1                     ; mm1 = 0
450      pxor mm4, mm4                     ;
451      pcmpgtw mm1, mm0                  ; mm1 = (0 > mm0)
452      pcmpgtw mm4, mm3                  ;
453      pxor mm0, mm1                     ; mm0 = |mm0|
454      pxor mm3, mm4                     ;
455      psubw mm0, mm1                    ; displace
456      psubw mm3, mm4                    ;
457      psubusw mm0, mm6                  ; mm0 -= sub (unsigned, dont go < 0)
458      psubusw mm3, mm6                  ;
459      psrlw mm0, 1                      ; mm0 >>= 1   (/2)
460      psrlw mm3, 1                      ;
461      paddw mm5, mm0                    ; sum += mm0
462      pxor mm0, mm1                     ; mm0 *= sign(mm0)
463      paddw mm5, mm3                    ;
464      pxor mm3, mm4                     ;
465      psubw mm0, mm1                    ; undisplace
466      psubw mm3, mm4
467      movq [edi + 8*ecx], mm0
468      movq [edi + 8*ecx + 8], mm3
469    
470      add ecx, 2
471      cmp ecx, 16
472      jnz .q1loop
473    
474      jmp .done
475    
476    
477    
478    ;-----------------------------------------------------------------------------
479    ;
480    ; uint32_t quant_h263_inter_sse2(int16_t * coeff,
481    ;                                const int16_t const * data,
482    ;                                const uint32_t quant,
483    ;                                const uint16_t *mpeg_matrices);
484    ;
485    ;-----------------------------------------------------------------------------
486    
487    ALIGN 16
488    quant_h263_inter_sse2:
489    
490      push esi
491      push edi
492    
493      mov edi, [esp + 8 + 4]      ; coeff
494      mov esi, [esp + 8 + 8]      ; data
495      mov eax, [esp + 8 + 12]     ; quant
496    
497      xor ecx, ecx
498    
499      pxor xmm5, xmm5                           ; sum
500    
501      movq mm0, [mmx_sub + eax*8 - 8]           ; sub
502      movq2dq xmm6, mm0                         ; load into low 8 bytes
503      movlhps xmm6, xmm6                        ; duplicate into high 8 bytes
504    
505      cmp al, 1
506      jz near .qes2_q1loop
507    
508    .qes2_not1
509      movq mm0, [mmx_div + eax*8 - 8]           ; divider
510      movq2dq xmm7, mm0
511      movlhps xmm7, xmm7
512    
513    ALIGN 16
514    .qes2_loop
515      movdqa xmm0, [esi + ecx*8]                ; xmm0 = [1st]
516      movdqa xmm3, [esi + ecx*8 + 16]           ; xmm3 = [2nd]
517      pxor xmm1, xmm1
518      pxor xmm4, xmm4
519      pcmpgtw xmm1, xmm0
520      pcmpgtw xmm4, xmm3
521      pxor xmm0, xmm1
522      pxor xmm3, xmm4
523      psubw xmm0, xmm1
524      psubw xmm3, xmm4
525      psubusw xmm0, xmm6
526      psubusw xmm3, xmm6
527      pmulhw xmm0, xmm7
528      pmulhw xmm3, xmm7
529      paddw xmm5, xmm0
530      pxor xmm0, xmm1
531      paddw xmm5, xmm3
532      pxor xmm3, xmm4
533      psubw xmm0, xmm1
534      psubw xmm3, xmm4
535      movdqa [edi + ecx*8], xmm0
536      movdqa [edi + ecx*8 + 16], xmm3
537    
538      add ecx, 4
539      cmp ecx, 16
540      jnz .qes2_loop
541    
542    .qes2_done
543      movdqu xmm6, [plus_one]
544      pmaddwd xmm5, xmm6
545      movhlps xmm6, xmm5
546      paddd xmm5, xmm6
547      movdq2q mm0, xmm5
548    
549      movq mm5, mm0
550      psrlq mm5, 32
551      paddd mm0, mm5
552    
553      movd eax, mm0         ; return sum
554    
555      pop edi
556      pop esi
557    
558      ret
559    
560    ALIGN 16
561    .qes2_q1loop
562      movdqa xmm0, [esi + ecx*8]        ; xmm0 = [1st]
563      movdqa xmm3, [esi + ecx*8 + 16]   ; xmm3 = [2nd]
564      pxor xmm1, xmm1
565      pxor xmm4, xmm4
566      pcmpgtw xmm1, xmm0
567      pcmpgtw xmm4, xmm3
568      pxor xmm0, xmm1
569      pxor xmm3, xmm4
570      psubw xmm0, xmm1
571      psubw xmm3, xmm4
572      psubusw xmm0, xmm6
573      psubusw xmm3, xmm6
574      psrlw xmm0, 1
575      psrlw xmm3, 1
576      paddw xmm5, xmm0
577      pxor xmm0, xmm1
578      paddw xmm5, xmm3
579      pxor xmm3, xmm4
580      psubw xmm0, xmm1
581      psubw xmm3, xmm4
582      movdqa [edi + ecx*8], xmm0
583      movdqa [edi + ecx*8 + 16], xmm3
584    
585      add ecx, 4
586      cmp ecx, 16
587      jnz .qes2_q1loop
588      jmp .qes2_done
589    
590    
591    ;-----------------------------------------------------------------------------
592    ;
593    ; uint32_t dequant_h263_intra_mmx(int16_t *data,
594    ;                                 const int16_t const *coeff,
595    ;                                 const uint32_t quant,
596    ;                                 const uint32_t dcscalar,
597    ;                                 const uint16_t *mpeg_matrices);
598    ;
599    ;-----------------------------------------------------------------------------
600    
601      ; note: we only saturate to +2047 *before* restoring the sign.
602      ; Hence, final clamp really is [-2048,2047]
603    
604    ALIGN 16
605    dequant_h263_intra_mmx:
606    
607      mov edx, [esp+ 4]                 ; data
608      mov ecx, [esp+ 8]                 ; coeff
609      mov eax, [esp+12]                 ; quant
610      movq mm6, [mmx_add + eax*8 - 8]   ; quant or quant-1
611      movq mm7, [mmx_mul + eax*8 - 8]   ; 2*quant
612      mov eax, -16
613    
614    ALIGN 16
615    .loop
616      movq mm0, [ecx+8*eax+8*16]        ; c  = coeff[i]
617      movq mm3, [ecx+8*eax+8*16 + 8]    ; c' = coeff[i+1]
618      pxor mm1, mm1
619      pxor mm4, mm4
620      pcmpgtw mm1, mm0                  ; sign(c)
621      pcmpgtw mm4, mm3                  ; sign(c')
622      pxor mm2, mm2
623      pxor mm5, mm5
624      pcmpeqw mm2, mm0                  ; c is zero
625      pcmpeqw mm5, mm3                  ; c' is zero
626      pandn mm2, mm6                    ; offset = isZero ? 0 : quant_add
627      pandn mm5, mm6
628      pxor mm0, mm1                     ; negate if negative
629      pxor mm3, mm4                     ; negate if negative
630      psubw mm0, mm1
631      psubw mm3, mm4
632      pmullw mm0, mm7                   ; *= 2Q
633      pmullw mm3, mm7                   ; *= 2Q
634      paddw mm0, mm2                    ; + offset
635      paddw mm3, mm5                    ; + offset
636      paddw mm0, mm1                    ; negate back
637      paddw mm3, mm4                    ; negate back
638    
639      ; saturates to +2047
640      movq mm2, [mmx_32767_minus_2047]
641      add eax, 2
642      paddsw mm0, mm2
643      paddsw mm3, mm2
644      psubsw mm0, mm2
645      psubsw mm3, mm2
646    
647      pxor mm0, mm1
648      pxor mm3, mm4
649      movq [edx + 8*eax + 8*16   - 2*8], mm0
650      movq [edx + 8*eax + 8*16+8 - 2*8], mm3
651      jnz near .loop
652    
653     ; deal with DC
654      movd mm0, [ecx]
655      pmullw mm0, [esp+16]          ; dcscalar
656      movq mm2, [mmx_32767_minus_2047]
657      paddsw mm0, mm2
658      psubsw mm0, mm2
659      movq mm3, [mmx_32768_minus_2048]
660      psubsw mm0, mm3
661      paddsw mm0, mm3
662      movd eax, mm0
663      mov [edx], ax
664    
665      xor eax, eax              ; return(0);
666      ret
667    
668    ;-----------------------------------------------------------------------------
669    ;
670    ; uint32_t dequant_h263_intra_xmm(int16_t *data,
671    ;                                 const int16_t const *coeff,
672    ;                                 const uint32_t quant,
673    ;                                 const uint32_t dcscalar,
674    ;                                 const uint16_t *mpeg_matrices);
675    ;
676    ;-----------------------------------------------------------------------------
677    
678      ; this is the same as dequant_inter_mmx, except that we're
679      ; saturating using 'pminsw' (saves 2 cycles/loop => ~5% faster)
680    
681    ALIGN 16
682    dequant_h263_intra_xmm:
683    
684      mov edx, [esp+ 4]                 ; data
685      mov ecx, [esp+ 8]                 ; coeff
686      mov eax, [esp+12]                 ; quant
687      movq mm6, [mmx_add + eax*8 - 8]   ; quant or quant-1
688      movq mm7, [mmx_mul + eax*8 - 8]   ; 2*quant
689      mov eax, -16
690    
691    ALIGN 16
692    .loop
693      movq mm0, [ecx+8*eax+8*16]        ; c  = coeff[i]
694      movq mm3, [ecx+8*eax+8*16 + 8]    ; c' = coeff[i+1]
695      pxor mm1, mm1
696      pxor mm4, mm4
697      pcmpgtw mm1, mm0                  ; sign(c)
698      pcmpgtw mm4, mm3                  ; sign(c')
699      pxor mm2, mm2
700      pxor mm5, mm5
701      pcmpeqw mm2, mm0                  ; c is zero
702      pcmpeqw mm5, mm3                  ; c' is zero
703      pandn mm2, mm6                    ; offset = isZero ? 0 : quant_add
704      pandn mm5, mm6
705      pxor mm0, mm1                     ; negate if negative
706      pxor mm3, mm4                     ; negate if negative
707      psubw mm0, mm1
708      psubw mm3, mm4
709      pmullw mm0, mm7                   ; *= 2Q
710      pmullw mm3, mm7                   ; *= 2Q
711      paddw mm0, mm2                    ; + offset
712      paddw mm3, mm5                    ; + offset
713      paddw mm0, mm1                    ; negate back
714      paddw mm3, mm4                    ; negate back
715    
716       ; saturates to +2047
717      movq mm2, [mmx_2047]
718      pminsw mm0, mm2
719      add eax, 2
720      pminsw mm3, mm2
721    
722      pxor mm0, mm1
723      pxor mm3, mm4
724      movq [edx + 8*eax + 8*16   - 2*8], mm0
725      movq [edx + 8*eax + 8*16+8 - 2*8], mm3
726      jnz near .loop
727    
728        ; deal with DC
729      movd mm0, [ecx]
730      pmullw mm0, [esp+16]    ; dcscalar
731      movq mm2, [mmx_32767_minus_2047]
732      paddsw mm0, mm2
733      psubsw mm0, mm2
734      movq mm2, [mmx_32768_minus_2048]
735      psubsw mm0, mm2
736      paddsw mm0, mm2
737      movd eax, mm0
738      mov [edx], ax
739    
740      xor eax, eax
741      ret
742    
743    
744    ;-----------------------------------------------------------------------------
745    ;
746    ; uint32_t dequant_h263_intra_sse2(int16_t *data,
747    ;                                  const int16_t const *coeff,
748    ;                                  const uint32_t quant,
749    ;                                  const uint32_t dcscalar,
750    ;                                  const uint16_t *mpeg_matrices);
751    ;
752    ;-----------------------------------------------------------------------------
753    
754    ALIGN 16
755    dequant_h263_intra_sse2:
756      mov edx, [esp+ 4]        ; data
757      mov ecx, [esp+ 8]        ; coeff
758      mov eax, [esp+12]        ; quant
759      movq mm6, [mmx_add + eax * 8 - 8]
760      movq mm7, [mmx_mul + eax * 8 - 8]
761      movq2dq xmm6, mm6
762      movq2dq xmm7, mm7
763      movlhps xmm6, xmm6
764      movlhps xmm7, xmm7
765      mov eax, -16
766    
767    ALIGN 16
768    .loop
769      movdqa xmm0, [ecx + 8*16 + 8*eax]      ; c  = coeff[i]
770      movdqa xmm3, [ecx + 8*16 + 8*eax+ 16]
771      pxor xmm1, xmm1
772      pxor xmm4, xmm4
773      pcmpgtw xmm1, xmm0    ; sign(c)
774      pcmpgtw xmm4, xmm3
775      pxor xmm2, xmm2
776      pxor xmm5, xmm5
777      pcmpeqw xmm2, xmm0    ; c is zero
778      pcmpeqw xmm5, xmm3
779      pandn xmm2, xmm6      ; offset = isZero ? 0 : quant_add
780      pandn xmm5, xmm6
781      pxor xmm0, xmm1       ; negate if negative
782      pxor xmm3, xmm4
783      psubw xmm0, xmm1
784      psubw xmm3, xmm4
785      pmullw xmm0, xmm7     ; *= 2Q
786      pmullw xmm3, xmm7
787      paddw xmm0, xmm2      ; + offset
788      paddw xmm3, xmm5
789      paddw xmm0, xmm1      ; negate back
790      paddw xmm3, xmm4
791    
792        ; saturates to +2047
793      movdqa xmm2, [sse2_2047]
794      pminsw xmm0, xmm2
795      add eax, 4
796      pminsw xmm3, xmm2
797    
798      pxor xmm0, xmm1
799      pxor xmm3, xmm4
800      movdqa [edx + 8*16 - 8*4 + 8*eax], xmm0
801      movdqa [edx + 8*16 - 8*4 + 8*eax + 16], xmm3
802      jnz near .loop
803    
804     ; deal with DC
805      movd mm0, [ecx]
806      pmullw mm0, [esp+16]    ; dcscalar
807      movq mm2, [mmx_32767_minus_2047]
808      paddsw mm0, mm2
809      psubsw mm0, mm2
810      movq mm2, [mmx_32768_minus_2048]
811      psubsw mm0, mm2
812      paddsw mm0, mm2
813      movd eax, mm0
814      mov [edx], ax
815    
816      xor eax, eax
817      ret
818    
819    ;-----------------------------------------------------------------------------
820    ;
821    ; uint32t dequant_h263_inter_mmx(int16_t * data,
822    ;                                const int16_t * const coeff,
823    ;                                const uint32_t quant,
824    ;                                const uint16_t *mpeg_matrices);
825    ;
826    ;-----------------------------------------------------------------------------
827    
828    ALIGN 16
829    dequant_h263_inter_mmx:
830    
831      mov edx, [esp+ 4]        ; data
832      mov ecx, [esp+ 8]        ; coeff
833      mov eax, [esp+12]        ; quant
834      movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1
835      movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant
836      mov eax, -16
837    
838    ALIGN 16
839    .loop
840      movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]
841      movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]
842      pxor mm1, mm1
843      pxor mm4, mm4
844      pcmpgtw mm1, mm0  ; sign(c)
845      pcmpgtw mm4, mm3  ; sign(c')
846      pxor mm2, mm2
847      pxor mm5, mm5
848      pcmpeqw mm2, mm0  ; c is zero
849      pcmpeqw mm5, mm3  ; c' is zero
850      pandn mm2, mm6    ; offset = isZero ? 0 : quant_add
851      pandn mm5, mm6
852      pxor mm0, mm1     ; negate if negative
853      pxor mm3, mm4     ; negate if negative
854      psubw mm0, mm1
855      psubw mm3, mm4
856      pmullw mm0, mm7   ; *= 2Q
857      pmullw mm3, mm7   ; *= 2Q
858      paddw mm0, mm2    ; + offset
859      paddw mm3, mm5    ; + offset
860      paddw mm0, mm1    ; negate back
861      paddw mm3, mm4    ; negate back
862      ; saturates to +2047
863      movq mm2, [mmx_32767_minus_2047]
864      add eax, 2
865      paddsw mm0, mm2
866      paddsw mm3, mm2
867      psubsw mm0, mm2
868      psubsw mm3, mm2
869    
870      pxor mm0, mm1
871      pxor mm3, mm4
872      movq [edx + 8*eax + 8*16   - 2*8], mm0
873      movq [edx + 8*eax + 8*16+8 - 2*8], mm3
874      jnz near .loop
875    
876      xor eax, eax
877      ret
878    
879    ;-----------------------------------------------------------------------------
880    ;
881    ; uint32_t dequant_h263_inter_xmm(int16_t * data,
882    ;                                 const int16_t * const coeff,
883    ;                                 const uint32_t quant,
884    ;                                 const uint16_t *mpeg_matrices);
885    ;
886    ;-----------------------------------------------------------------------------
887    
888      ; this is the same as dequant_inter_mmx,
889      ; except that we're saturating using 'pminsw' (saves 2 cycles/loop)
890    
891    ALIGN 16
892    dequant_h263_inter_xmm:
893    
894      mov edx, [esp+ 4]        ; data
895      mov ecx, [esp+ 8]        ; coeff
896      mov eax, [esp+12]        ; quant
897      movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1
898      movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant
899      mov eax, -16
900    
901    ALIGN 16
902    .loop
903      movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]
904      movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]
905      pxor mm1, mm1
906      pxor mm4, mm4
907      pcmpgtw mm1, mm0  ; sign(c)
908      pcmpgtw mm4, mm3  ; sign(c')
909      pxor mm2, mm2
910      pxor mm5, mm5
911      pcmpeqw mm2, mm0  ; c is zero
912      pcmpeqw mm5, mm3  ; c' is zero
913      pandn mm2, mm6    ; offset = isZero ? 0 : quant_add
914      pandn mm5, mm6
915      pxor mm0, mm1     ; negate if negative
916      pxor mm3, mm4     ; negate if negative
917      psubw mm0, mm1
918      psubw mm3, mm4
919      pmullw mm0, mm7   ; *= 2Q
920      pmullw mm3, mm7   ; *= 2Q
921      paddw mm0, mm2    ; + offset
922      paddw mm3, mm5    ; + offset
923      paddw mm0, mm1    ; start restoring sign
924      paddw mm3, mm4    ; start restoring sign
925                                ; saturates to +2047
926      movq mm2, [mmx_2047]
927      pminsw mm0, mm2
928      add eax, 2
929      pminsw mm3, mm2
930    
931      pxor mm0, mm1 ; finish restoring sign
932      pxor mm3, mm4 ; finish restoring sign
933      movq [edx + 8*eax + 8*16   - 2*8], mm0
934      movq [edx + 8*eax + 8*16+8 - 2*8], mm3
935      jnz near .loop
936    
937      xor eax, eax
938      ret
939    
940    ;-----------------------------------------------------------------------------
941    ;
942    ; uint32_t dequant_h263_inter_sse2(int16_t * data,
943    ;                                  const int16_t * const coeff,
944    ;                                  const uint32_t quant,
945    ;                                  const uint16_t *mpeg_matrices);
946    ;
947    ;-----------------------------------------------------------------------------
948    
949    ALIGN 16
950    dequant_h263_inter_sse2:
951      mov edx, [esp + 4]    ; data
952      mov ecx, [esp + 8]    ; coeff
953      mov eax, [esp + 12]   ; quant
954      movq mm6, [mmx_add + eax * 8 - 8]
955      movq mm7, [mmx_mul + eax * 8 - 8]
956      movq2dq xmm6, mm6
957      movq2dq xmm7, mm7
958      movlhps xmm6, xmm6
959      movlhps xmm7, xmm7
960      mov eax, -16
961    
962    ALIGN 16
963    .loop
964      movdqa xmm0, [ecx + 8*16 + 8*eax]  ; c  = coeff[i]
965      movdqa xmm3, [ecx + 8*16 + 8*eax + 16]
966    
967      pxor xmm1, xmm1
968      pxor xmm4, xmm4
969      pcmpgtw xmm1, xmm0    ; sign(c)
970      pcmpgtw xmm4, xmm3
971      pxor xmm2, xmm2
972      pxor xmm5, xmm5
973      pcmpeqw xmm2, xmm0    ; c is zero
974      pcmpeqw xmm5, xmm3
975      pandn xmm2, xmm6
976      pandn xmm5, xmm6
977      pxor xmm0, xmm1       ; negate if negative
978      pxor xmm3, xmm4
979      psubw xmm0, xmm1
980      psubw xmm3, xmm4
981      pmullw xmm0, xmm7     ; *= 2Q
982      pmullw xmm3, xmm7
983      paddw xmm0, xmm2      ; + offset
984      paddw xmm3, xmm5
985    
986      paddw xmm0, xmm1      ; start restoring sign
987      paddw xmm3, xmm4
988    
989     ; saturates to +2047
990      movdqa xmm2, [sse2_2047]
991      pminsw xmm0, xmm2
992      add eax, 4
993      pminsw xmm3, xmm2
994    
995      pxor xmm0, xmm1 ; finish restoring sign
996      pxor xmm3, xmm4
997      movdqa [edx + 8*16 - 8*4 + 8*eax], xmm0
998      movdqa [edx + 8*16 - 8*4 + 8*eax + 16], xmm3
999      jnz near .loop
1000    
1001      xor eax, eax
1002      ret

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

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