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

Diff of /xvidcore/src/quant/x86_asm/quantize_mpeg_xmm.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.2, Mon Mar 22 22:36:24 2004 UTC
# Line 0  Line 1 
1    ;/****************************************************************************
2    ; *
3    ; *  XVID MPEG-4 VIDEO CODEC
4    ; *  - 3dne Quantization/Dequantization -
5    ; *
6    ; *  Copyright (C) 2002-2003 Peter Ross <pross@xvid.org>
7    ; *                2002      Jaan Kalda
8    ; *
9    ; *  This program is free software ; you can redistribute it and/or modify
10    ; *  it under the terms of the GNU General Public License as published by
11    ; *  the Free Software Foundation ; either version 2 of the License, or
12    ; *  (at your option) any later version.
13    ; *
14    ; *  This program is distributed in the hope that it will be useful,
15    ; *  but WITHOUT ANY WARRANTY ; without even the implied warranty of
16    ; *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    ; *  GNU General Public License for more details.
18    ; *
19    ; *  You should have received a copy of the GNU General Public License
20    ; *  along with this program ; if not, write to the Free Software
21    ; *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
22    ; *
23    ; * $Id$
24    ; *
25    ; ***************************************************************************/
26    
27    ; _3dne functions are compatible with iSSE, but are optimized specifically
28    ; for K7 pipelines
29    
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    %macro cextern 1
44            %ifdef PREFIX
45                    extern _%1
46                    %define %1 _%1
47            %else
48                    extern %1
49            %endif
50    %endmacro
51    
52    ;=============================================================================
53    ; Local data
54    ;=============================================================================
55    
56    %ifdef FORMAT_COFF
57    SECTION .rodata data
58    %else
59    SECTION .rodata data align=16
60    %endif
61    
62    ALIGN 8
63    mmzero:
64            dd 0,0
65    mmx_one:
66            times 4 dw 1
67    
68    ;-----------------------------------------------------------------------------
69    ; divide by 2Q table
70    ;-----------------------------------------------------------------------------
71    
72    ALIGN 16
73    mmx_divs:               ;i>2
74    %assign i 1
75    %rep 31
76            times 4 dw  ((1 << 15) / i + 1)
77            %assign i i+1
78    %endrep
79    
80    ALIGN 16
81    mmx_div:                ;quant>2
82            times 4 dw 65535 ; the div by 2 formula will overflow for the case
83                             ; quant=1 but we don't care much because quant=1
84                             ; is handled by a different piece of code that
85                             ; doesn't use this table.
86    %assign quant 2
87    %rep 31
88            times 4 dw  ((1 << 16) / quant + 1)
89            %assign quant quant+1
90    %endrep
91    
92    %macro FIXX 1
93    dw (1 << 16) / (%1) + 1
94    %endmacro
95    
96    %define nop4    db      08Dh, 074h, 026h,0
97    %define nop3    add     esp, byte 0
98    %define nop2    mov     esp, esp
99    %define nop7    db      08dh, 02ch, 02dh,0,0,0,0
100    %define nop6    add     ebp, dword 0
101    
102    ;-----------------------------------------------------------------------------
103    ; quantd table
104    ;-----------------------------------------------------------------------------
105    
106    %define VM18P   3
107    %define VM18Q   4
108    
109    ALIGN 16
110    quantd:
111    %assign i 1
112    %rep 31
113            times 4 dw  (((VM18P*i) + (VM18Q/2)) / VM18Q)
114            %assign i i+1
115    %endrep
116    
117    ;-----------------------------------------------------------------------------
118    ; multiple by 2Q table
119    ;-----------------------------------------------------------------------------
120    
121    ALIGN 16
122    mmx_mul_quant:
123    %assign i 1
124    %rep 31
125            times 4 dw  i
126            %assign i i+1
127    %endrep
128    
129    ;-----------------------------------------------------------------------------
130    ; saturation limits
131    ;-----------------------------------------------------------------------------
132    
133    ALIGN 16
134    mmx_32767_minus_2047:
135            times 4 dw (32767-2047)
136    mmx_32768_minus_2048:
137            times 4 dw (32768-2048)
138    mmx_2047:
139            times 4 dw 2047
140    mmx_minus_2048:
141            times 4 dw (-2048)
142    zero:
143            times 4 dw 0
144    
145    int_div:
146    dd 0
147    %assign i 1
148    %rep 255
149            dd  (1 << 17) / ( i) + 1
150            %assign i i+1
151    %endrep
152    
153    ;=============================================================================
154    ; Code
155    ;=============================================================================
156    
157    SECTION .text
158    
159    cglobal quant_mpeg_intra_xmm
160    cglobal quant_mpeg_inter_xmm
161    cglobal dequant_mpeg_intra_3dne
162    cglobal dequant_mpeg_inter_3dne
163    
164    ;-----------------------------------------------------------------------------
165    ;
166    ; uint32_t quant_mpeg_intra_xmm(int16_t * coeff,
167    ;                               const int16_t const * data,
168    ;                               const uint32_t quant,
169    ;                               const uint32_t dcscalar,
170    ;                               const uint16_t *mpeg_matrices);
171    ;
172    ;-----------------------------------------------------------------------------
173    
174    ALIGN 16
175    quant_mpeg_intra_xmm:
176      mov eax, [esp  + 8]       ; data
177      mov ecx, [esp  + 12]      ; quant
178      mov edx, [esp  + 4]       ; coeff
179      push esi
180      push edi
181      push ebx
182      nop
183      mov edi, [esp + 12 + 20]              ; mpeg_quant_matrices
184      mov esi, -14
185      pxor mm0, mm0
186      pxor mm3, mm3
187      cmp ecx, byte 1
188      je near .q1loop
189      cmp ecx, byte 19
190      jg near .lloop
191      nop6
192    
193    ALIGN 16
194    .loop
195      movq mm1, [eax + 8*esi+112]   ; mm0 = [1st]
196      psubw mm0, mm1                ;-mm1
197      movq mm4, [eax + 8*esi + 120] ;
198      psubw mm3, mm4                ;-mm4
199      pmaxsw mm0, mm1               ;|src|
200      pmaxsw mm3,mm4
201      nop2
202      psraw mm1, 15     ;sign src
203      psraw mm4, 15
204      psllw mm0, 4      ;level << 4 ;
205      psllw mm3, 4
206      paddw mm0, [edi + 128 + 8*esi+112]
207      paddw mm3, [edi + 128 + 8*esi+120]
208      movq mm5, [edi + 384 + 8*esi+112]
209      movq mm7, [edi + 384 + 8*esi+120]
210      pmulhuw mm5, mm0
211      pmulhuw mm7, mm3
212      mov esp, esp
213      movq mm2, [edi + 8*esi+112]
214      movq mm6, [edi + 8*esi+120]
215      pmullw mm2, mm5
216      pmullw mm6, mm7
217      psubw mm0, mm2
218      psubw mm3, mm6
219      nop4
220      movq mm2, [quantd + ecx * 8 - 8]
221      movq mm6, [mmx_divs + ecx * 8 - 8]
222      paddw mm5, mm2
223      paddw mm7, mm2
224      mov esp, esp
225      pmulhuw mm0, [edi + 256 + 8*esi+112]
226      pmulhuw mm3, [edi + 256 + 8*esi+120]
227      paddw mm5, mm0
228      paddw mm7, mm3
229      pxor mm0, mm0
230      pxor mm3, mm3
231      pmulhuw mm5, mm6      ; mm0 = (mm0 / 2Q) >> 16
232      pmulhuw mm7, mm6      ;  (level + quantd) / quant (0<quant<32)
233      pxor mm5, mm1         ; mm0 *= sign(mm0)
234      pxor mm7, mm4         ;
235      psubw mm5, mm1        ; undisplace
236      psubw mm7, mm4        ;
237      movq [edx + 8*esi+112], mm5
238      movq [edx + 8*esi +120], mm7
239      add esi, byte 2
240      jng near .loop
241    
242    .done
243    ; calculate  data[0] // (int32_t)dcscalar)
244      mov esi, [esp + 12 + 16]  ; dcscalar
245      movsx ecx, word [eax]
246      mov edi, ecx
247      mov edx, [esp + 12 + 16]
248      shr edx, 1            ; ebx = dcscalar /2
249      sar edi, 31           ; cdq is vectorpath
250      xor edx, edi          ; ebx = eax V -eax -1
251      sub ecx, edi
252      add ecx, edx
253      mov edx, [dword esp + 12 + 4]
254      mov esi, [int_div+4*esi]
255      imul ecx, esi
256      sar ecx, 17
257      lea ebx, [byte ecx + 1]
258      cmovs ecx, ebx
259      ; idiv    cx          ; ecx = edi:ecx / dcscalar
260    
261      mov ebx, [esp]
262      mov edi, [esp+4]
263      mov esi, [esp+8]
264      add esp, byte 12
265      mov [edx], cx     ; coeff[0] = ax
266    
267      xor eax, eax
268      ret
269    
270    ALIGN 16
271    .q1loop
272      movq mm1, [eax + 8*esi+112]               ; mm0 = [1st]
273      psubw mm0, mm1                            ;-mm1
274      movq mm4, [eax + 8*esi+120]               ;
275      psubw mm3, mm4                            ;-mm4
276      pmaxsw mm0, mm1                           ;|src|
277      pmaxsw mm3, mm4
278      nop2
279      psraw mm1, 15                             ;sign src
280      psraw mm4, 15
281      psllw mm0, 4                              ; level << 4
282      psllw mm3, 4
283      paddw mm0, [edi + 128 + 8*esi+112]    ;mm0 is to be divided
284      paddw mm3, [edi + 128 + 8*esi+120]    ;intra1 contains fix for division by 1
285      movq mm5, [edi + 384 + 8*esi+112] ;with rounding down
286      movq mm7, [edi + 384 + 8*esi+120]
287      pmulhuw mm5, mm0
288      pmulhuw mm7, mm3      ;mm7: first approx of division
289      mov esp, esp
290      movq mm2, [edi + 8*esi+112]
291      movq mm6, [edi + 8*esi+120]      ; divs for q<=16
292      pmullw mm2, mm5       ;test value <= original
293      pmullw mm6, mm7
294      psubw mm0, mm2        ;mismatch
295      psubw mm3, mm6
296      nop4
297      movq mm2, [quantd + ecx * 8 - 8]
298      paddw mm5, mm2        ;first approx with quantd
299      paddw mm7, mm2
300      mov esp, esp
301      pmulhuw mm0, [edi + 256 + 8*esi+112]   ;correction
302      pmulhuw mm3, [edi + 256 + 8*esi+120]
303      paddw mm5, mm0        ;final result with quantd
304      paddw mm7, mm3
305      pxor mm0, mm0
306      pxor mm3, mm3
307      mov esp, esp
308      psrlw mm5, 1          ;  (level + quantd) /2  (quant = 1)
309      psrlw mm7, 1
310      pxor mm5, mm1         ; mm0 *= sign(mm0)
311      pxor mm7, mm4         ;
312      psubw mm5, mm1        ; undisplace
313      psubw mm7, mm4        ;
314      movq [edx + 8*esi+112], mm5
315      movq [edx + 8*esi +120], mm7
316      add esi, byte 2
317      jng near .q1loop
318      jmp near .done
319    
320    ALIGN 8
321    .lloop
322      movq mm1, [eax + 8*esi+112]       ; mm0 = [1st]
323      psubw mm0, mm1        ;-mm1
324      movq mm4, [eax + 8*esi+120]
325      psubw mm3, mm4        ;-mm4
326      pmaxsw mm0, mm1       ;|src|
327      pmaxsw mm3, mm4
328      nop2
329      psraw mm1, 15         ;sign src
330      psraw mm4, 15
331      psllw mm0, 4          ; level << 4
332      psllw mm3, 4          ;
333      paddw mm0, [edi + 128 + 8*esi+112] ;mm0 is to be divided intra1 contains fix for division by 1
334      paddw mm3, [edi + 128 + 8*esi+120]
335      movq mm5, [edi + 384 + 8*esi+112]
336      movq mm7, [edi + 384 + 8*esi+120]
337      pmulhuw mm5, mm0
338      pmulhuw mm7, mm3      ;mm7: first approx of division
339      mov esp, esp
340      movq mm2, [edi + 8*esi+112]
341      movq mm6, [edi + 8*esi+120]
342      pmullw mm2, mm5       ;test value <= original
343      pmullw mm6, mm7
344      psubw mm0, mm2        ;mismatch
345      psubw mm3, mm6
346      nop4
347      movq mm2, [quantd + ecx * 8 - 8]
348      movq mm6, [mmx_div + ecx * 8 - 8] ; divs for q<=16
349      paddw mm5, mm2        ;first approx with quantd
350      paddw mm7, mm2
351      mov esp, esp
352      pmulhuw mm0, [edi + 256 + 8*esi+112] ;correction
353      pmulhuw mm3, [edi + 256 + 8*esi+120]
354      paddw mm5, mm0        ;final result with quantd
355      paddw mm7, mm3
356      pxor mm0, mm0
357      pxor mm3, mm3
358      mov esp, esp
359      pmulhuw mm5, mm6      ; mm0 = (mm0 / 2Q) >> 16
360      pmulhuw mm7, mm6      ;  (level + quantd) / quant (0<quant<32)
361      psrlw mm5, 1          ; (level + quantd) / (2*quant)
362      psrlw mm7, 1
363      pxor mm5, mm1         ; mm0 *= sign(mm0)
364      pxor mm7, mm4         ;
365      psubw mm5, mm1        ; undisplace
366      psubw mm7, mm4        ;
367      movq [edx + 8*esi+112], mm5
368      movq [edx + 8*esi +120], mm7
369      add esi,byte 2
370      jng near .lloop
371      jmp near .done
372    
373    ;-----------------------------------------------------------------------------
374    ;
375    ; uint32_t quant_mpeg_inter_xmm(int16_t * coeff,
376    ;                               const int16_t const * data,
377    ;                               const uint32_t quant,
378    ;                               const uint16_t *mpeg_matrices);
379    ;
380    ;-----------------------------------------------------------------------------
381    
382    ALIGN 16
383    quant_mpeg_inter_xmm:
384      mov eax, [esp  + 8]       ; data
385      mov ecx, [esp  + 12]      ; quant
386      mov edx, [esp  + 4]       ; coeff
387      push esi
388      push edi
389      push ebx
390      nop
391      mov edi, [esp + 12 + 16]
392      mov esi, -14
393      mov ebx, esp
394      sub esp, byte 24
395      lea ebx, [esp+8]
396      and ebx, byte -8 ;ALIGN 8
397      pxor mm0, mm0
398      pxor mm3, mm3
399      movq [byte ebx],mm0
400      db 0Fh, 7Fh, 44h, 23h, 8 ;movq [ebx+8],mm0
401      cmp ecx, byte 1
402      je near .q1loop
403      cmp ecx, byte 19
404      jg near .lloop
405      nop
406    
407    ALIGN 16
408    .loop
409      movq mm1, [eax + 8*esi+112]       ; mm0 = [1st]
410      psubw mm0, mm1 ;-mm1
411      movq mm4, [eax + 8*esi + 120] ;
412      psubw mm3, mm4 ;-mm4
413      pmaxsw mm0, mm1 ;|src|
414      pmaxsw mm3, mm4
415      nop2
416      psraw mm1, 15         ;sign src
417      psraw mm4, 15
418      psllw mm0, 4          ; level << 4
419      psllw mm3, 4          ;
420      paddw mm0, [edi + 640 + 8*esi+112]
421      paddw mm3, [edi + 640 + 8*esi+120]
422      movq mm5, [edi + 896 + 8*esi+112]
423      movq mm7, [edi + 896 + 8*esi+120]
424      pmulhuw mm5, mm0
425      pmulhuw mm7, mm3
426      mov esp, esp
427      movq mm2, [edi + 512 + 8*esi+112]
428      movq mm6, [edi + 512 + 8*esi+120]
429      pmullw mm2, mm5
430      pmullw mm6, mm7
431      psubw mm0, mm2
432      psubw mm3, mm6
433      movq mm2, [byte ebx]
434      movq mm6, [mmx_divs + ecx * 8 - 8]
435      pmulhuw mm0, [edi + 768 + 8*esi+112]
436      pmulhuw mm3, [edi + 768 + 8*esi+120]
437      paddw mm2, [ebx+8]    ;sum
438      paddw mm5, mm0
439      paddw mm7, mm3
440      pxor mm0, mm0
441      pxor mm3, mm3
442      pmulhuw mm5, mm6      ; mm0 = (mm0 / 2Q) >> 16
443      pmulhuw mm7, mm6      ;  (level ) / quant (0<quant<32)
444      add esi, byte 2
445      paddw mm2, mm5        ;sum += x1
446      movq [ebx], mm7       ;store x2
447      pxor mm5, mm1         ; mm0 *= sign(mm0)
448      pxor mm7, mm4         ;
449      psubw mm5, mm1        ; undisplace
450      psubw mm7, mm4        ;
451      db 0Fh, 7Fh, 54h, 23h, 08 ;movq   [ebx+8],mm2 ;store sum
452      movq [edx + 8*esi+112-16], mm5
453      movq [edx + 8*esi +120-16], mm7
454      jng near .loop
455    
456    .done
457    ; calculate  data[0] // (int32_t)dcscalar)
458      paddw mm2, [ebx]
459      mov ebx, [esp+24]
460      mov edi, [esp+4+24]
461      mov esi, [esp+8+24]
462      add esp, byte 12+24
463      pmaddwd mm2, [mmx_one]
464      punpckldq mm0, mm2 ;get low dw to mm0:high
465      paddd mm0,mm2
466      punpckhdq mm0, mm0 ;get result to low
467      movd eax, mm0
468    
469      ret
470    
471    ALIGN 16
472    .q1loop
473      movq mm1, [eax + 8*esi+112]       ; mm0 = [1st]
474      psubw mm0, mm1                    ;-mm1
475      movq mm4, [eax + 8*esi+120]
476      psubw mm3, mm4                    ;-mm4
477      pmaxsw mm0, mm1                   ;|src|
478      pmaxsw mm3, mm4
479      nop2
480      psraw mm1, 15                             ; sign src
481      psraw mm4, 15
482      psllw mm0, 4                              ; level << 4
483      psllw mm3, 4
484      paddw mm0, [edi + 640 + 8*esi+112]    ;mm0 is to be divided
485      paddw mm3, [edi + 640 + 8*esi+120]    ; inter1 contains fix for division by 1
486      movq mm5, [edi + 896 + 8*esi+112] ;with rounding down
487      movq mm7, [edi + 896 + 8*esi+120]
488      pmulhuw mm5, mm0
489      pmulhuw mm7, mm3                          ;mm7: first approx of division
490      mov esp, esp
491      movq mm2, [edi + 512 + 8*esi+112]
492      movq mm6, [edi + 512 + 8*esi+120]      ; divs for q<=16
493      pmullw mm2, mm5                           ;test value <= original
494      pmullw mm6, mm7
495      psubw mm0, mm2                            ;mismatch
496      psubw mm3, mm6
497      movq mm2, [byte ebx]
498      pmulhuw mm0, [edi + 768 + 8*esi+112]  ;correction
499      pmulhuw mm3, [edi + 768 + 8*esi+120]
500      paddw mm2, [ebx+8]    ;sum
501      paddw mm5, mm0        ;final result
502      paddw mm7, mm3
503      pxor mm0, mm0
504      pxor mm3, mm3
505      psrlw mm5, 1          ;  (level ) /2  (quant = 1)
506      psrlw mm7, 1
507      add esi, byte 2
508      paddw mm2, mm5        ;sum += x1
509      movq [ebx], mm7       ;store x2
510      pxor mm5, mm1         ; mm0 *= sign(mm0)
511      pxor mm7, mm4         ;
512      psubw mm5, mm1        ; undisplace
513      psubw mm7, mm4        ;
514      movq [ebx+8], mm2     ;store sum
515      movq [edx + 8*esi+112-16], mm5
516      movq [edx + 8*esi +120-16], mm7
517      jng near .q1loop
518      jmp near .done
519    
520    ALIGN 8
521    .lloop
522      movq mm1, [eax + 8*esi+112]       ; mm0 = [1st]
523      psubw mm0,mm1         ;-mm1
524      movq mm4, [eax + 8*esi+120]
525      psubw mm3,mm4         ;-mm4
526      pmaxsw mm0,mm1        ;|src|
527      pmaxsw mm3,mm4
528      nop2
529      psraw mm1,15          ;sign src
530      psraw mm4,15
531      psllw mm0, 4          ; level << 4
532      psllw mm3, 4          ;
533      paddw mm0, [edi + 640 + 8*esi+112] ;mm0 is to be divided inter1 contains fix for division by 1
534      paddw mm3, [edi + 640 + 8*esi+120]
535      movq mm5,[edi + 896 + 8*esi+112]
536      movq mm7,[edi + 896 + 8*esi+120]
537      pmulhuw mm5,mm0
538      pmulhuw mm7,mm3       ;mm7: first approx of division
539      mov esp,esp
540      movq mm2,[edi + 512 + 8*esi+112]
541      movq mm6,[edi + 512 + 8*esi+120]
542      pmullw mm2,mm5        ;test value <= original
543      pmullw mm6,mm7
544      psubw mm0,mm2         ;mismatch
545      psubw mm3,mm6
546      movq mm2,[byte ebx]
547      movq mm6,[mmx_div + ecx * 8 - 8]  ; divs for q<=16
548      pmulhuw mm0,[edi + 768 + 8*esi+112] ;correction
549      pmulhuw mm3,[edi + 768 + 8*esi+120]
550      paddw mm2,[ebx+8]     ;sum
551      paddw mm5,mm0         ;final result
552      paddw mm7,mm3
553      pxor mm0,mm0
554      pxor mm3,mm3
555      pmulhuw mm5, mm6      ; mm0 = (mm0 / 2Q) >> 16
556      pmulhuw mm7, mm6      ;  (level ) / quant (0<quant<32)
557      add esi,byte 2
558      psrlw mm5, 1          ; (level ) / (2*quant)
559      paddw mm2,mm5         ;sum += x1
560      psrlw mm7, 1
561      movq [ebx],mm7        ;store x2
562      pxor mm5, mm1         ; mm0 *= sign(mm0)
563      pxor mm7, mm4         ;
564      psubw mm5, mm1        ; undisplace
565      psubw mm7, mm4        ;
566      db 0Fh, 7Fh, 54h, 23h, 08 ;movq   [ebx+8],mm2 ;store sum
567      movq [edx + 8*esi+112-16], mm5
568      movq [edx + 8*esi +120-16], mm7
569      jng near .lloop
570      jmp near .done
571    
572    
573    ;-----------------------------------------------------------------------------
574    ;
575    ; uint32_t dequant_mpeg_intra_3dne(int16_t *data,
576    ;                                  const int16_t const *coeff,
577    ;                                  const uint32_t quant,
578    ;                                  const uint32_t dcscalar,
579    ;                                  const uint16_t *mpeg_matrices);
580    ;
581    ;-----------------------------------------------------------------------------
582    
583      ;   Note: in order to saturate 'easily', we pre-shift the quantifier
584      ; by 4. Then, the high-word of (coeff[]*matrix[i]*quant) are used to
585      ; build a saturating mask. It is non-zero only when an overflow occured.
586      ; We thus avoid packing/unpacking toward double-word.
587      ; Moreover, we perform the mult (matrix[i]*quant) first, instead of, e.g.,
588      ; (coeff[i]*matrix[i]). This is less prone to overflow if coeff[] are not
589      ; checked. Input ranges are: coeff in [-127,127], inter_matrix in [1..255],a
590      ; and quant in [1..31].
591      ;
592    
593    %macro DEQUANT4INTRAMMX 1
594      movq mm1, [byte ecx+ 16 * %1] ; mm0 = c  = coeff[i]
595      movq mm4, [ecx+ 16 * %1 +8]   ; mm3 = c' = coeff[i+1]
596      psubw mm0, mm1
597      psubw mm3, mm4
598      pmaxsw mm0, mm1
599      pmaxsw mm3, mm4
600      psraw mm1, 15
601      psraw mm4, 15
602    %if %1
603      movq mm2, [eax+8] ;preshifted quant
604      movq mm7, [eax+8]
605    %endif
606      pmullw mm2, [edi + 16 * %1 ]     ; matrix[i]*quant
607      pmullw mm7, [edi + 16 * %1 +8]   ; matrix[i+1]*quant
608      movq mm5, mm0
609      movq mm6, mm3
610      pmulhw mm0, mm2   ; high of coeff*(matrix*quant)
611      pmulhw mm3, mm7   ; high of coeff*(matrix*quant)
612      pmullw mm2, mm5   ; low  of coeff*(matrix*quant)
613      pmullw mm7, mm6   ; low  of coeff*(matrix*quant)
614      pcmpgtw mm0, [eax]
615      pcmpgtw mm3, [eax]
616      paddusw mm2, mm0
617      paddusw mm7, mm3
618      psrlw mm2, 5
619      psrlw mm7, 5
620      pxor mm2, mm1     ; start negating back
621      pxor mm7, mm4     ; start negating back
622      psubusw mm1, mm0
623      psubusw mm4, mm3
624      movq mm0, [eax]   ;zero
625      movq mm3, [eax]   ;zero
626      psubw mm2, mm1    ; finish negating back
627      psubw mm7, mm4    ; finish negating back
628      movq [byte edx + 16 * %1], mm2   ; data[i]
629      movq [edx + 16 * %1  +8], mm7   ; data[i+1]
630    %endmacro
631    
632    ALIGN 16
633    dequant_mpeg_intra_3dne:
634      mov eax, [esp+12] ; quant
635      mov ecx, [esp+8]  ; coeff
636      movq mm7, [mmx_mul_quant  + eax*8 - 8]
637      psllw mm7, 2      ; << 2. See comment.
638      mov edx, [esp+4]  ; data
639      push ebx
640      movsx ebx, word [ecx]
641      pxor mm0, mm0
642      pxor mm3, mm3
643      push esi
644      lea eax, [esp-28]
645      sub esp, byte 32
646      and eax, byte -8  ;points to qword ALIGNed space on stack
647      movq [eax], mm0
648      movq [eax+8], mm7
649      imul ebx, [esp+16+8+32]    ; dcscalar
650      movq mm2, mm7
651      push edi
652      mov edi, [esp + 32 + 12 + 20] ; mpeg_quant_matrices
653    ALIGN 4
654    
655      DEQUANT4INTRAMMX 0
656    
657      mov esi, -2048
658      nop
659      cmp ebx, esi
660    
661      DEQUANT4INTRAMMX 1
662    
663      cmovl ebx, esi
664      neg esi
665      sub esi, byte 1 ;2047
666    
667      DEQUANT4INTRAMMX 2
668    
669      cmp ebx, esi
670      cmovg ebx, esi
671      lea ebp, [byte ebp]
672    
673      DEQUANT4INTRAMMX 3
674    
675      mov esi, [esp+36]
676      mov [byte edx], bx
677      mov ebx, [esp+36+4]
678    
679      DEQUANT4INTRAMMX 4
680      DEQUANT4INTRAMMX 5
681      DEQUANT4INTRAMMX 6
682      DEQUANT4INTRAMMX 7
683    
684      pop edi
685    
686      add esp, byte 32+8
687    
688      xor eax, eax
689      ret
690    
691    ;-----------------------------------------------------------------------------
692    ;
693    ; uint32_t dequant_mpeg_inter_3dne(int16_t * data,
694    ;                                  const int16_t * const coeff,
695    ;                                  const uint32_t quant,
696    ;                                  const uint16_t *mpeg_matrices);
697    ;
698    ;-----------------------------------------------------------------------------
699    
700        ; Note:  We use (2*c + sgn(c) - sgn(-c)) as multiplier
701        ; so we handle the 3 cases: c<0, c==0, and c>0 in one shot.
702        ; sgn(x) is the result of 'pcmpgtw 0,x':  0 if x>=0, -1 if x<0.
703        ; It's mixed with the extraction of the absolute value.
704    
705    ALIGN 16
706    dequant_mpeg_inter_3dne:
707      mov edx, [esp+ 4]        ; data
708      mov ecx, [esp+ 8]        ; coeff
709      mov eax, [esp+12]        ; quant
710      movq mm7, [mmx_mul_quant  + eax*8 - 8]
711      mov eax, -14
712      paddw mm7, mm7    ; << 1
713      pxor mm6, mm6     ; mismatch sum
714      push esi
715      push edi
716      mov esi, mmzero
717      pxor mm1, mm1
718      pxor mm3, mm3
719      mov edi, [esp + 8 + 16] ; mpeg_quant_matrices
720      nop
721      nop4
722    
723    ALIGN 16
724    .loop
725      movq mm0, [ecx+8*eax + 7*16   ]   ; mm0 = coeff[i]
726      pcmpgtw mm1, mm0  ; mm1 = sgn(c)    (preserved)
727      movq mm2, [ecx+8*eax + 7*16 +8]   ; mm2 = coeff[i+1]
728      pcmpgtw mm3, mm2  ; mm3 = sgn(c')   (preserved)
729      paddsw mm0, mm1   ; c += sgn(c)
730      paddsw mm2, mm3   ; c += sgn(c')
731      paddw mm0, mm0    ; c *= 2
732      paddw mm2, mm2    ; c'*= 2
733    
734      movq mm4, [esi]
735      movq mm5, [esi]
736      psubw mm4, mm0    ; -c
737      psubw mm5, mm2    ; -c'
738    
739      psraw mm4, 16     ; mm4 = sgn(-c)
740      psraw mm5, 16     ; mm5 = sgn(-c')
741      psubsw mm0, mm4   ; c  -= sgn(-c)
742      psubsw mm2, mm5   ; c' -= sgn(-c')
743      pxor mm0, mm1     ; finish changing sign if needed
744      pxor mm2, mm3     ; finish changing sign if needed
745    
746     ; we're short on register, here. Poor pairing...
747    
748      movq mm4, mm7     ; (matrix*quant)
749      nop
750      pmullw mm4, [edi + 512 + 8*eax + 7*16]
751      movq mm5, mm4
752      pmulhw mm5, mm0   ; high of c*(matrix*quant)
753      pmullw mm0, mm4   ; low  of c*(matrix*quant)
754    
755      movq mm4, mm7     ; (matrix*quant)
756      pmullw mm4, [edi + 512 + 8*eax + 7*16 + 8]
757      add eax, byte 2
758    
759      pcmpgtw mm5, [esi]
760      paddusw mm0, mm5
761      psrlw mm0, 5
762      pxor mm0, mm1     ; start restoring sign
763      psubusw mm1, mm5
764    
765      movq mm5, mm4
766      pmulhw mm5, mm2   ; high of c*(matrix*quant)
767      pmullw mm2, mm4   ; low  of c*(matrix*quant)
768      psubw mm0, mm1    ; finish restoring sign
769    
770      pcmpgtw mm5, [esi]
771      paddusw mm2, mm5
772      psrlw mm2, 5
773      pxor mm2, mm3     ; start restoring sign
774      psubusw mm3, mm5
775      psubw mm2, mm3    ; finish restoring sign
776      movq mm1, [esi]
777      movq mm3, [byte esi]
778      pxor mm6, mm0                             ; mismatch control
779      movq [edx + 8*eax + 7*16 -2*8   ], mm0    ; data[i]
780      pxor mm6, mm2                             ; mismatch control
781      movq [edx + 8*eax + 7*16 -2*8 +8], mm2    ; data[i+1]
782    
783      jng .loop
784      nop
785    
786     ; mismatch control
787    
788      pshufw mm0, mm6, 01010101b
789      pshufw mm1, mm6, 10101010b
790      pshufw mm2, mm6, 11111111b
791      pxor mm6, mm0
792      pxor mm1, mm2
793      pxor mm6, mm1
794      movd eax, mm6
795      pop edi
796      and eax, byte 1
797      xor eax, byte 1
798      mov esi, [esp]
799      add esp, byte 4
800      xor word [edx + 2*63], ax
801    
802      xor eax, eax
803      ret

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

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