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

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

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