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

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

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