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

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

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