[svn] / branches / dev-api-4 / xvidcore / src / quant / x86_asm / quantize4_mmx.asm Repository:
ViewVC logotype

Diff of /branches/dev-api-4/xvidcore/src/quant/x86_asm/quantize4_mmx.asm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

trunk/xvidcore/src/quant/x86_asm/quantize4_mmx.asm revision 3, Fri Mar 8 02:46:11 2002 UTC branches/dev-api-4/xvidcore/src/quant/x86_asm/quantize4_mmx.asm revision 886, Fri Feb 21 14:49:29 2003 UTC
# Line 42  Line 42 
42  ; *                                                                            *  ; *                                                                            *
43  ; *  Revision history:                                                         *  ; *  Revision history:                                                         *
44  ; *                                                                            *  ; *                                                                            *
45    ; *  14.06.2002  mmx dequant4_* funcs revamped  -Skal-                         *
46  ; *  22.01.2002 initial version                                                *  ; *  22.01.2002 initial version                                                *
47  ; *                                                                            *  ; *                                                                            *
48  ; ******************************************************************************/  ; ******************************************************************************/
# Line 53  Line 54 
54    
55  bits 32  bits 32
56    
57  section .data  %ifdef FORMAT_COFF
58    SECTION .data data
59    %else
60    SECTION .data data align=8
61    %endif
62    
63    
64  %macro cglobal 1  %macro cglobal 1
65          %ifdef PREFIX          %ifdef PREFIX
# Line 64  Line 70 
70          %endif          %endif
71  %endmacro  %endmacro
72    
73    %macro cextern 1
74            %ifdef PREFIX
75                    extern _%1
76                    %define %1 _%1
77            %else
78                    extern %1
79            %endif
80    %endmacro
81    
82  mmx_one times 4 dw       1  mmx_one times 4 dw       1
83    
84  ;===========================================================================  ;===========================================================================
# Line 113  Line 128 
128    
129  ;===========================================================================  ;===========================================================================
130  ;  ;
131  ; default intra matrix  ; intra matrix
132  ;  ;
133  ;===========================================================================  ;===========================================================================
134    
135  mmx_intra_matrix  cextern intra_matrix
136                  dw 8, 17, 18, 19  cextern intra_matrix_fix
                 dw 21, 23, 25, 27  
                 dw 17, 18, 19, 21  
                 dw 23, 25, 27, 28  
                 dw 20, 21, 22, 23  
                 dw 24, 26, 28, 30  
                 dw 21, 22, 23, 24  
                 dw 26, 28, 30, 32  
                 dw 22, 23, 24, 26  
                 dw 28, 30, 32, 35  
                 dw 23, 24, 26, 28  
                 dw 30, 32, 35, 38  
                 dw 25, 26, 28, 30  
                 dw 32, 35, 38, 41  
                 dw 27, 28, 30, 32  
                 dw 35, 38, 41, 45  
   
 %macro MMX_FIX  4  
 dw (1 << 16) / (%1) + 1, (1 << 16) / (%2) + 1, (1 << 16) / (%3) + 1, (1 << 16) / (%4) + 1  
 %endmacro  
   
 mmx_intra_matrix_fix  
                 MMX_FIX 8, 17, 18, 19  
                 MMX_FIX 21, 23, 25, 27  
                 MMX_FIX 17, 18, 19, 21  
                 MMX_FIX 23, 25, 27, 28  
                 MMX_FIX 20, 21, 22, 23  
                 MMX_FIX 24, 26, 28, 30  
                 MMX_FIX 21, 22, 23, 24  
                 MMX_FIX 26, 28, 30, 32  
                 MMX_FIX 22, 23, 24, 26  
                 MMX_FIX 28, 30, 32, 35  
                 MMX_FIX 23, 24, 26, 28  
                 MMX_FIX 30, 32, 35, 38  
                 MMX_FIX 25, 26, 28, 30  
                 MMX_FIX 32, 35, 38, 41  
                 MMX_FIX 27, 28, 30, 32  
                 MMX_FIX 35, 38, 41, 45  
   
137    
138  ;===========================================================================  ;===========================================================================
139  ;  ;
140  ; default inter matrix  ; inter matrix
141  ;  ;
142  ;===========================================================================  ;===========================================================================
143    
144  mmx_inter_matrix  cextern inter_matrix
145                  dw 16,17,18,19  cextern inter_matrix_fix
146                  dw 20,21,22,23  
                 dw 17,18,19,20  
                 dw 21,22,23,24  
                 dw 18,19,20,21  
                 dw 22,23,24,25  
                 dw 19,20,21,22  
                 dw 23,24,26,27  
                 dw 20,21,22,23  
                 dw 25,26,27,28  
                 dw 21,22,23,24  
                 dw 26,27,28,30  
                 dw 22,23,24,26  
                 dw 27,28,30,31  
                 dw 23,24,25,27  
                 dw 28,30,31,33  
   
   
 mmx_inter_matrix_fix  
                 MMX_FIX 16,17,18,19  
                 MMX_FIX 20,21,22,23  
                 MMX_FIX 17,18,19,20  
                 MMX_FIX 21,22,23,24  
                 MMX_FIX 18,19,20,21  
                 MMX_FIX 22,23,24,25  
                 MMX_FIX 19,20,21,22  
                 MMX_FIX 23,24,26,27  
                 MMX_FIX 20,21,22,23  
                 MMX_FIX 25,26,27,28  
                 MMX_FIX 21,22,23,24  
                 MMX_FIX 26,27,28,30  
                 MMX_FIX 22,23,24,26  
                 MMX_FIX 27,28,30,31  
                 MMX_FIX 23,24,25,27  
                 MMX_FIX 28,30,31,33  
147    
148  %define VM18P 3  %define VM18P 3
149  %define VM18Q 4  %define VM18Q 4
150    
151    
152  ;===========================================================================  ;===========================================================================
153  ;  ;
154  ; quantd table  ; quantd table
# Line 250  Line 195 
195    
196  ;===========================================================================  ;===========================================================================
197  ;  ;
 ; multiple by matrix table  
 ;  
 ;===========================================================================  
   
 %macro MMX_MUL 4  
 dw  %1  
 dw  %2  
 dw  %3  
 dw  %4  
 %endmacro  
   
 default_inter_matrix_mul  
         MMX_MUL    16,17,18,19  
         MMX_MUL    20,21,22,23  
         MMX_MUL    17,18,19,20  
         MMX_MUL    21,22,23,24  
         MMX_MUL    18,19,20,21  
         MMX_MUL    22,23,24,25  
         MMX_MUL    19,20,21,22  
         MMX_MUL    23,24,26,27  
         MMX_MUL    20,21,22,23  
         MMX_MUL    25,26,27,28  
         MMX_MUL    21,22,23,24  
         MMX_MUL    26,27,28,30  
         MMX_MUL    22,23,24,26  
         MMX_MUL    27,28,30,31  
         MMX_MUL    23,24,25,27  
         MMX_MUL    28,30,31,33  
   
   
 default_intra_matrix_mul  
         MMX_MUL 8,17,18,19  
         MMX_MUL 21,23,25,27  
         MMX_MUL 17,18,19,21  
         MMX_MUL 23,25,27,28  
         MMX_MUL 20,21,22,23  
         MMX_MUL 24,26,28,30  
         MMX_MUL 21,22,23,24  
         MMX_MUL 26,28,30,32  
         MMX_MUL 22,23,24,26  
         MMX_MUL 28,30,32,35  
         MMX_MUL 23,24,26,28  
         MMX_MUL 30,32,35,38  
         MMX_MUL 25,26,28,30  
         MMX_MUL 32,35,38,41  
         MMX_MUL 27,28,30,32  
         MMX_MUL 35,38,41,45  
   
   
 ;===========================================================================  
 ;  
198  ; multiple by 2Q table  ; multiple by 2Q table
199  ;  ;
200  ;===========================================================================  ;===========================================================================
# Line 349  Line 243 
243  ;===========================================================================  ;===========================================================================
244    
245  align 16  align 16
246  mmx_32768_minus_2048                times 4 dw (32768-2048)  
247  mmx_32767_minus_2047                times 4 dw (32767-2047)  mmx_32767_minus_2047                times 4 dw (32767-2047)
248    mmx_32768_minus_2048                            times 4 dw (32768-2048)
249    mmx_2047 times 4 dw 2047
250    mmx_minus_2048 times 4 dw (-2048)
251    zero times 4 dw 0
252    
253  section .text  section .text
254    
# Line 405  Line 303 
303                  psllw   mm0, 4                  ; level << 4                  psllw   mm0, 4                  ; level << 4
304                  psllw   mm3, 4                  ;                  psllw   mm3, 4                  ;
305    
306                  movq    mm2, [mmx_intra_matrix + 8*ecx]                  movq    mm2, [intra_matrix + 8*ecx]
307                  psrlw   mm2, 1                  ; intra_matrix[i]>>1                  psrlw   mm2, 1                  ; intra_matrix[i]>>1
308                  paddw   mm0, mm2                  paddw   mm0, mm2
309    
310                  movq    mm2, [mmx_intra_matrix_fix + ecx*8]                  movq    mm2, [intra_matrix_fix + ecx*8]
311                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
312    
313                  movq    mm2, [mmx_intra_matrix + 8*ecx + 8]                  movq    mm2, [intra_matrix + 8*ecx + 8]
314                  psrlw   mm2, 1                  psrlw   mm2, 1
315                  paddw   mm3, mm2                  paddw   mm3, mm2
316    
317                  movq    mm2, [mmx_intra_matrix_fix + ecx*8 + 8]                  movq    mm2, [intra_matrix_fix + ecx*8 + 8]
318                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
319    
320              paddw   mm0, mm5            ; + quantd              paddw   mm0, mm5            ; + quantd
# Line 484  Line 382 
382                  psllw   mm0, 4                  psllw   mm0, 4
383                  psllw   mm3, 4                  psllw   mm3, 4
384    
385                  movq    mm2, [mmx_intra_matrix + 8*ecx]                  movq    mm2, [intra_matrix + 8*ecx]
386                  psrlw   mm2, 1                  psrlw   mm2, 1
387                  paddw   mm0, mm2                  paddw   mm0, mm2
388    
389                  movq    mm2, [mmx_intra_matrix_fix + ecx*8]                  movq    mm2, [intra_matrix_fix + ecx*8]
390                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
391    
392                  movq    mm2, [mmx_intra_matrix + 8*ecx + 8]                  movq    mm2, [intra_matrix + 8*ecx + 8]
393                  psrlw   mm2, 1                  psrlw   mm2, 1
394                  paddw   mm3, mm2                  paddw   mm3, mm2
395    
396                  movq    mm2, [mmx_intra_matrix_fix + ecx*8 + 8]                  movq    mm2, [intra_matrix_fix + ecx*8 + 8]
397                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
398    
399          paddw   mm0, mm5          paddw   mm0, mm5
# Line 537  Line 435 
435                  psllw   mm0, 4                  psllw   mm0, 4
436                  psllw   mm3, 4                  psllw   mm3, 4
437    
438                  movq    mm2, [mmx_intra_matrix + 8*ecx]                  movq    mm2, [intra_matrix + 8*ecx]
439                  psrlw   mm2, 1                  psrlw   mm2, 1
440                  paddw   mm0, mm2                  paddw   mm0, mm2
441    
442                  movq    mm2, [mmx_intra_matrix_fix + ecx*8]                  movq    mm2, [intra_matrix_fix + ecx*8]
443                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
444    
445                  movq    mm2, [mmx_intra_matrix + 8*ecx + 8]                  movq    mm2, [intra_matrix + 8*ecx + 8]
446                  psrlw   mm2, 1                  psrlw   mm2, 1
447                  paddw   mm3, mm2                  paddw   mm3, mm2
448    
449                  movq    mm2, [mmx_intra_matrix_fix + ecx*8 + 8]                  movq    mm2, [intra_matrix_fix + ecx*8 + 8]
450                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
451    
452          paddw   mm0, mm5          paddw   mm0, mm5
# Line 619  Line 517 
517                  psllw   mm0, 4                  psllw   mm0, 4
518                  psllw   mm3, 4                  psllw   mm3, 4
519    
520                  movq    mm2, [mmx_inter_matrix + 8*ecx]                  movq    mm2, [inter_matrix + 8*ecx]
521                  psrlw   mm2, 1                  psrlw   mm2, 1
522                  paddw   mm0, mm2                  paddw   mm0, mm2
523    
524                  movq    mm2, [mmx_inter_matrix_fix + ecx*8]                  movq    mm2, [inter_matrix_fix + ecx*8]
525                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
526    
527                  movq    mm2, [mmx_inter_matrix + 8*ecx + 8]                  movq    mm2, [inter_matrix + 8*ecx + 8]
528                  psrlw   mm2, 1                  psrlw   mm2, 1
529                  paddw   mm3, mm2                  paddw   mm3, mm2
530    
531                  movq    mm2, [mmx_inter_matrix_fix + ecx*8 + 8]                  movq    mm2, [inter_matrix_fix + ecx*8 + 8]
532                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
533    
534                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16
# Line 683  Line 581 
581                  psllw   mm0, 4                  psllw   mm0, 4
582                  psllw   mm3, 4                  psllw   mm3, 4
583    
584                  movq    mm2, [mmx_inter_matrix + 8*ecx]                  movq    mm2, [inter_matrix + 8*ecx]
585                  psrlw   mm2, 1                  psrlw   mm2, 1
586                  paddw   mm0, mm2                  paddw   mm0, mm2
587    
588                  movq    mm2, [mmx_inter_matrix_fix + ecx*8]                  movq    mm2, [inter_matrix_fix + ecx*8]
589                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
590    
591                  movq    mm2, [mmx_inter_matrix + 8*ecx + 8]                  movq    mm2, [inter_matrix + 8*ecx + 8]
592                  psrlw   mm2, 1                  psrlw   mm2, 1
593                  paddw   mm3, mm2                  paddw   mm3, mm2
594    
595                  movq    mm2, [mmx_inter_matrix_fix + ecx*8 + 8]                  movq    mm2, [inter_matrix_fix + ecx*8 + 8]
596                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
597    
598                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)
# Line 736  Line 634 
634                  psllw   mm0, 4                  psllw   mm0, 4
635                  psllw   mm3, 4                  psllw   mm3, 4
636    
637                  movq    mm2, [mmx_inter_matrix + 8*ecx]                  movq    mm2, [inter_matrix + 8*ecx]
638                  psrlw   mm2, 1                  psrlw   mm2, 1
639                  paddw   mm0, mm2                  paddw   mm0, mm2
640    
641                  movq    mm2, [mmx_inter_matrix_fix + ecx*8]                  movq    mm2, [inter_matrix_fix + ecx*8]
642                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
643    
644                  movq    mm2, [mmx_inter_matrix + 8*ecx + 8]                  movq    mm2, [inter_matrix + 8*ecx + 8]
645                  psrlw   mm2, 1                  psrlw   mm2, 1
646                  paddw   mm3, mm2                  paddw   mm3, mm2
647    
648                  movq    mm2, [mmx_inter_matrix_fix + ecx*8 + 8]                  movq    mm2, [inter_matrix_fix + ecx*8 + 8]
649                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
650    
651                  psrlw   mm0, 2                  ; mm0 >>= 1   (/2)                  psrlw   mm0, 2                  ; mm0 >>= 1   (/2)
# Line 779  Line 677 
677  ;  ;
678  ;===========================================================================  ;===========================================================================
679    
680  align 16    ;   Note: in order to saturate 'easily', we pre-shift the quantifier
681  cglobal dequant4_intra_mmx    ; by 4. Then, the high-word of (coeff[]*matrix[i]*quant) are used to
682  dequant4_intra_mmx    ; build a saturating mask. It is non-zero only when an overflow occured.
683      ; We thus avoid packing/unpacking toward double-word.
684      ; Moreover, we perform the mult (matrix[i]*quant) first, instead of, e.g.,
685      ; (coeff[i]*matrix[i]). This is less prone to overflow if coeff[] are not
686      ; checked. Input ranges are: coeff in [-127,127], inter_matrix in [1..255],a
687      ; and quant in [1..31].
688      ;
689      ; The original loop is:
690      ;
691    %if 0
692      movq mm0, [ecx+8*eax + 8*16]   ; mm0 = coeff[i]
693      pxor mm1, mm1
694      pcmpgtw mm1, mm0
695      pxor mm0, mm1     ; change sign if negative
696      psubw mm0, mm1    ; -> mm0 = abs(coeff[i]), mm1 = sign of coeff[i]
697    
698      movq mm2, mm7     ; mm2 = quant
699      pmullw mm2,  [intra_matrix + 8*eax + 8*16 ]  ; matrix[i]*quant.
700    
701      movq mm6, mm2
702      pmulhw mm2, mm0   ; high of coeff*(matrix*quant)  (should be 0 if no overflow)
703      pmullw mm0, mm6   ; low  of coeff*(matrix*quant)
704    
705      pxor mm5, mm5
706      pcmpgtw mm2, mm5  ; otherflow?
707      psrlw mm2, 5      ; =0 if no clamp, 2047 otherwise
708      psrlw mm0, 5
709      paddw mm0, mm1    ; start restoring sign
710      por mm0, mm2      ; saturate to 2047 if needed
711      pxor mm0, mm1     ; finish negating back
712    
713          push    esi    movq [edx + 8*eax + 8*16], mm0   ; data[i]
714          push    edi    add eax, 1
715    %endif
716    
717          mov    edi, [esp + 8 + 4]        ; data    ;********************************************************************
         mov    esi, [esp + 8 + 8]        ; coeff  
         mov    eax, [esp + 8 + 12]        ; quant  
718    
719          movq mm7, [mmx_mul_quant  + eax*8 - 8]  align 16
720    cglobal dequant4_intra_mmx
721    dequant4_intra_mmx:
722    
723          xor eax, eax    mov edx, [esp+4]  ; data
724      mov ecx, [esp+8]  ; coeff
725      mov eax, [esp+12] ; quant
726    
727      movq mm7, [mmx_mul_quant  + eax*8 - 8]
728      mov eax, -16   ; to keep aligned, we regularly process coeff[0]
729      psllw mm7, 2   ; << 2. See comment.
730      pxor mm6, mm6   ; this is a NOP
731    
732  align 16  align 16
733  .loop  .loop
734          movq    mm0, [esi + 8*eax]        ; mm0 = [coeff]    movq mm0, [ecx+8*eax + 8*16]   ; mm0 = c  = coeff[i]
735      movq mm3, [ecx+8*eax + 8*16 +8]; mm3 = c' = coeff[i+1]
736      pxor mm1, mm1
737      pxor mm4, mm4
738      pcmpgtw mm1, mm0  ; mm1 = sgn(c)
739      movq mm2, mm7     ; mm2 = quant
740    
741          pxor    mm1, mm1                ; mm1 = 0    pcmpgtw mm4, mm3  ; mm4 = sgn(c')
742          pcmpeqw    mm1, mm0                ; mm1 = (0 == mm0)    pmullw mm2,  [intra_matrix + 8*eax + 8*16 ]  ; matrix[i]*quant
743    
744          pxor    mm2, mm2                ; mm2 = 0    pxor mm0, mm1     ; negate if negative
745          pcmpgtw    mm2, mm0                ; mm2 = (0 > mm0)    pxor mm3, mm4     ; negate if negative
         pxor    mm0, mm2                ; mm0 = |mm0|  
         psubw    mm0, mm2                ; displace  
746    
747          pmullw    mm0, mm7                ; mm0 *= quant    psubw mm0, mm1
748      psubw mm3, mm4
749    
750          movq    mm3, [default_intra_matrix_mul + 8*eax]      ; we're short on register, here. Poor pairing...
751    
752          movq  mm4, mm0                    ;    movq mm5, mm2
753          pmullw    mm0, mm3                ; mm0 = low(mm0 * mm3)    pmullw mm2, mm0   ; low  of coeff*(matrix*quant)
         pmulhw    mm3, mm4                ; mm3 = high(mm0 * mm3)  
754    
755          movq    mm4, mm0                ; mm0,mm4 = unpack(mm3, mm0)    pmulhw mm0, mm5   ; high of coeff*(matrix*quant)
756          punpcklwd mm0, mm3                ;    movq mm5, mm7     ; mm2 = quant
         punpckhwd mm4, mm3                ;  
         psrld mm0, 3                    ; mm0,mm4 /= 8  
         psrld mm4, 3                    ;  
         packssdw mm0, mm4                ; mm0 = pack(mm4, mm0)  
757    
758          pxor    mm0, mm2                ; mm0 *= sign(mm0)    pmullw mm5,  [intra_matrix + 8*eax + 8*16 +8]  ; matrix[i+1]*quant
         psubw    mm0, mm2                ; undisplace  
         pandn    mm1, mm0                ; mm1 = ~(iszero) & mm0  
759    
760  %ifdef SATURATE    movq mm6, mm5
761          movq mm2, [mmx_32767_minus_2047]    add eax,2   ; z-flag will be tested later
         movq mm6, [mmx_32768_minus_2048]  
         paddsw    mm1, mm2  
         psubsw    mm1, mm2  
         psubsw    mm1, mm6  
         paddsw    mm1, mm6  
 %endif  
762    
763          movq    [edi + 8*eax], mm1        ; [data] = mm0    pmullw mm6, mm3   ; low  of coeff*(matrix*quant)
764      pmulhw mm3, mm5   ; high of coeff*(matrix*quant)
765    
766          add eax, 1    pcmpgtw mm0, [zero]
767          cmp eax, 16    paddusw mm2, mm0
768          jnz    near .loop    psrlw mm2, 5
769    
770          mov    ax, [esi]                    ; ax = data[0]    pcmpgtw mm3, [zero]
771          imul     ax, [esp + 8 + 16]        ; eax = data[0] * dcscalar    paddusw mm6, mm3
772          mov    [edi], ax                    ; data[0] = ax    psrlw mm6, 5
   
 %ifdef SATURATE  
         cmp ax, -2048  
         jl .set_n2048  
         cmp ax, 2047  
         jg .set_2047  
 %endif  
773    
774          pop    edi    pxor mm2, mm1  ; start negating back
775          pop    esi    pxor mm6, mm4  ; start negating back
         ret  
776    
777  %ifdef SATURATE    psubusw mm1, mm0
778  .set_n2048    psubusw mm4, mm3
         mov    word [edi], -2048  
         pop    edi  
         pop    esi  
         ret  
779    
780  .set_2047    psubw mm2, mm1 ; finish negating back
781          mov    word [edi], 2047    psubw mm6, mm4 ; finish negating back
         pop    edi  
         pop    esi  
782    
783                  ret    movq [edx + 8*eax + 8*16   -2*8   ], mm2   ; data[i]
784  %endif    movq [edx + 8*eax + 8*16   -2*8 +8], mm6   ; data[i+1]
785    
786      jnz near .loop
787    
788        ; deal with DC
789    
790      movd mm0, [ecx]
791      pmullw mm0, [esp+16]  ; dcscalar
792      movq mm2, [mmx_32767_minus_2047]
793      paddsw mm0, mm2
794      psubsw mm0, mm2
795      movq mm2, [mmx_32768_minus_2048]
796      psubsw mm0, mm2
797      paddsw mm0, mm2
798      movd eax, mm0
799      mov [edx], ax
800    
801      ret
802    
803  ;===========================================================================  ;===========================================================================
804  ;  ;
# Line 881  Line 808 
808  ;  ;
809  ;===========================================================================  ;===========================================================================
810    
811        ; Note:  We use (2*c + sgn(c) - sgn(-c)) as multiplier
812        ; so we handle the 3 cases: c<0, c==0, and c>0 in one shot.
813        ; sgn(x) is the result of 'pcmpgtw 0,x':  0 if x>=0, -1 if x<0.
814        ; It's mixed with the extraction of the absolute value.
815    
816  align 16  align 16
817  cglobal dequant4_inter_mmx  cglobal dequant4_inter_mmx
818  dequant4_inter_mmx  dequant4_inter_mmx:
819    
820          push    esi    mov    edx, [esp+ 4]        ; data
821          push    edi    mov    ecx, [esp+ 8]        ; coeff
822      mov    eax, [esp+12]        ; quant
         mov    edi, [esp + 8 + 4]        ; data  
         mov    esi, [esp + 8 + 8]        ; coeff  
         mov    eax, [esp + 8 + 12]        ; quant  
823          movq mm7, [mmx_mul_quant  + eax*8 - 8]          movq mm7, [mmx_mul_quant  + eax*8 - 8]
824          movq mm6, [mmx_one]    mov eax, -16
825          xor eax, eax    paddw mm7, mm7    ; << 1
826          pxor mm5, mm5        ; mismatch sum    pxor mm6, mm6 ; mismatch sum
   
827    
828  align 16  align 16
829  .loop  .loop
830          movq    mm0, [esi + 8*eax]                        ; mm0 = [coeff]    movq mm0, [ecx+8*eax + 8*16   ]   ; mm0 = coeff[i]
831      movq mm2, [ecx+8*eax + 8*16 +8]   ; mm2 = coeff[i+1]
832      add eax,2
833    
834      pxor mm1, mm1
835      pxor mm3, mm3
836      pcmpgtw mm1, mm0  ; mm1 = sgn(c)    (preserved)
837      pcmpgtw mm3, mm2  ; mm3 = sgn(c')   (preserved)
838      paddsw mm0, mm1   ; c += sgn(c)
839      paddsw mm2, mm3   ; c += sgn(c')
840      paddw mm0, mm0    ; c *= 2
841      paddw mm2, mm2    ; c'*= 2
842    
843          pxor    mm1, mm1                ; mm1 = 0    pxor mm4, mm4
844          pcmpeqw    mm1, mm0                ; mm1 = (0 == mm0)    pxor mm5, mm5
845      psubw mm4, mm0    ; -c
846          pxor    mm2, mm2                ; mm2 = 0    psubw mm5, mm2    ; -c'
847          pcmpgtw    mm2, mm0                ; mm2 = (0 > mm0)    psraw mm4, 16     ; mm4 = sgn(-c)
848          pxor    mm0, mm2                ; mm0 = |mm0|    psraw mm5, 16     ; mm5 = sgn(-c')
849          psubw    mm0, mm2                ; displace    psubsw mm0, mm4   ; c  -= sgn(-c)
850      psubsw mm2, mm5   ; c' -= sgn(-c')
851          psllw    mm0, 1                ;    pxor mm0, mm1     ; finish changing sign if needed
852          paddsw    mm0, mm6            ; mm0 = 2*mm0 + 1    pxor mm2, mm3     ; finish changing sign if needed
853          pmullw    mm0, mm7            ; mm0 *= quant  
854        ; we're short on register, here. Poor pairing...
855          movq    mm3, [default_inter_matrix_mul + 8*eax]  
856      movq mm4, mm7     ; (matrix*quant)
857          movq  mm4, mm0    pmullw mm4,  [inter_matrix + 8*eax + 8*16 -2*8]
858          pmullw    mm0, mm3            ; mm0 = low(mm0 * mm3)    movq mm5, mm4
859          pmulhw    mm3, mm4            ; mm3 = high(mm0 * mm3)    pmulhw mm5, mm0   ; high of c*(matrix*quant)
860      pmullw mm0, mm4   ; low  of c*(matrix*quant)
861          movq    mm4, mm0            ; mm0,mm4 = unpack(mm3, mm0)  
862          punpcklwd mm0, mm3            ;    movq mm4, mm7     ; (matrix*quant)
863          punpckhwd mm4, mm3            ;    pmullw mm4,  [inter_matrix + 8*eax + 8*16 -2*8 + 8]
864    
865          psrad mm0, 4                ; mm0,mm4 /= 16    pcmpgtw mm5, [zero]
866          psrad mm4, 4                ;    paddusw mm0, mm5
867          packssdw mm0, mm4            ; mm0 = pack(mm4, mm0)    psrlw mm0, 5
868      pxor mm0, mm1     ; start restoring sign
869          pxor    mm0, mm2            ; mm0 *= sign(mm0)    psubusw mm1, mm5
870          psubw    mm0, mm2            ; undisplace  
871          pandn    mm1, mm0            ; mm1 = ~(iszero) & mm0    movq mm5, mm4
872      pmulhw mm5, mm2   ; high of c*(matrix*quant)
873      pmullw mm2, mm4   ; low  of c*(matrix*quant)
874  ;%ifdef SATURATE    psubw mm0, mm1    ; finish restoring sign
875          movq mm2, [mmx_32767_minus_2047]  
876          movq mm4, [mmx_32768_minus_2048]    pcmpgtw mm5, [zero]
877          paddsw    mm1, mm2    paddusw mm2, mm5
878          psubsw    mm1, mm2    psrlw mm2, 5
879          psubsw    mm1, mm4    pxor mm2, mm3    ; start restoring sign
880          paddsw    mm1, mm4    psubusw mm3, mm5
881  ;%endif    psubw mm2, mm3   ; finish restoring sign
882    
883          pxor mm5, mm1        ; mismatch    pxor mm6, mm0     ; mismatch control
884      movq [edx + 8*eax + 8*16 -2*8   ], mm0   ; data[i]
885          movq    [edi + 8*eax], mm1        ; [data] = mm0    pxor mm6, mm2     ; mismatch control
886      movq [edx + 8*eax + 8*16 -2*8 +8], mm2   ; data[i+1]
887    
         add eax, 1  
         cmp eax, 16  
888          jnz    near .loop          jnz    near .loop
889    
890          ; mismatch control          ; mismatch control
891    
892          movq mm0, mm5    movq mm0, mm6
         movq mm1, mm5  
         movq mm2, mm5  
893          psrlq mm0, 48          psrlq mm0, 48
894      movq mm1, mm6
895      movq mm2, mm6
896          psrlq mm1, 32          psrlq mm1, 32
897      pxor mm6, mm0
898          psrlq mm2, 16          psrlq mm2, 16
899          pxor mm5, mm0    pxor mm6, mm1
900          pxor mm5, mm1    pxor mm6, mm2
901          pxor mm5, mm2    movd eax, mm6
902      and eax, 1
903          movd eax, mm5    xor eax, 1
904          test eax, 0x1    xor word [edx + 2*63], ax
         jnz .done  
   
         xor word [edi + 2*63], 1  
   
 .done  
         pop    edi  
         pop    esi  
905    
906          ret          ret
907    

Legend:
Removed from v.3  
changed lines
  Added in v.886

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