[svn] / trunk / xvidcore / src / quant / x86_asm / quantize4_mmx.asm Repository:
ViewVC logotype

Diff of /trunk/xvidcore/src/quant/x86_asm/quantize4_mmx.asm

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

revision 3, Fri Mar 8 02:46:11 2002 UTC revision 268, Sun Jul 7 11:44:02 2002 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 64  Line 65 
65          %endif          %endif
66  %endmacro  %endmacro
67    
68    %macro cextern 1
69            %ifdef PREFIX
70                    extern _%1
71                    %define %1 _%1
72            %else
73                    extern %1
74            %endif
75    %endmacro
76    
77  mmx_one times 4 dw       1  mmx_one times 4 dw       1
78    
79  ;===========================================================================  ;===========================================================================
# Line 113  Line 123 
123    
124  ;===========================================================================  ;===========================================================================
125  ;  ;
126  ; default intra matrix  ; intra matrix
127  ;  ;
128  ;===========================================================================  ;===========================================================================
129    
130  mmx_intra_matrix  cextern intra_matrix
131                  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  
   
132    
133  ;===========================================================================  ;===========================================================================
134  ;  ;
135  ; default inter matrix  ; inter matrix
136  ;  ;
137  ;===========================================================================  ;===========================================================================
138    
139  mmx_inter_matrix  cextern inter_matrix
140                  dw 16,17,18,19  cextern inter_matrix_fix
141                  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  
142    
143  %define VM18P 3  %define VM18P 3
144  %define VM18Q 4  %define VM18Q 4
145    
146    
147  ;===========================================================================  ;===========================================================================
148  ;  ;
149  ; quantd table  ; quantd table
# Line 250  Line 190 
190    
191  ;===========================================================================  ;===========================================================================
192  ;  ;
 ; 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  
   
   
 ;===========================================================================  
 ;  
193  ; multiple by 2Q table  ; multiple by 2Q table
194  ;  ;
195  ;===========================================================================  ;===========================================================================
# Line 349  Line 238 
238  ;===========================================================================  ;===========================================================================
239    
240  align 16  align 16
241  mmx_32768_minus_2048                times 4 dw (32768-2048)  
242  mmx_32767_minus_2047                times 4 dw (32767-2047)  mmx_32767_minus_2047                times 4 dw (32767-2047)
243    mmx_32768_minus_2048                            times 4 dw (32768-2048)
244    mmx_2047 times 4 dw 2047
245    mmx_minus_2048 times 4 dw (-2048)
246    zero times 4 dw 0
247    
248  section .text  section .text
249    
# Line 405  Line 298 
298                  psllw   mm0, 4                  ; level << 4                  psllw   mm0, 4                  ; level << 4
299                  psllw   mm3, 4                  ;                  psllw   mm3, 4                  ;
300    
301                  movq    mm2, [mmx_intra_matrix + 8*ecx]                  movq    mm2, [intra_matrix + 8*ecx]
302                  psrlw   mm2, 1                  ; intra_matrix[i]>>1                  psrlw   mm2, 1                  ; intra_matrix[i]>>1
303                  paddw   mm0, mm2                  paddw   mm0, mm2
304    
305                  movq    mm2, [mmx_intra_matrix_fix + ecx*8]                  movq    mm2, [intra_matrix_fix + ecx*8]
306                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
307    
308                  movq    mm2, [mmx_intra_matrix + 8*ecx + 8]                  movq    mm2, [intra_matrix + 8*ecx + 8]
309                  psrlw   mm2, 1                  psrlw   mm2, 1
310                  paddw   mm3, mm2                  paddw   mm3, mm2
311    
312                  movq    mm2, [mmx_intra_matrix_fix + ecx*8 + 8]                  movq    mm2, [intra_matrix_fix + ecx*8 + 8]
313                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
314    
315              paddw   mm0, mm5            ; + quantd              paddw   mm0, mm5            ; + quantd
# Line 484  Line 377 
377                  psllw   mm0, 4                  psllw   mm0, 4
378                  psllw   mm3, 4                  psllw   mm3, 4
379    
380                  movq    mm2, [mmx_intra_matrix + 8*ecx]                  movq    mm2, [intra_matrix + 8*ecx]
381                  psrlw   mm2, 1                  psrlw   mm2, 1
382                  paddw   mm0, mm2                  paddw   mm0, mm2
383    
384                  movq    mm2, [mmx_intra_matrix_fix + ecx*8]                  movq    mm2, [intra_matrix_fix + ecx*8]
385                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
386    
387                  movq    mm2, [mmx_intra_matrix + 8*ecx + 8]                  movq    mm2, [intra_matrix + 8*ecx + 8]
388                  psrlw   mm2, 1                  psrlw   mm2, 1
389                  paddw   mm3, mm2                  paddw   mm3, mm2
390    
391                  movq    mm2, [mmx_intra_matrix_fix + ecx*8 + 8]                  movq    mm2, [intra_matrix_fix + ecx*8 + 8]
392                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
393    
394          paddw   mm0, mm5          paddw   mm0, mm5
# Line 537  Line 430 
430                  psllw   mm0, 4                  psllw   mm0, 4
431                  psllw   mm3, 4                  psllw   mm3, 4
432    
433                  movq    mm2, [mmx_intra_matrix + 8*ecx]                  movq    mm2, [intra_matrix + 8*ecx]
434                  psrlw   mm2, 1                  psrlw   mm2, 1
435                  paddw   mm0, mm2                  paddw   mm0, mm2
436    
437                  movq    mm2, [mmx_intra_matrix_fix + ecx*8]                  movq    mm2, [intra_matrix_fix + ecx*8]
438                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
439    
440                  movq    mm2, [mmx_intra_matrix + 8*ecx + 8]                  movq    mm2, [intra_matrix + 8*ecx + 8]
441                  psrlw   mm2, 1                  psrlw   mm2, 1
442                  paddw   mm3, mm2                  paddw   mm3, mm2
443    
444                  movq    mm2, [mmx_intra_matrix_fix + ecx*8 + 8]                  movq    mm2, [intra_matrix_fix + ecx*8 + 8]
445                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
446    
447          paddw   mm0, mm5          paddw   mm0, mm5
# Line 619  Line 512 
512                  psllw   mm0, 4                  psllw   mm0, 4
513                  psllw   mm3, 4                  psllw   mm3, 4
514    
515                  movq    mm2, [mmx_inter_matrix + 8*ecx]                  movq    mm2, [inter_matrix + 8*ecx]
516                  psrlw   mm2, 1                  psrlw   mm2, 1
517                  paddw   mm0, mm2                  paddw   mm0, mm2
518    
519                  movq    mm2, [mmx_inter_matrix_fix + ecx*8]                  movq    mm2, [inter_matrix_fix + ecx*8]
520                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
521    
522                  movq    mm2, [mmx_inter_matrix + 8*ecx + 8]                  movq    mm2, [inter_matrix + 8*ecx + 8]
523                  psrlw   mm2, 1                  psrlw   mm2, 1
524                  paddw   mm3, mm2                  paddw   mm3, mm2
525    
526                  movq    mm2, [mmx_inter_matrix_fix + ecx*8 + 8]                  movq    mm2, [inter_matrix_fix + ecx*8 + 8]
527                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
528    
529                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16
# Line 683  Line 576 
576                  psllw   mm0, 4                  psllw   mm0, 4
577                  psllw   mm3, 4                  psllw   mm3, 4
578    
579                  movq    mm2, [mmx_inter_matrix + 8*ecx]                  movq    mm2, [inter_matrix + 8*ecx]
580                  psrlw   mm2, 1                  psrlw   mm2, 1
581                  paddw   mm0, mm2                  paddw   mm0, mm2
582    
583                  movq    mm2, [mmx_inter_matrix_fix + ecx*8]                  movq    mm2, [inter_matrix_fix + ecx*8]
584                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
585    
586                  movq    mm2, [mmx_inter_matrix + 8*ecx + 8]                  movq    mm2, [inter_matrix + 8*ecx + 8]
587                  psrlw   mm2, 1                  psrlw   mm2, 1
588                  paddw   mm3, mm2                  paddw   mm3, mm2
589    
590                  movq    mm2, [mmx_inter_matrix_fix + ecx*8 + 8]                  movq    mm2, [inter_matrix_fix + ecx*8 + 8]
591                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
592    
593                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)
# Line 736  Line 629 
629                  psllw   mm0, 4                  psllw   mm0, 4
630                  psllw   mm3, 4                  psllw   mm3, 4
631    
632                  movq    mm2, [mmx_inter_matrix + 8*ecx]                  movq    mm2, [inter_matrix + 8*ecx]
633                  psrlw   mm2, 1                  psrlw   mm2, 1
634                  paddw   mm0, mm2                  paddw   mm0, mm2
635    
636                  movq    mm2, [mmx_inter_matrix_fix + ecx*8]                  movq    mm2, [inter_matrix_fix + ecx*8]
637                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
638    
639                  movq    mm2, [mmx_inter_matrix + 8*ecx + 8]                  movq    mm2, [inter_matrix + 8*ecx + 8]
640                  psrlw   mm2, 1                  psrlw   mm2, 1
641                  paddw   mm3, mm2                  paddw   mm3, mm2
642    
643                  movq    mm2, [mmx_inter_matrix_fix + ecx*8 + 8]                  movq    mm2, [inter_matrix_fix + ecx*8 + 8]
644                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
645    
646                  psrlw   mm0, 2                  ; mm0 >>= 1   (/2)                  psrlw   mm0, 2                  ; mm0 >>= 1   (/2)
# Line 779  Line 672 
672  ;  ;
673  ;===========================================================================  ;===========================================================================
674    
675  align 16    ;   Note: in order to saturate 'easily', we pre-shift the quantifier
676  cglobal dequant4_intra_mmx    ; by 4. Then, the high-word of (coeff[]*matrix[i]*quant) are used to
677  dequant4_intra_mmx    ; build a saturating mask. It is non-zero only when an overflow occured.
678      ; We thus avoid packing/unpacking toward double-word.
679      ; Moreover, we perform the mult (matrix[i]*quant) first, instead of, e.g.,
680      ; (coeff[i]*matrix[i]). This is less prone to overflow if coeff[] are not
681      ; checked. Input ranges are: coeff in [-127,127], inter_matrix in [1..255],a
682      ; and quant in [1..31].
683      ;
684      ; The original loop is:
685      ;
686    %if 0
687      movq mm0, [ecx+8*eax + 8*16]   ; mm0 = coeff[i]
688      pxor mm1, mm1
689      pcmpgtw mm1, mm0
690      pxor mm0, mm1     ; change sign if negative
691      psubw mm0, mm1    ; -> mm0 = abs(coeff[i]), mm1 = sign of coeff[i]
692    
693      movq mm2, mm7     ; mm2 = quant
694      pmullw mm2,  [intra_matrix + 8*eax + 8*16 ]  ; matrix[i]*quant.
695    
696      movq mm6, mm2
697      pmulhw mm2, mm0   ; high of coeff*(matrix*quant)  (should be 0 if no overflow)
698      pmullw mm0, mm6   ; low  of coeff*(matrix*quant)
699    
700      pxor mm5, mm5
701      pcmpgtw mm2, mm5  ; otherflow?
702      psrlw mm2, 5      ; =0 if no clamp, 2047 otherwise
703      psrlw mm0, 5
704      paddw mm0, mm1    ; start restoring sign
705      por mm0, mm2      ; saturate to 2047 if needed
706      pxor mm0, mm1     ; finish negating back
707    
708          push    esi    movq [edx + 8*eax + 8*16], mm0   ; data[i]
709          push    edi    add eax, 1
710    %endif
711    
712          mov    edi, [esp + 8 + 4]        ; data    ;********************************************************************
         mov    esi, [esp + 8 + 8]        ; coeff  
         mov    eax, [esp + 8 + 12]        ; quant  
713    
714          movq mm7, [mmx_mul_quant  + eax*8 - 8]  align 16
715    cglobal dequant4_intra_mmx
716    dequant4_intra_mmx:
717    
718          xor eax, eax    mov edx, [esp+4]  ; data
719      mov ecx, [esp+8]  ; coeff
720      mov eax, [esp+12] ; quant
721    
722      movq mm7, [mmx_mul_quant  + eax*8 - 8]
723      mov eax, -16   ; to keep aligned, we regularly process coeff[0]
724      psllw mm7, 2   ; << 2. See comment.
725      pxor mm6, mm6   ; this is a NOP
726    
727  align 16  align 16
728  .loop  .loop
729          movq    mm0, [esi + 8*eax]        ; mm0 = [coeff]    movq mm0, [ecx+8*eax + 8*16]   ; mm0 = c  = coeff[i]
730      movq mm3, [ecx+8*eax + 8*16 +8]; mm3 = c' = coeff[i+1]
731      pxor mm1, mm1
732      pxor mm4, mm4
733      pcmpgtw mm1, mm0  ; mm1 = sgn(c)
734      movq mm2, mm7     ; mm2 = quant
735    
736          pxor    mm1, mm1                ; mm1 = 0    pcmpgtw mm4, mm3  ; mm4 = sgn(c')
737          pcmpeqw    mm1, mm0                ; mm1 = (0 == mm0)    pmullw mm2,  [intra_matrix + 8*eax + 8*16 ]  ; matrix[i]*quant
738    
739          pxor    mm2, mm2                ; mm2 = 0    pxor mm0, mm1     ; negate if negative
740          pcmpgtw    mm2, mm0                ; mm2 = (0 > mm0)    pxor mm3, mm4     ; negate if negative
         pxor    mm0, mm2                ; mm0 = |mm0|  
         psubw    mm0, mm2                ; displace  
741    
742          pmullw    mm0, mm7                ; mm0 *= quant    psubw mm0, mm1
743      psubw mm3, mm4
744    
745          movq    mm3, [default_intra_matrix_mul + 8*eax]      ; we're short on register, here. Poor pairing...
746    
747          movq  mm4, mm0                    ;    movq mm5, mm2
748          pmullw    mm0, mm3                ; mm0 = low(mm0 * mm3)    pmullw mm2, mm0   ; low  of coeff*(matrix*quant)
         pmulhw    mm3, mm4                ; mm3 = high(mm0 * mm3)  
749    
750          movq    mm4, mm0                ; mm0,mm4 = unpack(mm3, mm0)    pmulhw mm0, mm5   ; high of coeff*(matrix*quant)
751          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)  
752    
753          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  
754    
755  %ifdef SATURATE    movq mm6, mm5
756          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  
757    
758          movq    [edi + 8*eax], mm1        ; [data] = mm0    pmullw mm6, mm3   ; low  of coeff*(matrix*quant)
759      pmulhw mm3, mm5   ; high of coeff*(matrix*quant)
760    
761          add eax, 1    pcmpgtw mm0, [zero]
762          cmp eax, 16    paddusw mm2, mm0
763          jnz    near .loop    psrlw mm2, 5
764    
765          mov    ax, [esi]                    ; ax = data[0]    pcmpgtw mm3, [zero]
766          imul     ax, [esp + 8 + 16]        ; eax = data[0] * dcscalar    paddusw mm6, mm3
767          mov    [edi], ax                    ; data[0] = ax    psrlw mm6, 5
   
 %ifdef SATURATE  
         cmp ax, -2048  
         jl .set_n2048  
         cmp ax, 2047  
         jg .set_2047  
 %endif  
768    
769          pop    edi    pxor mm2, mm1  ; start negating back
770          pop    esi    pxor mm6, mm4  ; start negating back
         ret  
771    
772  %ifdef SATURATE    psubusw mm1, mm0
773  .set_n2048    psubusw mm4, mm3
         mov    word [edi], -2048  
         pop    edi  
         pop    esi  
         ret  
774    
775  .set_2047    psubw mm2, mm1 ; finish negating back
776          mov    word [edi], 2047    psubw mm6, mm4 ; finish negating back
         pop    edi  
         pop    esi  
777    
778                  ret    movq [edx + 8*eax + 8*16   -2*8   ], mm2   ; data[i]
779  %endif    movq [edx + 8*eax + 8*16   -2*8 +8], mm6   ; data[i+1]
780    
781      jnz near .loop
782    
783        ; deal with DC
784    
785      movd mm0, [ecx]
786      pmullw mm0, [esp+16]  ; dcscalar
787      movq mm2, [mmx_32767_minus_2047]
788      paddsw mm0, mm2
789      psubsw mm0, mm2
790      movq mm2, [mmx_32768_minus_2048]
791      psubsw mm0, mm2
792      paddsw mm0, mm2
793      movd eax, mm0
794      mov [edx], ax
795    
796      ret
797    
798  ;===========================================================================  ;===========================================================================
799  ;  ;
# Line 881  Line 803 
803  ;  ;
804  ;===========================================================================  ;===========================================================================
805    
806        ; Note:  We use (2*c + sgn(c) - sgn(-c)) as multiplier
807        ; so we handle the 3 cases: c<0, c==0, and c>0 in one shot.
808        ; sgn(x) is the result of 'pcmpgtw 0,x':  0 if x>=0, -1 if x<0.
809        ; It's mixed with the extraction of the absolute value.
810    
811  align 16  align 16
812  cglobal dequant4_inter_mmx  cglobal dequant4_inter_mmx
813  dequant4_inter_mmx  dequant4_inter_mmx:
814    
815          push    esi    mov    edx, [esp+ 4]        ; data
816          push    edi    mov    ecx, [esp+ 8]        ; coeff
817      mov    eax, [esp+12]        ; quant
         mov    edi, [esp + 8 + 4]        ; data  
         mov    esi, [esp + 8 + 8]        ; coeff  
         mov    eax, [esp + 8 + 12]        ; quant  
818          movq mm7, [mmx_mul_quant  + eax*8 - 8]          movq mm7, [mmx_mul_quant  + eax*8 - 8]
819          movq mm6, [mmx_one]    mov eax, -16
820          xor eax, eax    paddw mm7, mm7    ; << 1
821          pxor mm5, mm5        ; mismatch sum    pxor mm6, mm6 ; mismatch sum
   
822    
823  align 16  align 16
824  .loop  .loop
825          movq    mm0, [esi + 8*eax]                        ; mm0 = [coeff]    movq mm0, [ecx+8*eax + 8*16   ]   ; mm0 = coeff[i]
826      movq mm2, [ecx+8*eax + 8*16 +8]   ; mm2 = coeff[i+1]
827          pxor    mm1, mm1                ; mm1 = 0    add eax,2
828          pcmpeqw    mm1, mm0                ; mm1 = (0 == mm0)  
829      pxor mm1, mm1
830          pxor    mm2, mm2                ; mm2 = 0    pxor mm3, mm3
831          pcmpgtw    mm2, mm0                ; mm2 = (0 > mm0)    pcmpgtw mm1, mm0  ; mm1 = sgn(c)    (preserved)
832          pxor    mm0, mm2                ; mm0 = |mm0|    pcmpgtw mm3, mm2  ; mm3 = sgn(c')   (preserved)
833          psubw    mm0, mm2                ; displace    paddsw mm0, mm1   ; c += sgn(c)
834      paddsw mm2, mm3   ; c += sgn(c')
835          psllw    mm0, 1                ;    paddw mm0, mm0    ; c *= 2
836          paddsw    mm0, mm6            ; mm0 = 2*mm0 + 1    paddw mm2, mm2    ; c'*= 2
         pmullw    mm0, mm7            ; mm0 *= quant  
   
         movq    mm3, [default_inter_matrix_mul + 8*eax]  
   
         movq  mm4, mm0  
         pmullw    mm0, mm3            ; mm0 = low(mm0 * mm3)  
         pmulhw    mm3, mm4            ; mm3 = high(mm0 * mm3)  
   
         movq    mm4, mm0            ; mm0,mm4 = unpack(mm3, mm0)  
         punpcklwd mm0, mm3            ;  
         punpckhwd mm4, mm3            ;  
   
         psrad mm0, 4                ; mm0,mm4 /= 16  
         psrad mm4, 4                ;  
         packssdw mm0, mm4            ; mm0 = pack(mm4, mm0)  
   
         pxor    mm0, mm2            ; mm0 *= sign(mm0)  
         psubw    mm0, mm2            ; undisplace  
         pandn    mm1, mm0            ; mm1 = ~(iszero) & mm0  
   
   
 ;%ifdef SATURATE  
         movq mm2, [mmx_32767_minus_2047]  
         movq mm4, [mmx_32768_minus_2048]  
         paddsw    mm1, mm2  
         psubsw    mm1, mm2  
         psubsw    mm1, mm4  
         paddsw    mm1, mm4  
 ;%endif  
837    
838          pxor mm5, mm1        ; mismatch    pxor mm4, mm4
839      pxor mm5, mm5
840          movq    [edi + 8*eax], mm1        ; [data] = mm0    psubw mm4, mm0    ; -c
841      psubw mm5, mm2    ; -c'
842      psraw mm4, 16     ; mm4 = sgn(-c)
843      psraw mm5, 16     ; mm5 = sgn(-c')
844      psubsw mm0, mm4   ; c  -= sgn(-c)
845      psubsw mm2, mm5   ; c' -= sgn(-c')
846      pxor mm0, mm1     ; finish changing sign if needed
847      pxor mm2, mm3     ; finish changing sign if needed
848    
849        ; we're short on register, here. Poor pairing...
850    
851      movq mm4, mm7     ; (matrix*quant)
852      pmullw mm4,  [inter_matrix + 8*eax + 8*16 -2*8]
853      movq mm5, mm4
854      pmulhw mm5, mm0   ; high of c*(matrix*quant)
855      pmullw mm0, mm4   ; low  of c*(matrix*quant)
856    
857      movq mm4, mm7     ; (matrix*quant)
858      pmullw mm4,  [inter_matrix + 8*eax + 8*16 -2*8 + 8]
859    
860      pcmpgtw mm5, [zero]
861      paddusw mm0, mm5
862      psrlw mm0, 5
863      pxor mm0, mm1     ; start restoring sign
864      psubusw mm1, mm5
865    
866      movq mm5, mm4
867      pmulhw mm5, mm2   ; high of c*(matrix*quant)
868      pmullw mm2, mm4   ; low  of c*(matrix*quant)
869      psubw mm0, mm1    ; finish restoring sign
870    
871      pcmpgtw mm5, [zero]
872      paddusw mm2, mm5
873      psrlw mm2, 5
874      pxor mm2, mm3    ; start restoring sign
875      psubusw mm3, mm5
876      psubw mm2, mm3   ; finish restoring sign
877    
878      pxor mm6, mm0     ; mismatch control
879      movq [edx + 8*eax + 8*16 -2*8   ], mm0   ; data[i]
880      pxor mm6, mm2     ; mismatch control
881      movq [edx + 8*eax + 8*16 -2*8 +8], mm2   ; data[i+1]
882    
         add eax, 1  
         cmp eax, 16  
883          jnz    near .loop          jnz    near .loop
884    
885          ; mismatch control          ; mismatch control
886    
887          movq mm0, mm5    movq mm0, mm6
         movq mm1, mm5  
         movq mm2, mm5  
888          psrlq mm0, 48          psrlq mm0, 48
889      movq mm1, mm6
890      movq mm2, mm6
891          psrlq mm1, 32          psrlq mm1, 32
892      pxor mm6, mm0
893          psrlq mm2, 16          psrlq mm2, 16
894          pxor mm5, mm0    pxor mm6, mm1
895          pxor mm5, mm1    pxor mm6, mm2
896          pxor mm5, mm2    movd eax, mm6
897      and eax, 1
898          movd eax, mm5    xor eax, 1
899          test eax, 0x1    xor word [edx + 2*63], ax
         jnz .done  
   
         xor word [edi + 2*63], 1  
   
 .done  
         pop    edi  
         pop    esi  
900    
901          ret          ret
902    

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

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