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

Diff of /xvidcore/src/quant/x86_asm/quantize_h263_3dne.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.2, Thu Oct 9 18:50:22 2003 UTC
# Line 0  Line 1 
1    ;/**************************************************************************
2    ; *
3    ; *  XVID MPEG-4 VIDEO CODEC
4    ; *  - 3dne Quantization/Dequantization -
5    ; *
6    ; *  Copyright(C) 2002-2003 Jaan Kalda
7    ; *
8    ; *  This program is free software ; you can redistribute it and/or modify
9    ; *  it under the terms of the GNU General Public License as published by
10    ; *  the Free Software Foundation ; either version 2 of the License, or
11    ; *  (at your option) any later version.
12    ; *
13    ; *  This program is distributed in the hope that it will be useful,
14    ; *  but WITHOUT ANY WARRANTY ; without even the implied warranty of
15    ; *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    ; *  GNU General Public License for more details.
17    ; *
18    ; *  You should have received a copy of the GNU General Public License
19    ; *  along with this program ; if not, write to the Free Software
20    ; *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21    ; *
22    ; * $Id$
23    ; *
24    ; *************************************************************************/
25    ;
26    ; these 3dne functions are compatible with iSSE, but are optimized specifically for
27    ; K7 pipelines
28    
29    ; enable dequant saturate [-2048,2047], test purposes only.
30    %define SATURATE
31    
32    ; data/text alignment
33    %define ALIGN 16
34    
35    bits 32
36    
37    %macro cglobal 1
38            %ifdef PREFIX
39                    global _%1
40                    %define %1 _%1
41            %else
42                    global %1
43            %endif
44    %endmacro
45    
46    ;***************************************************************************
47    ; Local data
48    ;***************************************************************************
49    
50    %ifdef FORMAT_COFF
51    section .data data
52    %else
53    section .data data align=16
54    %endif
55    
56    align 4
57    int_div:
58    dd 0
59    %assign i 1
60    %rep 255
61            dd  (1 << 16) / (i) + 1
62            %assign i i+1
63    %endrep
64    
65    align 16
66    plus_one:
67            times 8 dw 1
68    
69    ;===========================================================================
70    ;
71    ; subtract by Q/2 table
72    ;
73    ;===========================================================================
74    
75    align 16
76    mmx_sub:
77    %assign i 1
78    %rep 31
79            times 4 dw i / 2
80            %assign i i+1
81    %endrep
82    
83    
84    ;===========================================================================
85    ;
86    ; divide by 2Q table
87    ;
88    ; use a shift of 16 to take full advantage of _pmulhw_
89    ; for q=1, _pmulhw_ will overflow so it is treated seperately
90    ; (3dnow2 provides _pmulhuw_ which wont cause overflow)
91    ;
92    ;===========================================================================
93    
94    align 16
95    mmx_div:
96    %assign i 1
97    %rep 31
98            times 4 dw  (1 << 16) / (i * 2) + 1
99            %assign i i+1
100    %endrep
101    
102    ;===========================================================================
103    ;
104    ; add by (odd(Q) ? Q : Q - 1) table
105    ;
106    ;===========================================================================
107    
108    align 16
109    mmx_add:
110    %assign i 1
111    %rep 31
112            %if i % 2 != 0
113            times 4 dw i
114            %else
115            times 4 dw i - 1
116            %endif
117            %assign i i+1
118    %endrep
119    
120    ;===========================================================================
121    ;
122    ; multiple by 2Q table
123    ;
124    ;===========================================================================
125    
126    align 16
127    mmx_mul:
128    %assign i 1
129    %rep 31
130            times 4 dw i * 2
131            %assign i i+1
132    %endrep
133    
134    ;===========================================================================
135    ;
136    ; saturation limits
137    ;
138    ;===========================================================================
139    
140    align 8
141    mmx_32768_minus_2048:
142            times 4 dw (32768-2048)
143    mmx_32767_minus_2047:
144            times 4 dw (32767-2047)
145    
146    align 16
147    mmx_2047:
148            times 4 dw 2047
149    
150    align 8
151    mmzero:
152            dd 0, 0
153    int2047:
154            dd 2047
155    int_2048:
156            dd -2048
157    
158    ;***************************************************************************
159    ; Code
160    ;***************************************************************************
161    
162    section .text
163    
164    
165    ;===========================================================================
166    ;
167    ; uint32_t quant_h263_intra_3dne(int16_t * coeff,
168    ;                                const int16_t const * data,
169    ;                                const uint32_t quant,
170    ;                                const uint32_t dcscalar);
171    ;
172    ;===========================================================================
173    ;This is Athlon-optimized code (ca 70 clk per call)
174    
175    %macro quant_intra1  1
176    
177            psubw   mm1, mm0        ;A3
178            psubw   mm3, mm2        ;B3
179    %if (%1)
180            psubw   mm5, mm4        ;C8
181            psubw   mm7, mm6        ;D8
182    %endif
183    
184    align 8
185            db      0Fh, 6Fh, 64h, 21h, (%1 * 32 +16)       ;movq   mm4, [ecx + %1 * 32 +16+32]     ;C1
186            pmaxsw  mm1, mm0        ;A4
187            db      0Fh, 6Fh, 74h, 21h, (%1 * 32 +24)       ;movq   mm6, [ecx + %1 * 32 +24+32]     ;D1
188            pmaxsw  mm3, mm2        ;B4
189    
190    
191            psraw   mm0, 15         ;A5
192            psraw   mm2, 15         ;B5
193    %if (%1)
194            movq    [edx + %1 * 32 + 16-32], mm5    ;C9
195            movq    [edx + %1 * 32 + 24-32], mm7    ;D9
196    %endif
197    
198            psrlw   mm1, 1          ;A6
199            psrlw   mm3, 1          ;B6
200            movq    mm5, [ebx]      ;C2
201            movq    mm7, [ebx]      ;D2
202    
203            pxor    mm1, mm0        ;A7
204            pxor    mm3, mm2        ;B7
205    
206            psubw   mm5, mm4        ;C3
207            psubw   mm7, mm6        ;D3
208            psubw   mm1, mm0        ;A8
209            psubw   mm3, mm2        ;B8
210    
211    %if (%1 == 0)
212            push    ebp
213            movq    mm0, [ecx + %1 * 32 +32]
214    %elif (%1 < 3)
215            db      0Fh, 6Fh, 44h, 21h, (%1 * 32 +32)       ;movq   mm0, [ecx + %1 * 32 +32]        ;A1
216    %endif
217            pmaxsw  mm5, mm4        ;C4
218    %if (%1 < 3)
219            db      0Fh, 6Fh, 54h, 21h, ( %1 * 32 +8+32)    ;movq   mm2, [ecx + %1 * 32 +8+32]      ;B1
220    %else
221            cmp     esp, esp
222    %endif
223            pmaxsw  mm7, mm6        ;D4
224    
225            psraw   mm4, 15         ;C5
226            psraw   mm6, 15         ;D5
227            movq    [byte edx + %1 * 32], mm1       ;A9
228            movq    [edx + %1 * 32+8], mm3          ;B9
229    
230    
231            psrlw   mm5, 1          ;C6
232            psrlw   mm7, 1          ;D6
233    %if (%1 < 3)
234            movq    mm1, [ebx]      ;A2
235            movq    mm3, [ebx]      ;B2
236    %endif
237    %if (%1 == 3)
238            imul    eax, [int_div+4*edi]
239    %endif
240            pxor    mm5, mm4        ;C7
241            pxor    mm7, mm6        ;D7
242    %endm
243    
244    
245    %macro quant_intra  1
246            ; Rules for athlon:
247                    ; 1) schedule latencies
248                    ; 2) add/mul and load/store in 2:1 proportion
249                    ; 3) avoid spliting >3byte instructions over 8byte boundaries
250    
251            psubw   mm1, mm0        ;A3
252            psubw   mm3, mm2        ;B3
253    %if (%1)
254            psubw   mm5, mm4        ;C8
255            psubw   mm7, mm6        ;D8
256    %endif
257    
258    align 8
259            db      0Fh, 6Fh, 64h, 21h, (%1 * 32 +16)       ;movq   mm4, [ecx + %1 * 32 +16+32]     ;C1
260            pmaxsw  mm1, mm0        ;A4
261            db      0Fh, 6Fh, 74h, 21h, (%1 * 32 +24)       ;movq   mm6, [ecx + %1 * 32 +24+32]     ;D1
262            pmaxsw  mm3, mm2        ;B4
263    
264    
265            psraw   mm0, 15         ;A5
266            psraw   mm2, 15         ;B5
267    %if (%1)
268            movq    [edx + %1 * 32 + 16-32], mm5 ;C9
269            movq    [edx + %1 * 32 + 24-32], mm7 ;D9
270    %endif
271    
272            pmulhw  mm1, [esi]      ;A6
273            pmulhw  mm3, [esi]      ;B6
274            movq    mm5, [ebx]      ;C2
275            movq    mm7, [ebx]      ;D2
276    
277            nop
278            nop
279            pxor    mm1, mm0        ;A7
280            pxor    mm3, mm2        ;B7
281    
282            psubw   mm5, mm4        ;C3
283            psubw   mm7, mm6        ;D3
284            psubw   mm1, mm0        ;A8
285            psubw   mm3, mm2        ;B8
286    
287    
288    %if (%1 < 3)
289            db      0Fh, 6Fh, 44h, 21h, (%1 * 32 +32) ;movq mm0, [ecx + %1 * 32 +32]        ;A1
290    %endif
291            pmaxsw  mm5, mm4          ;C4
292    %if (%1 < 3)
293            db      0Fh, 6Fh, 54h, 21h, ( %1 * 32 +8+32) ;movq      mm2, [ecx + %1 * 32 +8+32]      ;B1
294    %else
295            cmp     esp, esp
296    %endif
297            pmaxsw  mm7,mm6         ;D4
298    
299            psraw   mm4, 15         ;C5
300            psraw   mm6, 15         ;D5
301            movq    [byte edx + %1 * 32], mm1 ;A9
302            movq    [edx + %1 * 32+8], mm3    ;B9
303    
304    
305            pmulhw  mm5, [esi]      ;C6
306            pmulhw  mm7, [esi]      ;D6
307    %if (%1 < 3)
308            movq    mm1, [ebx]      ;A2
309            movq    mm3, [ebx]      ;B2
310    %endif
311    %if (%1 == 0)
312            push    ebp
313    %elif (%1 < 3)
314            nop
315    %endif
316            nop
317    %if (%1 == 3)
318            imul    eax, [int_div+4*edi]
319    %endif
320            pxor    mm5, mm4        ;C7
321            pxor    mm7, mm6        ;D7
322    %endmacro
323    
324    
325    align ALIGN
326    cglobal quant_h263_intra_3dne
327    quant_h263_intra_3dne:
328    
329            mov             eax, [esp + 12]         ; quant
330            mov             ecx, [esp + 8]          ; data
331            mov             edx, [esp + 4]          ; coeff
332            cmp             al, 1
333            pxor    mm1, mm1
334            pxor    mm3, mm3
335            movq    mm0, [ecx]              ; mm0 = [1st]
336            movq    mm2, [ecx + 8]
337            push    esi
338            lea             esi, [mmx_div + eax*8 - 8]
339    
340            push    ebx
341            mov             ebx, mmzero
342            push    edi
343            jz              near .q1loop
344    
345    quant_intra 0
346            mov     ebp, [esp + 16 + 16]    ; dcscalar
347                                            ; NB -- there are 3 pushes in the function preambule and one more
348                                            ; in "quant_intra 0", thus an added offset of 16 bytes
349            movsx   eax, word [byte ecx]    ; DC
350    
351    quant_intra 1
352            mov             edi, eax
353            sar             edi, 31         ; sign(DC)
354            shr     ebp, byte 1     ; ebp = dcscalar/2
355    
356    quant_intra 2
357            sub             eax, edi                ; DC (+1)
358            xor     ebp, edi                ; sign(DC) dcscalar /2  (-1)
359            mov             edi, [esp + 16 + 16]    ; dscalar
360            lea             eax, [byte eax + ebp]   ; DC + sign(DC) dcscalar/2
361            mov             ebp, [byte esp]
362    
363    quant_intra 3
364            psubw   mm5, mm4                        ;C8
365            mov             esi, [esp + 12]                 ; pop back the register value
366            mov             edi, [esp + 4]                  ; pop back the register value
367            sar             eax, 16
368            lea             ebx, [byte eax + 1]             ; workaround for eax < 0
369            cmovs   eax, ebx                        ; conditionnaly move the corrected value
370            mov             [edx], ax                       ; coeff[0] = ax
371            mov             ebx, [esp + 8]                  ; pop back the register value
372            add             esp, byte 16                    ; "quant_intra 0" pushed ebp, but we don't restore that one, just correct the stack offset by 16
373            psubw   mm7, mm6                        ;D8
374            movq    [edx + 3 * 32 + 16], mm5        ;C9
375            movq    [edx + 3 * 32 + 24], mm7        ;D9
376    
377            xor             eax, eax
378            ret
379    
380            align 16
381    
382    .q1loop
383    quant_intra1 0
384            mov             ebp, [esp + 16 + 16]    ; dcscalar
385            movsx   eax, word [byte ecx]    ; DC
386    
387    quant_intra1 1
388            mov             edi, eax
389            sar             edi, 31         ; sign(DC)
390            shr     ebp, byte 1     ; ebp = dcscalar /2
391    
392    quant_intra1 2
393            sub             eax, edi                ; DC (+1)
394            xor     ebp, edi                ; sign(DC) dcscalar /2  (-1)
395            mov             edi, [esp + 16 + 16]    ; dcscalar
396            lea             eax, [byte eax + ebp]   ; DC + sign(DC) dcscalar /2
397            mov             ebp, [byte esp]
398    
399    quant_intra1 3
400            psubw   mm5, mm4                        ;C8
401            mov             esi, [dword esp + 12]           ; pop back the register value
402            mov             edi, [esp + 4]          ; pop back the register value
403            sar             eax, 16
404            lea             ebx, [byte eax + 1]     ; workaround for eax < 0
405            cmovs   eax, ebx                        ; conditionnaly move the corrected value
406            mov             [edx], ax                       ; coeff[0] = ax
407            mov             ebx, [esp + 8]          ; pop back the register value
408            add             esp, byte 16            ; "quant_intra 0" pushed ebp, but we don't restore that one, just correct the stack offset by 16
409            psubw   mm7, mm6                        ;D8
410            movq    [edx + 3 * 32 + 16], mm5        ;C9
411            movq    [edx + 3 * 32 + 24], mm7        ;D9
412    
413            xor             eax, eax
414            ret
415    
416    
417    
418    
419    ;===========================================================================
420    ;
421    ; uint32_t quant_h263_inter_3dne(int16_t * coeff,
422    ;                                const int16_t const * data,
423    ;                                const uint32_t quant);
424    ;
425    ;===========================================================================
426    ;This is Athlon-optimized code (ca 90 clk per call)
427    ;Optimized by Jaan, 30 Nov 2002
428    
429    
430    %macro quantinter 1
431            movq    mm1, [eax]      ;A2
432            psraw   mm3, 15         ;B6
433    %if (%1)
434            psubw   mm2, mm6        ;C10
435    %endif
436            psubw   mm1, mm0                ;A3
437            pmulhw  mm4, mm7                ;B7
438            movq    mm6, [ecx + %1*24+16]   ;C1
439            pmaxsw  mm1, mm0                ;A4
440            paddw   mm5, mm4                ;B8
441    %if (%1)
442            movq    [edx + %1*24+16-24], mm2        ;C11
443    %endif
444            psubusw mm1, [ebx]              ;A5 mm0 -= sub (unsigned, dont go < 0)
445            pxor    mm4, mm3                ;B9
446            movq    mm2, [eax]              ;C2
447            psraw   mm0, 15                 ;A6
448            psubw   mm4, mm3                ;B10
449            psubw   mm2, mm6                ;C3
450            pmulhw  mm1, mm7                ;A7 mm0 = (mm0 / 2Q) >> 24
451            movq    mm3, [ecx + %1*24+8]    ;B1
452            pmaxsw  mm2, mm6                ;C4
453            paddw   mm5, mm1                ;A8 sum += mm0
454    %if (%1)
455            movq    [edx + %1*24+8-24], mm4 ;B11
456    %else
457            movq    [edx + 120], mm4        ;B11
458    %endif
459            psubusw mm2, [ebx]              ;C5
460            pxor    mm1, mm0                ;A9 mm0 *= sign(mm0)
461            movq    mm4, [eax]              ;B2
462            psraw   mm6, 15                 ;C6
463            psubw   mm1, mm0                ;A10 undisplace
464            psubw   mm4, mm3                ;B3
465            pmulhw  mm2, mm7                ;C7
466            movq    mm0, [ecx + %1*24+24]   ;A1 mm0 = [1st]
467            pmaxsw  mm4, mm3                ;B4
468            paddw   mm5, mm2                ;C8
469            movq    [byte edx + %1*24], mm1 ;A11
470            psubusw mm4, [ebx]              ;B5
471            pxor    mm2, mm6                ;C9
472    %endmacro
473    
474    %macro quantinter1 1
475            movq    mm0, [byte ecx + %1*16] ;mm0 = [1st]
476            movq    mm3, [ecx + %1*16+8]    ;
477            movq    mm1, [eax]
478            movq    mm4, [eax]
479            psubw   mm1, mm0
480            psubw   mm4, mm3
481            pmaxsw  mm1, mm0
482            pmaxsw  mm4, mm3
483            psubusw mm1, mm6                ; mm0 -= sub (unsigned, dont go < 0)
484            psubusw mm4, mm6                ;
485            psraw   mm0, 15
486            psraw   mm3, 15
487            psrlw   mm1, 1                  ; mm0 = (mm0 / 2Q) >> 16
488            psrlw   mm4, 1                  ;
489            paddw   mm5, mm1                ; sum += mm0
490            pxor    mm1, mm0                ; mm0 *= sign(mm0)
491            paddw   mm5, mm4
492            pxor    mm4, mm3                ;
493            psubw   mm1, mm0                ; undisplace
494            psubw   mm4, mm3
495            cmp             esp, esp
496            movq    [byte edx + %1*16], mm1
497            movq    [edx + %1*16+8], mm4
498    %endmacro
499    
500    align ALIGN
501    cglobal quant_h263_inter_3dne
502    quant_h263_inter_3dne:
503            mov             edx, [esp  + 4]         ; coeff
504            mov             ecx, [esp  + 8]         ; data
505            mov             eax, [esp  + 12]        ; quant
506            push    ebx
507    
508            pxor    mm5, mm5                        ; sum
509            nop
510            lea             ebx,[mmx_sub + eax * 8 - 8]     ; sub
511            movq    mm7, [mmx_div + eax * 8 - 8]    ; divider
512    
513            cmp             al, 1
514            lea             eax, [mmzero]
515            jz              near .q1loop
516            cmp             esp, esp
517    align 8
518            movq    mm3, [ecx + 120]        ;B1
519            pxor    mm4, mm4                ;B2
520            psubw   mm4, mm3                ;B3
521            movq    mm0, [ecx]              ;A1 mm0 = [1st]
522            pmaxsw  mm4, mm3                ;B4
523            psubusw mm4, [ebx]              ;B5
524    
525            quantinter 0
526            quantinter 1
527            quantinter 2
528            quantinter 3
529            quantinter 4
530    
531            psraw   mm3, 15                 ;B6
532            psubw   mm2, mm6                ;C10
533            pmulhw  mm4, mm7                ;B7
534            paddw   mm5, mm4                ;B8
535            pxor    mm4, mm3                ;B9
536            psubw   mm4, mm3                ;B10
537            movq    [edx + 4*24+16], mm2    ;C11
538            pop             ebx
539            movq    [edx + 4*24+8], mm4     ;B11
540            pmaddwd mm5, [plus_one]
541            movq    mm0, mm5
542            punpckhdq       mm5, mm5
543            paddd   mm0, mm5
544            movd    eax, mm0                ; return sum
545    
546            ret
547    
548    align ALIGN
549    .q1loop
550            movq mm6, [byte ebx]
551    
552            quantinter1 0
553            quantinter1 1
554            quantinter1 2
555            quantinter1 3
556            quantinter1 4
557            quantinter1 5
558            quantinter1 6
559            quantinter1 7
560    
561            pmaddwd mm5, [plus_one]
562            movq    mm0, mm5
563            psrlq   mm5, 32
564            paddd   mm0, mm5
565            movd    eax, mm0        ; return sum
566    
567            pop ebx
568    
569            ret
570    
571    ;===========================================================================
572    ;
573    ; uint32_t dequant_h263_intra_3dne(int16_t *data,
574    ;                                  const int16_t const *coeff,
575    ;                                  const uint32_t quant,
576    ;                                  const uint32_t dcscalar);
577    ;
578    ;===========================================================================
579    
580      ; this is the same as dequant_inter_3dne, except that we're
581      ; saturating using 'pminsw' (saves 2 cycles/loop => ~5% faster)
582    
583    ;This is Athlon-optimized code (ca 106 clk per call)
584    
585    %macro dequant 1
586            movq    mm1, [ecx+%1*24]        ; c  = coeff[i] ;A2
587            psubw   mm0, mm1                ;-c             ;A3 (1st dep)
588    %if (%1)
589            paddw   mm4, mm6                ;C11 mm6 free (4th+)
590    %endif
591            pmaxsw  mm0, mm1                ;|c|            ;A4 (2nd)
592    %if (%1)
593            mov             ebp, ebp
594            pminsw  mm4, [ebx]              ;C12 saturates to +2047 (5th+) later
595    %endif
596            movq    mm6, [esi]              ;0              ;A5  mm6 in use
597            pandn   mm7, [eax]              ;B9 offset = isZero ? 0 : quant_add (2nd)
598    %if (%1)
599            pxor    mm5, mm4                ;C13 (6th+) 1later
600    %endif
601            movq    mm4, [esi]              ;C1 ;0
602            mov             esp, esp
603            pcmpeqw mm6, [ecx+%1*24]        ;A6 (c ==0) ? -1 : 0 (1st)
604    align 4
605            psraw   mm1, 15                 ; sign(c)       ;A7 (2nd)
606    %if (%1)
607            movq    [edx+%1*24+16-24], mm5  ; C14 (7th) 2later
608    %endif
609            paddw   mm7, mm3                ;B10  offset +negate back (3rd)
610            pmullw  mm0, [edi]              ;*= 2Q  ;A8 (3rd+)
611            paddw   mm2, mm7                ;B11 mm7 free (4th+)
612            lea             ebp, [byte ebp]
613            movq    mm5, [ecx+%1*24+16]     ;C2 ; c  = coeff[i]
614            psubw   mm4, mm5                ;-c             ;C3 (1st dep)
615            pandn   mm6, [eax]              ;A9 offset = isZero ? 0 : quant_add (2nd)
616            pminsw  mm2, [ebx]              ;B12 saturates to +2047 (5th+)
617            pxor    mm3, mm2                ;B13 (6th+)
618            movq    mm2, [byte esi]         ;B1 ;0
619    %if (%1)
620            movq    [edx+%1*24+8-24], mm3   ;B14 (7th)
621    %else
622            movq    [edx+120], mm3
623    %endif
624            pmaxsw  mm4, mm5                ;|c|            ;C4 (2nd)
625            paddw   mm6, mm1                ;A10  offset +negate back (3rd)
626            movq    mm3, [ecx+%1*24 + 8]    ;B2 ; c  = coeff[i]
627            psubw   mm2, mm3                ;-c             ;B3 (1st dep)
628            paddw   mm0, mm6                ;A11 mm6 free (4th+)
629            movq    mm6, [byte esi]         ;0              ;C5  mm6 in use
630            pcmpeqw mm6, [ecx+%1*24+16]     ;C6 (c ==0) ? -1 : 0 (1st)
631            pminsw  mm0, [ebx]              ;A12 saturates to +2047 (5th+)
632            pmaxsw  mm2, mm3                ;|c|            ;B4 (2nd)
633            pxor    mm1, mm0                ;A13 (6th+)
634            pmullw  mm4, [edi]              ;*= 2Q  ;C8 (3rd+)
635            psraw   mm5, 15                 ; sign(c)       ;C7 (2nd)
636            movq    mm7, [byte esi]         ;0              ;B5 mm7 in use
637            pcmpeqw mm7, [ecx+%1*24 + 8]    ;B6 (c ==0) ? -1 : 0 (1st)
638    %if (%1 < 4)
639            movq    mm0, [byte esi]         ;A1 ;0
640    %endif
641            pandn   mm6, [byte eax]         ;C9 offset = isZero ? 0 : quant_add (2nd)
642            psraw   mm3, 15                 ;sign(c)        ;B7 (2nd)
643            movq    [byte edx+%1*24], mm1   ;A14 (7th)
644            paddw   mm6, mm5                ;C10  offset +negate back (3rd)
645            pmullw  mm2, [edi]              ;*= 2Q  ;B8 (3rd+)
646            mov             esp, esp
647    %endmacro
648    
649    
650    align ALIGN
651    cglobal dequant_h263_intra_3dne
652    dequant_h263_intra_3dne:
653            mov             ecx, [esp+ 8]                   ; coeff
654            mov             eax, [esp+12]                   ; quant
655            pxor    mm0, mm0
656            pxor    mm2, mm2
657            push    edi
658            push    ebx
659            lea             edi, [mmx_mul + eax*8 - 8]      ; 2*quant
660            push    ebp
661            mov             ebx, mmx_2047
662            movsx   ebp, word [ecx]
663            lea             eax, [mmx_add + eax*8 - 8]      ; quant or quant-1
664            push    esi
665            mov             esi, mmzero
666            pxor    mm7, mm7
667            movq    mm3, [ecx+120]                  ;B2 ; c  = coeff[i]
668            pcmpeqw mm7, [ecx+120]                  ;B6 (c ==0) ? -1 : 0 (1st)
669    
670            imul    ebp, [esp+16+16]                ; dcscalar
671            psubw   mm2, mm3                        ;-c             ;B3 (1st dep)
672            pmaxsw  mm2, mm3                        ;|c|            ;B4 (2nd)
673            pmullw  mm2, [edi]                      ;*= 2Q  ;B8 (3rd+)
674            psraw   mm3, 15                         ; sign(c)       ;B7 (2nd)
675            mov             edx, [esp+ 4+16]                ; data
676    
677    align 8
678            dequant 0
679    
680            cmp             ebp, -2048
681            mov             esp, esp
682    
683            dequant 1
684    
685            cmovl   ebp, [int_2048]
686            nop
687    
688            dequant 2
689    
690            cmp             ebp, 2047
691            mov             esp, esp
692    
693            dequant 3
694    
695            cmovg   ebp, [int2047]
696            nop
697    
698            dequant 4
699    
700            paddw   mm4, mm6                ;C11 mm6 free (4th+)
701            pminsw  mm4, [ebx]              ;C12 saturates to +2047 (5th+)
702            pandn   mm7, [eax]              ;B9 offset = isZero ? 0 : quant_add (2nd)
703            mov             eax, ebp
704            mov             esi, [esp]
705            mov             ebp, [esp+4]
706            pxor    mm5, mm4                ;C13 (6th+)
707            paddw   mm7, mm3                ;B10  offset +negate back (3rd)
708            movq    [edx+4*24+16], mm5      ;C14 (7th)
709            paddw   mm2, mm7                ;B11 mm7 free (4th+)
710            pminsw  mm2, [ebx]              ;B12 saturates to +2047 (5th+)
711            mov             ebx, [esp+8]
712            mov             edi, [esp+12]
713            add             esp, byte 16
714            pxor    mm3, mm2                ;B13 (6th+)
715            movq    [edx+4*24+8], mm3       ;B14 (7th)
716            mov             [edx], ax
717    
718            xor             eax, eax
719            ret
720    
721    ;===========================================================================
722    ;
723    ; uint32_t dequant_h263_inter_3dne(int16_t * data,
724    ;                                  const int16_t * const coeff,
725    ;                                  const uint32_t quant);
726    ;
727    ;===========================================================================
728    
729    ; this is the same as dequant_inter_3dne,
730    ; except that we're saturating using 'pminsw' (saves 2 cycles/loop)
731    ; This is Athlon-optimized code (ca 100 clk per call)
732    
733    align ALIGN
734    cglobal dequant_h263_inter_3dne
735    dequant_h263_inter_3dne:
736            mov             ecx, [esp+ 8]                   ; coeff
737            mov             eax, [esp+12]                   ; quant
738            pxor    mm0, mm0
739            pxor    mm2, mm2
740            push    edi
741            push    ebx
742            push    esi
743            lea             edi, [mmx_mul + eax*8 - 8]      ; 2*quant
744            mov             ebx, mmx_2047
745            pxor    mm7, mm7
746            movq    mm3, [ecx+120]                  ;B2 ; c  = coeff[i]
747            pcmpeqw mm7, [ecx+120]                  ;B6 (c ==0) ? -1 : 0 (1st)
748            lea             eax, [mmx_add + eax*8 - 8]      ; quant or quant-1
749            psubw   mm2, mm3                        ;-c     ;B3 (1st dep)
750            mov             esi, mmzero
751            pmaxsw  mm2, mm3                        ;|c|            ;B4 (2nd)
752            pmullw  mm2, [edi]                      ;*= 2Q          ;B8 (3rd+)
753            psraw   mm3, 15                         ; sign(c)       ;B7 (2nd)
754            mov             edx, [dword esp+ 4+12]          ; data
755    
756    align 8
757    
758            dequant 0
759            dequant 1
760            dequant 2
761            dequant 3
762            dequant 4
763    
764            paddw   mm4, mm6                ;C11 mm6 free (4th+)
765            pminsw  mm4, [ebx]              ;C12 saturates to +2047 (5th+)
766            pandn   mm7, [eax]              ;B9 offset = isZero ? 0 : quant_add (2nd)
767            mov             esi, [esp]
768            pxor    mm5, mm4                ;C13 (6th+)
769            paddw   mm7, mm3                ;B10  offset +negate back (3rd)
770            movq    [edx+4*24+16], mm5      ;C14 (7th)
771            paddw   mm2, mm7                ;B11 mm7 free (4th+)
772            pminsw  mm2, [ebx]              ;B12 saturates to +2047 (5th+)
773            mov             ebx, [esp+4]
774            mov             edi, [esp+8]
775            add             esp, byte 12
776            pxor    mm3, mm2                ;B13 (6th+)
777            movq    [edx+4*24+8], mm3       ;B14 (7th)
778    
779            xor             eax, eax
780            ret

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

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