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