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

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

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

revision 268, Sun Jul 7 11:44:02 2002 UTC revision 269, Sun Jul 7 13:21:34 2002 UTC
# Line 32  Line 32 
32  ; *  ; *
33  ; *     History:  ; *     History:
34  ; *  ; *
35    ; * 14.06.2002  mmx+xmm dequant_* funcs revamped  -Skal-
36  ; * 24.02.2002  sse2 quant_intra / dequant_intra (have to use movdqu ???)  ; * 24.02.2002  sse2 quant_intra / dequant_intra (have to use movdqu ???)
37  ; * 17.04.2002  sse2 quant_inter / dequant_inter  ; * 17.04.2002  sse2 quant_inter / dequant_inter
38  ; * 26.12.2001  minor bug fixes, dequant saturate, further optimization  ; * 26.12.2001  minor bug fixes, dequant saturate, further optimization
# Line 64  Line 65 
65    
66  plus_one times 8        dw       1  plus_one times 8        dw       1
67    
   
68  ;===========================================================================  ;===========================================================================
69  ;  ;
70  ; subtract by Q/2 table  ; subtract by Q/2 table
# Line 261  Line 261 
261  ;  ;
262  ;===========================================================================  ;===========================================================================
263    
264  align ALIGN  align 8
265  mmx_32768_minus_2048                            times 4 dw (32768-2048)  mmx_32768_minus_2048                            times 4 dw (32768-2048)
266  mmx_32767_minus_2047                            times 4 dw (32767-2047)  mmx_32767_minus_2047                            times 4 dw (32767-2047)
267    
268  align 16  align 16
269    mmx_2047 times 4 dw 2047
270    
271    align 16
272  sse2_pos_2047                                           times 8 dw 2047  sse2_pos_2047                                           times 8 dw 2047
273  sse2_neg_2048                                           times 8 dw -2048  sse2_neg_2048                                           times 8 dw -2048
274    
# Line 700  Line 703 
703                  jmp             .qes2_done                  jmp             .qes2_done
704    
705    
   
706  ;===========================================================================  ;===========================================================================
707  ;  ;
708  ; void dequant_intra_mmx(int16_t *data,  ; void dequant_intra_mmx(int16_t *data,
# Line 710  Line 712 
712  ;  ;
713  ;===========================================================================  ;===========================================================================
714    
715      ; note: we only saturate to +2047 *before* restoring the sign.
716      ; Hence, final clamp really is [-2048,2047]
717    
718  align ALIGN  align ALIGN
719  cglobal dequant_intra_mmx  cglobal dequant_intra_mmx
720  dequant_intra_mmx  dequant_intra_mmx:
   
                 push    esi  
                 push    edi  
   
                 mov     edi, [esp + 8 + 4]              ; data  
                 mov     esi, [esp + 8 + 8]              ; coeff  
                 mov     eax, [esp + 8 + 12]             ; quant  
721    
722                  movq    mm6, [mmx_add + eax * 8 - 8]    mov    edx, [esp+ 4]        ; data
723                  movq    mm7, [mmx_mul + eax * 8 - 8]    mov    ecx, [esp+ 8]        ; coeff
724                  xor eax, eax    mov    eax, [esp+12]        ; quant
725      movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1
726      movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant
727      mov eax, -16
728    
729  align ALIGN  align ALIGN
730  .loop  .loop
731                  movq    mm0, [esi + 8*eax]              ; mm0 = [coeff]    movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]
732                  movq    mm3, [esi + 8*eax + 8]  ;    movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]
733                  pxor    mm1, mm1                ; mm1 = 0    pxor mm1, mm1
734                  pxor    mm4, mm4                ;    pxor mm4, mm4
735                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)    pcmpgtw mm1, mm0  ; sign(c)
736                  pcmpgtw mm4, mm3                ;    pcmpgtw mm4, mm3  ; sign(c')
737                  pxor    mm2, mm2                ; mm2 = 0    pxor mm2, mm2
738                  pxor    mm5, mm5                ;    pxor mm5, mm5
739                  pcmpeqw mm2, mm0                ; mm2 = (0 == mm0)    pcmpeqw mm2, mm0  ; c is zero
740                  pcmpeqw mm5, mm3                ;    pcmpeqw mm5, mm3  ; c' is zero
741                  pandn   mm2, mm6                ; mm2 = (iszero ? 0 : add)    pandn mm2, mm6    ; offset = isZero ? 0 : quant_add
742                  pandn   mm5, mm6                ;    pandn mm5, mm6
743                  pxor    mm0, mm1                ; mm0 = |mm0|    pxor mm0, mm1     ; negate if negative
744                  pxor    mm3, mm4                ;    pxor mm3, mm4     ; negate if negative
745                  psubw   mm0, mm1                ; displace    psubw mm0, mm1
                 psubw   mm3, mm4                ;  
                 pmullw  mm0, mm7                ; mm0 *= 2Q  
                 pmullw  mm3, mm7                ;  
                 paddw   mm0, mm2                ; mm0 += mm2 (add)  
                 paddw   mm3, mm5                ;  
                 pxor    mm0, mm1                ; mm0 *= sign(mm0)  
                 pxor    mm3, mm4                ;  
                 psubw   mm0, mm1                ; undisplace  
746                  psubw   mm3, mm4                  psubw   mm3, mm4
747      pmullw mm0, mm7 ; *= 2Q
748      pmullw mm3, mm7 ; *= 2Q
749      paddw mm0, mm2 ; + offset
750      paddw mm3, mm5 ; + offset
751      paddw mm0, mm1 ; negate back
752      paddw mm3, mm4 ; negate back
753    
754  %ifdef SATURATE      ; saturates to +2047
755                  movq mm2, [mmx_32767_minus_2047]                  movq mm2, [mmx_32767_minus_2047]
756                  movq mm4, [mmx_32768_minus_2048]    add eax, 2
757                  paddsw  mm0, mm2                  paddsw  mm0, mm2
758                  paddsw  mm3, mm2                  paddsw  mm3, mm2
759                  psubsw  mm0, mm2                  psubsw  mm0, mm2
760                  psubsw  mm3, mm2                  psubsw  mm3, mm2
                 psubsw  mm0, mm4  
                 psubsw  mm3, mm4  
                 paddsw  mm0, mm4  
                 paddsw  mm3, mm4  
 %endif  
761    
762                  movq    [edi + 8*eax], mm0              ; [data] = mm0    pxor mm0, mm1
763                  movq    [edi + 8*eax + 8], mm3    pxor mm3, mm4
764      movq [edx + 8*eax + 8*16   - 2*8], mm0
765                  add eax, 2    movq [edx + 8*eax + 8*16+8 - 2*8], mm3
                 cmp eax, 16  
766                  jnz     near .loop                  jnz     near .loop
767    
768                  mov     ax, [esi]                                       ; ax = data[0]      ; deal with DC
                 imul ax, [esp + 8 + 16]                 ; eax = data[0] * dcscalar  
769    
770  %ifdef SATURATE    movd mm0, [ecx]
771                  cmp ax, -2048    pmullw mm0, [esp+16]    ; dcscalar
772                  jl .set_n2048    movq mm2, [mmx_32767_minus_2047]
773                  cmp ax, 2047    paddsw mm0, mm2
774                  jg .set_2047    psubsw mm0, mm2
775  %endif    movq mm3, [mmx_32768_minus_2048]
776                  mov     [edi], ax    psubsw mm0, mm3
777      paddsw mm0, mm3
778      movd eax, mm0
779      mov [edx], ax
780    
                 pop     edi  
                 pop     esi  
781                  ret                  ret
782    
783  %ifdef SATURATE  ;===========================================================================
784    ;
785    ; void dequant_intra_xmm(int16_t *data,
786    ;                                       const int16_t const *coeff,
787    ;                                       const uint32_t quant,
788    ;                                       const uint32_t dcscalar);
789    ;
790    ;===========================================================================
791    
792      ; this is the same as dequant_inter_mmx, except that we're
793      ; saturating using 'pminsw' (saves 2 cycles/loop => ~5% faster)
794    
795  align ALIGN  align ALIGN
796  .set_n2048  cglobal dequant_intra_xmm
797                  mov     word [edi], -2048  dequant_intra_xmm:
798                  pop     edi  
799                  pop     esi    mov    edx, [esp+ 4]        ; data
800                  ret    mov    ecx, [esp+ 8]        ; coeff
801      mov    eax, [esp+12]        ; quant
802      movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1
803      movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant
804      mov eax, -16
805    
806  align ALIGN  align ALIGN
807  .set_2047  .loop
808                  mov     word [edi], 2047    movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]
809                  pop     edi    movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]
810                  pop     esi    pxor mm1, mm1
811                  ret    pxor mm4, mm4
812  %endif    pcmpgtw mm1, mm0  ; sign(c)
813      pcmpgtw mm4, mm3  ; sign(c')
814      pxor mm2, mm2
815      pxor mm5, mm5
816      pcmpeqw mm2, mm0  ; c is zero
817      pcmpeqw mm5, mm3  ; c' is zero
818      pandn mm2, mm6    ; offset = isZero ? 0 : quant_add
819      pandn mm5, mm6
820      pxor mm0, mm1     ; negate if negative
821      pxor mm3, mm4     ; negate if negative
822      psubw mm0, mm1
823      psubw mm3, mm4
824      pmullw mm0, mm7 ; *= 2Q
825      pmullw mm3, mm7 ; *= 2Q
826      paddw mm0, mm2 ; + offset
827      paddw mm3, mm5 ; + offset
828      paddw mm0, mm1 ; negate back
829      paddw mm3, mm4 ; negate back
830    
831        ; saturates to +2047
832      movq mm2, [mmx_2047]
833      pminsw mm0, mm2
834      add eax, 2
835      pminsw mm3, mm2
836    
837      pxor mm0, mm1
838      pxor mm3, mm4
839      movq [edx + 8*eax + 8*16   - 2*8], mm0
840      movq [edx + 8*eax + 8*16+8 - 2*8], mm3
841      jnz   near .loop
842    
843        ; deal with DC
844    
845      movd mm0, [ecx]
846      pmullw mm0, [esp+16]    ; dcscalar
847      movq mm2, [mmx_32767_minus_2047]
848      paddsw mm0, mm2
849      psubsw mm0, mm2
850      movq mm2, [mmx_32768_minus_2048]
851      psubsw mm0, mm2
852      paddsw mm0, mm2
853      movd eax, mm0
854      mov [edx], ax
855    
856      ret
857    
858  ;===========================================================================  ;===========================================================================
859  ;  ;
# Line 816  Line 866 
866    
867  align 16  align 16
868  cglobal dequant_intra_sse2  cglobal dequant_intra_sse2
869  dequant_intra_sse2  dequant_intra_sse2:
870    
871                  push    esi                  push    esi
872                  push    edi                  push    edi
# Line 908  Line 958 
958                  ret                  ret
959  %endif  %endif
960    
   
   
961  ;===========================================================================  ;===========================================================================
962  ;  ;
963  ; void dequant_inter_mmx(int16_t * data,  ; void dequant_inter_mmx(int16_t * data,
# Line 920  Line 968 
968    
969  align ALIGN  align ALIGN
970  cglobal dequant_inter_mmx  cglobal dequant_inter_mmx
971  dequant_inter_mmx  dequant_inter_mmx:
972    
973                  push    esi    mov    edx, [esp+ 4]        ; data
974                  push    edi    mov    ecx, [esp+ 8]        ; coeff
975      mov    eax, [esp+12]        ; quant
976                  mov     edi, [esp + 8 + 4]      ; data    movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1
977                  mov     esi, [esp + 8 + 8]      ; coeff    movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant
978                  mov     eax, [esp + 8 + 12]     ; quant    mov eax, -16
                 movq    mm6, [mmx_add + eax * 8 - 8]  
                 movq    mm7, [mmx_mul + eax * 8 - 8]  
   
                 xor eax, eax  
979    
980  align ALIGN  align ALIGN
981  .loop  .loop
982                  movq    mm0, [esi + 8*eax]                      ; mm0 = [coeff]    movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]
983                  movq    mm3, [esi + 8*eax + 8]          ;    movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]
984                  pxor    mm1, mm1                ; mm1 = 0    pxor mm1, mm1
985                  pxor    mm4, mm4                ;    pxor mm4, mm4
986                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)    pcmpgtw mm1, mm0  ; sign(c)
987                  pcmpgtw mm4, mm3                ;    pcmpgtw mm4, mm3  ; sign(c')
988                  pxor    mm2, mm2                ; mm2 = 0    pxor mm2, mm2
989                  pxor    mm5, mm5                ;    pxor mm5, mm5
990                  pcmpeqw mm2, mm0                ; mm2 = (0 == mm0)    pcmpeqw mm2, mm0  ; c is zero
991                  pcmpeqw mm5, mm3                ;    pcmpeqw mm5, mm3  ; c' is zero
992                  pandn   mm2, mm6                ; mm2 = (iszero ? 0 : add)    pandn mm2, mm6    ; offset = isZero ? 0 : quant_add
993                  pandn   mm5, mm6                ;    pandn mm5, mm6
994                  pxor    mm0, mm1                ; mm0 = |mm0|    pxor mm0, mm1     ; negate if negative
995                  pxor    mm3, mm4                ;    pxor mm3, mm4     ; negate if negative
996                  psubw   mm0, mm1                ; displace    psubw mm0, mm1
                 psubw   mm3, mm4                ;  
                 pmullw  mm0, mm7                ; mm0 *= 2Q  
                 pmullw  mm3, mm7                ;  
                 paddw   mm0, mm2                ; mm0 += mm2 (add)  
                 paddw   mm3, mm5                ;  
                 pxor    mm0, mm1                ; mm0 *= sign(mm0)  
                 pxor    mm3, mm4                ;  
                 psubw   mm0, mm1                ; undisplace  
997                  psubw   mm3, mm4                  psubw   mm3, mm4
998      pmullw mm0, mm7 ; *= 2Q
999      pmullw mm3, mm7 ; *= 2Q
1000      paddw mm0, mm2 ; + offset
1001      paddw mm3, mm5 ; + offset
1002      paddw mm0, mm1 ; negate back
1003      paddw mm3, mm4 ; negate back
1004    
1005  %ifdef SATURATE      ; saturates to +2047
1006                  movq mm2, [mmx_32767_minus_2047]                  movq mm2, [mmx_32767_minus_2047]
1007                  movq mm4, [mmx_32768_minus_2048]    add eax, 2
1008                  paddsw  mm0, mm2                  paddsw  mm0, mm2
1009                  paddsw  mm3, mm2                  paddsw  mm3, mm2
1010                  psubsw  mm0, mm2                  psubsw  mm0, mm2
1011                  psubsw  mm3, mm2                  psubsw  mm3, mm2
                 psubsw  mm0, mm4  
                 psubsw  mm3, mm4  
                 paddsw  mm0, mm4  
                 paddsw  mm3, mm4  
 %endif  
1012    
1013                  movq    [edi + 8*eax], mm0    pxor mm0, mm1
1014                  movq    [edi + 8*eax + 8], mm3    pxor mm3, mm4
1015      movq [edx + 8*eax + 8*16   - 2*8], mm0
1016      movq [edx + 8*eax + 8*16+8 - 2*8], mm3
1017      jnz   near .loop
1018    
1019      ret
1020    
1021    ;===========================================================================
1022    ;
1023    ; void dequant_inter_xmm(int16_t * data,
1024    ;                                       const int16_t * const coeff,
1025    ;                                       const uint32_t quant);
1026    ;
1027    ;===========================================================================
1028    
1029      ; this is the same as dequant_inter_mmx,
1030      ; except that we're saturating using 'pminsw' (saves 2 cycles/loop)
1031    
1032    align ALIGN
1033    cglobal dequant_inter_xmm
1034    dequant_inter_xmm:
1035    
1036      mov    edx, [esp+ 4]        ; data
1037      mov    ecx, [esp+ 8]        ; coeff
1038      mov    eax, [esp+12]        ; quant
1039      movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1
1040      movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant
1041      mov eax, -16
1042    
1043    align ALIGN
1044    .loop
1045      movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]
1046      movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]
1047      pxor mm1, mm1
1048      pxor mm4, mm4
1049      pcmpgtw mm1, mm0  ; sign(c)
1050      pcmpgtw mm4, mm3  ; sign(c')
1051      pxor mm2, mm2
1052      pxor mm5, mm5
1053      pcmpeqw mm2, mm0  ; c is zero
1054      pcmpeqw mm5, mm3  ; c' is zero
1055      pandn mm2, mm6    ; offset = isZero ? 0 : quant_add
1056      pandn mm5, mm6
1057      pxor mm0, mm1     ; negate if negative
1058      pxor mm3, mm4     ; negate if negative
1059      psubw mm0, mm1
1060      psubw mm3, mm4
1061      pmullw mm0, mm7 ; *= 2Q
1062      pmullw mm3, mm7 ; *= 2Q
1063      paddw mm0, mm2 ; + offset
1064      paddw mm3, mm5 ; + offset
1065      paddw mm0, mm1 ; start restoring sign
1066      paddw mm3, mm4 ; start restoring sign
1067    
1068          ; saturates to +2047
1069      movq mm2, [mmx_2047]
1070      pminsw mm0, mm2
1071                  add eax, 2                  add eax, 2
1072                  cmp eax, 16    pminsw mm3, mm2
                 jnz     near .loop  
1073    
1074                  pop     edi    pxor mm0, mm1 ; finish restoring sign
1075                  pop     esi    pxor mm3, mm4 ; finish restoring sign
1076      movq [edx + 8*eax + 8*16   - 2*8], mm0
1077      movq [edx + 8*eax + 8*16+8 - 2*8], mm3
1078      jnz   near .loop
1079    
1080                  ret                  ret
1081    
   
1082  ;===========================================================================  ;===========================================================================
1083  ;  ;
1084  ; void dequant_inter_sse2(int16_t * data,  ; void dequant_inter_sse2(int16_t * data,

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

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