[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 135, Wed Apr 24 12:21:43 2002 UTC revision 463, Tue Sep 10 21:16:45 2002 UTC
# Line 1  Line 1 
1  ;/**************************************************************************  ;/*****************************************************************************
2  ; *  ; *
3  ; *     XVID MPEG-4 VIDEO CODEC  ; *     XVID MPEG-4 VIDEO CODEC
4  ; *     mmx quantization/dequantization  ; *  mmx optimized quantization/dequantization
5    ; *
6    ; *  Copyright(C) 2002 Peter Ross <pross@xvid.org>
7    ; *  Copyright(C) 2002 Michael Militzer <michael@xvid.org>
8    ; *  Copyright(C) 2002 Pascal Massimino <skal@planet-d.net>
9  ; *  ; *
10  ; *     This program is an implementation of a part of one or more MPEG-4  ; *     This program is an implementation of a part of one or more MPEG-4
11  ; *     Video tools as specified in ISO/IEC 14496-2 standard.  Those intending  ; *     Video tools as specified in ISO/IEC 14496-2 standard.  Those intending
# Line 24  Line 28 
28  ; *  ; *
29  ; *     You should have received a copy of the GNU General Public License  ; *     You should have received a copy of the GNU General Public License
30  ; *     along with this program; if not, write to the Free Software  ; *     along with this program; if not, write to the Free Software
31  ; *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  ; *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 ; *  
 ; *************************************************************************/  
   
 ;/**************************************************************************  
 ; *  
 ; *     History:  
 ; *  
 ; * 24.02.2002  sse2 quant_intra / dequant_intra (have to use movdqu ???)  
 ; * 17.04.2002  sse2 quant_inter / dequant_inter  
 ; * 26.12.2001  minor bug fixes, dequant saturate, further optimization  
 ; * 19.11.2001  quant_inter_mmx now returns sum of abs. coefficient values  
 ; *     04.11.2001      nasm version; (c)2001 peter ross <pross@cs.rmit.edu.au>  
32  ; *  ; *
33  ; *************************************************************************/  ; *************************************************************************/
34    
# Line 64  Line 56 
56    
57  plus_one times 8        dw       1  plus_one times 8        dw       1
58    
   
59  ;===========================================================================  ;===========================================================================
60  ;  ;
61  ; subtract by Q/2 table  ; subtract by Q/2 table
# Line 261  Line 252 
252  ;  ;
253  ;===========================================================================  ;===========================================================================
254    
255  align ALIGN  align 16
256  mmx_32768_minus_2048                            times 4 dw (32768-2048)  sse2_2047       times 8 dw 2047
 mmx_32767_minus_2047                            times 4 dw (32767-2047)  
257    
258  align 16  align 16
259  sse2_pos_2047                                           times 8 dw 2047  mmx_2047        times 4 dw 2047
260  sse2_neg_2048                                           times 8 dw -2048  
261    align 8
262    mmx_32768_minus_2048                            times 4 dw (32768-2048)
263    mmx_32767_minus_2047                            times 4 dw (32767-2047)
264    
265    
266  section .text  section .text
# Line 700  Line 693 
693                  jmp             .qes2_done                  jmp             .qes2_done
694    
695    
   
696  ;===========================================================================  ;===========================================================================
697  ;  ;
698  ; void dequant_intra_mmx(int16_t *data,  ; void dequant_intra_mmx(int16_t *data,
# Line 710  Line 702 
702  ;  ;
703  ;===========================================================================  ;===========================================================================
704    
705      ; note: we only saturate to +2047 *before* restoring the sign.
706      ; Hence, final clamp really is [-2048,2047]
707    
708  align ALIGN  align ALIGN
709  cglobal dequant_intra_mmx  cglobal dequant_intra_mmx
710  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  
711    
712                  movq    mm6, [mmx_add + eax * 8 - 8]    mov    edx, [esp+ 4]        ; data
713                  movq    mm7, [mmx_mul + eax * 8 - 8]    mov    ecx, [esp+ 8]        ; coeff
714                  xor eax, eax    mov    eax, [esp+12]        ; quant
715      movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1
716      movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant
717      mov eax, -16
718    
719  align ALIGN  align ALIGN
720  .loop  .loop
721                  movq    mm0, [esi + 8*eax]              ; mm0 = [coeff]    movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]
722                  movq    mm3, [esi + 8*eax + 8]  ;    movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]
723                  pxor    mm1, mm1                ; mm1 = 0    pxor mm1, mm1
724                  pxor    mm4, mm4                ;    pxor mm4, mm4
725                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)    pcmpgtw mm1, mm0  ; sign(c)
726                  pcmpgtw mm4, mm3                ;    pcmpgtw mm4, mm3  ; sign(c')
727                  pxor    mm2, mm2                ; mm2 = 0    pxor mm2, mm2
728                  pxor    mm5, mm5                ;    pxor mm5, mm5
729                  pcmpeqw mm2, mm0                ; mm2 = (0 == mm0)    pcmpeqw mm2, mm0  ; c is zero
730                  pcmpeqw mm5, mm3                ;    pcmpeqw mm5, mm3  ; c' is zero
731                  pandn   mm2, mm6                ; mm2 = (iszero ? 0 : add)    pandn mm2, mm6    ; offset = isZero ? 0 : quant_add
732                  pandn   mm5, mm6                ;    pandn mm5, mm6
733                  pxor    mm0, mm1                ; mm0 = |mm0|    pxor mm0, mm1     ; negate if negative
734                  pxor    mm3, mm4                ;    pxor mm3, mm4     ; negate if negative
735                  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  
736                  psubw   mm3, mm4                  psubw   mm3, mm4
737      pmullw mm0, mm7 ; *= 2Q
738      pmullw mm3, mm7 ; *= 2Q
739      paddw mm0, mm2 ; + offset
740      paddw mm3, mm5 ; + offset
741      paddw mm0, mm1 ; negate back
742      paddw mm3, mm4 ; negate back
743    
744  %ifdef SATURATE      ; saturates to +2047
745                  movq mm2, [mmx_32767_minus_2047]                  movq mm2, [mmx_32767_minus_2047]
746                  movq mm4, [mmx_32768_minus_2048]    add eax, 2
747                  paddsw  mm0, mm2                  paddsw  mm0, mm2
748                  paddsw  mm3, mm2                  paddsw  mm3, mm2
749                  psubsw  mm0, mm2                  psubsw  mm0, mm2
750                  psubsw  mm3, mm2                  psubsw  mm3, mm2
                 psubsw  mm0, mm4  
                 psubsw  mm3, mm4  
                 paddsw  mm0, mm4  
                 paddsw  mm3, mm4  
 %endif  
751    
752                  movq    [edi + 8*eax], mm0              ; [data] = mm0    pxor mm0, mm1
753                  movq    [edi + 8*eax + 8], mm3    pxor mm3, mm4
754      movq [edx + 8*eax + 8*16   - 2*8], mm0
755                  add eax, 2    movq [edx + 8*eax + 8*16+8 - 2*8], mm3
                 cmp eax, 16  
756                  jnz     near .loop                  jnz     near .loop
757    
758                  mov     ax, [esi]                                       ; ax = data[0]      ; deal with DC
                 imul ax, [esp + 8 + 16]                 ; eax = data[0] * dcscalar  
759    
760  %ifdef SATURATE    movd mm0, [ecx]
761                  cmp ax, -2048    pmullw mm0, [esp+16]    ; dcscalar
762                  jl .set_n2048    movq mm2, [mmx_32767_minus_2047]
763                  cmp ax, 2047    paddsw mm0, mm2
764                  jg .set_2047    psubsw mm0, mm2
765  %endif    movq mm3, [mmx_32768_minus_2048]
766                  mov     [edi], ax    psubsw mm0, mm3
767      paddsw mm0, mm3
768      movd eax, mm0
769      mov [edx], ax
770    
                 pop     edi  
                 pop     esi  
771                  ret                  ret
772    
773  %ifdef SATURATE  ;===========================================================================
774    ;
775    ; void dequant_intra_xmm(int16_t *data,
776    ;                                       const int16_t const *coeff,
777    ;                                       const uint32_t quant,
778    ;                                       const uint32_t dcscalar);
779    ;
780    ;===========================================================================
781    
782      ; this is the same as dequant_inter_mmx, except that we're
783      ; saturating using 'pminsw' (saves 2 cycles/loop => ~5% faster)
784    
785  align ALIGN  align ALIGN
786  .set_n2048  cglobal dequant_intra_xmm
787                  mov     word [edi], -2048  dequant_intra_xmm:
788                  pop     edi  
789                  pop     esi    mov    edx, [esp+ 4]        ; data
790                  ret    mov    ecx, [esp+ 8]        ; coeff
791      mov    eax, [esp+12]        ; quant
792      movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1
793      movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant
794      mov eax, -16
795    
796  align ALIGN  align ALIGN
797  .set_2047  .loop
798                  mov     word [edi], 2047    movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]
799                  pop     edi    movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]
800                  pop     esi    pxor mm1, mm1
801                  ret    pxor mm4, mm4
802  %endif    pcmpgtw mm1, mm0  ; sign(c)
803      pcmpgtw mm4, mm3  ; sign(c')
804      pxor mm2, mm2
805      pxor mm5, mm5
806      pcmpeqw mm2, mm0  ; c is zero
807      pcmpeqw mm5, mm3  ; c' is zero
808      pandn mm2, mm6    ; offset = isZero ? 0 : quant_add
809      pandn mm5, mm6
810      pxor mm0, mm1     ; negate if negative
811      pxor mm3, mm4     ; negate if negative
812      psubw mm0, mm1
813      psubw mm3, mm4
814      pmullw mm0, mm7 ; *= 2Q
815      pmullw mm3, mm7 ; *= 2Q
816      paddw mm0, mm2 ; + offset
817      paddw mm3, mm5 ; + offset
818      paddw mm0, mm1 ; negate back
819      paddw mm3, mm4 ; negate back
820    
821        ; saturates to +2047
822      movq mm2, [mmx_2047]
823      pminsw mm0, mm2
824      add eax, 2
825      pminsw mm3, mm2
826    
827      pxor mm0, mm1
828      pxor mm3, mm4
829      movq [edx + 8*eax + 8*16   - 2*8], mm0
830      movq [edx + 8*eax + 8*16+8 - 2*8], mm3
831      jnz   near .loop
832    
833        ; deal with DC
834    
835      movd mm0, [ecx]
836      pmullw mm0, [esp+16]    ; dcscalar
837      movq mm2, [mmx_32767_minus_2047]
838      paddsw mm0, mm2
839      psubsw mm0, mm2
840      movq mm2, [mmx_32768_minus_2048]
841      psubsw mm0, mm2
842      paddsw mm0, mm2
843      movd eax, mm0
844      mov [edx], ax
845    
846      ret
847    
848    
849  ;===========================================================================  ;===========================================================================
# Line 813  Line 854 
854  ;                                       const uint32_t dcscalar);  ;                                       const uint32_t dcscalar);
855  ;  ;
856  ;===========================================================================  ;===========================================================================
857    align ALIGN
 align 16  
858  cglobal dequant_intra_sse2  cglobal dequant_intra_sse2
859  dequant_intra_sse2  dequant_intra_sse2:
860            mov edx, [esp+ 4]        ; data
861                  push    esi          mov ecx, [esp+ 8]        ; coeff
862                  push    edi          mov eax, [esp+12]        ; quant
   
                 mov             edi, [esp + 8 + 4]                      ; data  
                 mov             esi, [esp + 8 + 8]                      ; coeff  
                 mov             eax, [esp + 8 + 12]                     ; quant  
   
863                  movq    mm6, [mmx_add + eax*8 - 8]                  movq    mm6, [mmx_add + eax*8 - 8]
864                  movq    mm7, [mmx_mul + eax*8 - 8]                  movq    mm7, [mmx_mul + eax*8 - 8]
865                  movq2dq xmm6, mm6                  movq2dq xmm6, mm6
866                  movq2dq xmm7, mm7                  movq2dq xmm7, mm7
867                  movlhps xmm6, xmm6                  movlhps xmm6, xmm6
868                  movlhps xmm7, xmm7                  movlhps xmm7, xmm7
869            mov eax, -16
870    
871                  xor             eax, eax  align ALIGN
872    .loop
873  align 16          movdqa xmm0, [ecx + 8*16 + 8*eax]      ; c  = coeff[i]
874  .das2_loop          movdqa xmm3, [ecx + 8*16 + 8*eax+ 16]
                 movdqa  xmm0, [esi + eax*8]  
                 movdqa  xmm3, [esi + eax*8 + 16]  
875                  pxor    xmm1, xmm1                  pxor    xmm1, xmm1
876                  pxor    xmm4, xmm4                  pxor    xmm4, xmm4
877                  pcmpgtw xmm1, xmm0          pcmpgtw xmm1, xmm0  ; sign(c)
878                  pcmpgtw xmm4, xmm3                  pcmpgtw xmm4, xmm3
879                  pxor    xmm2, xmm2                  pxor    xmm2, xmm2
880                  pxor    xmm5, xmm5                  pxor    xmm5, xmm5
881                  pcmpeqw xmm2, xmm0          pcmpeqw xmm2, xmm0  ; c is zero
882                  pcmpeqw xmm5, xmm3                  pcmpeqw xmm5, xmm3
883                  pandn   xmm2, xmm6          pandn xmm2, xmm6    ; offset = isZero ? 0 : quant_add
884                  pandn   xmm5, xmm6                  pandn   xmm5, xmm6
885                  pxor    xmm0, xmm1          pxor xmm0, xmm1     ; negate if negative
886                  pxor    xmm3, xmm4                  pxor    xmm3, xmm4
887                  psubw   xmm0, xmm1                  psubw   xmm0, xmm1
888                  psubw   xmm3, xmm4                  psubw   xmm3, xmm4
889                  pmullw  xmm0, xmm7          pmullw xmm0, xmm7 ; *= 2Q
890                  pmullw  xmm3, xmm7                  pmullw  xmm3, xmm7
891                  paddw   xmm0, xmm2          paddw xmm0, xmm2 ; + offset
892                  paddw   xmm3, xmm5                  paddw   xmm3, xmm5
893                  pxor    xmm0, xmm1          paddw xmm0, xmm1 ; negate back
894                  pxor    xmm3, xmm4          paddw xmm3, xmm4
                 psubw   xmm0, xmm1  
                 psubw   xmm3, xmm4  
895    
896  %ifdef SATURATE          ; saturates to +2047
897                  movdqu  xmm2, [sse2_pos_2047]          movdqa xmm2, [sse2_2047]
                 movdqu  xmm4, [sse2_neg_2048]  
898                  pminsw  xmm0, xmm2                  pminsw  xmm0, xmm2
                 pminsw  xmm3, xmm2  
                 pmaxsw  xmm0, xmm4  
                 pmaxsw  xmm3, xmm4  
 %endif  
   
                 movdqa  [edi + eax*8], xmm0  
                 movdqa  [edi + eax*8 + 16], xmm3  
   
899                  add             eax, 4                  add             eax, 4
900                  cmp             eax, 16          pminsw xmm3, xmm2
                 jnz             near .das2_loop  
   
                 mov             ax, [esi]                                       ; ax = data[0]  
                 imul    ax, [esp + 8 + 16]                      ; eax = data[0] * dcscalar  
901    
902  %ifdef SATURATE          pxor xmm0, xmm1
903                  cmp             ax, -2048          pxor xmm3, xmm4
904                  jl              .das2_set_n2048          movdqa [edx + 8*16 - 8*4 + 8*eax], xmm0
905                  cmp             ax, 2047          movdqa [edx + 8*16 - 8*4 + 8*eax + 16], xmm3
906                  jg              .das2_set_2047          jnz     near .loop
 %endif  
                 mov             [edi], ax  
907    
908                  pop             edi          ; deal with DC
909                  pop             esi          movd mm0, [ecx]
910                  ret          pmullw mm0, [esp+16]    ; dcscalar
911            movq mm2, [mmx_32767_minus_2047]
912            paddsw mm0, mm2
913            psubsw mm0, mm2
914            movq mm2, [mmx_32768_minus_2048]
915            psubsw mm0, mm2
916            paddsw mm0, mm2
917            movd eax, mm0
918            mov [edx], ax
919    
 %ifdef SATURATE  
 align 16  
 .das2_set_n2048  
                 mov             word [edi], -2048  
                 pop             edi  
                 pop             esi  
920                  ret                  ret
921    
 align 16  
 .das2_set_2047  
                 mov             word [edi], 2047  
                 pop             edi  
                 pop             esi  
                 ret  
 %endif  
922    
923    
924    
# Line 920  Line 932 
932    
933  align ALIGN  align ALIGN
934  cglobal dequant_inter_mmx  cglobal dequant_inter_mmx
935  dequant_inter_mmx  dequant_inter_mmx:
   
                 push    esi  
                 push    edi  
   
                 mov     edi, [esp + 8 + 4]      ; data  
                 mov     esi, [esp + 8 + 8]      ; coeff  
                 mov     eax, [esp + 8 + 12]     ; quant  
                 movq    mm6, [mmx_add + eax * 8 - 8]  
                 movq    mm7, [mmx_mul + eax * 8 - 8]  
936    
937                  xor eax, eax    mov    edx, [esp+ 4]        ; data
938      mov    ecx, [esp+ 8]        ; coeff
939      mov    eax, [esp+12]        ; quant
940      movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1
941      movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant
942      mov eax, -16
943    
944  align ALIGN  align ALIGN
945  .loop  .loop
946                  movq    mm0, [esi + 8*eax]                      ; mm0 = [coeff]    movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]
947                  movq    mm3, [esi + 8*eax + 8]          ;    movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]
948                  pxor    mm1, mm1                ; mm1 = 0    pxor mm1, mm1
949                  pxor    mm4, mm4                ;    pxor mm4, mm4
950                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)    pcmpgtw mm1, mm0  ; sign(c)
951                  pcmpgtw mm4, mm3                ;    pcmpgtw mm4, mm3  ; sign(c')
952                  pxor    mm2, mm2                ; mm2 = 0    pxor mm2, mm2
953                  pxor    mm5, mm5                ;    pxor mm5, mm5
954                  pcmpeqw mm2, mm0                ; mm2 = (0 == mm0)    pcmpeqw mm2, mm0  ; c is zero
955                  pcmpeqw mm5, mm3                ;    pcmpeqw mm5, mm3  ; c' is zero
956                  pandn   mm2, mm6                ; mm2 = (iszero ? 0 : add)    pandn mm2, mm6    ; offset = isZero ? 0 : quant_add
957                  pandn   mm5, mm6                ;    pandn mm5, mm6
958                  pxor    mm0, mm1                ; mm0 = |mm0|    pxor mm0, mm1     ; negate if negative
959                  pxor    mm3, mm4                ;    pxor mm3, mm4     ; negate if negative
960                  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  
961                  psubw   mm3, mm4                  psubw   mm3, mm4
962      pmullw mm0, mm7 ; *= 2Q
963      pmullw mm3, mm7 ; *= 2Q
964      paddw mm0, mm2 ; + offset
965      paddw mm3, mm5 ; + offset
966      paddw mm0, mm1 ; negate back
967      paddw mm3, mm4 ; negate back
968    
969  %ifdef SATURATE      ; saturates to +2047
970                  movq mm2, [mmx_32767_minus_2047]                  movq mm2, [mmx_32767_minus_2047]
971                  movq mm4, [mmx_32768_minus_2048]    add eax, 2
972                  paddsw  mm0, mm2                  paddsw  mm0, mm2
973                  paddsw  mm3, mm2                  paddsw  mm3, mm2
974                  psubsw  mm0, mm2                  psubsw  mm0, mm2
975                  psubsw  mm3, mm2                  psubsw  mm3, mm2
                 psubsw  mm0, mm4  
                 psubsw  mm3, mm4  
                 paddsw  mm0, mm4  
                 paddsw  mm3, mm4  
 %endif  
976    
977                  movq    [edi + 8*eax], mm0    pxor mm0, mm1
978                  movq    [edi + 8*eax + 8], mm3    pxor mm3, mm4
979      movq [edx + 8*eax + 8*16   - 2*8], mm0
980      movq [edx + 8*eax + 8*16+8 - 2*8], mm3
981      jnz   near .loop
982    
983      ret
984    
985    ;===========================================================================
986    ;
987    ; void dequant_inter_xmm(int16_t * data,
988    ;                                       const int16_t * const coeff,
989    ;                                       const uint32_t quant);
990    ;
991    ;===========================================================================
992    
993      ; this is the same as dequant_inter_mmx,
994      ; except that we're saturating using 'pminsw' (saves 2 cycles/loop)
995    
996    align ALIGN
997    cglobal dequant_inter_xmm
998    dequant_inter_xmm:
999    
1000      mov    edx, [esp+ 4]        ; data
1001      mov    ecx, [esp+ 8]        ; coeff
1002      mov    eax, [esp+12]        ; quant
1003      movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1
1004      movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant
1005      mov eax, -16
1006    
1007    align ALIGN
1008    .loop
1009      movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]
1010      movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]
1011      pxor mm1, mm1
1012      pxor mm4, mm4
1013      pcmpgtw mm1, mm0  ; sign(c)
1014      pcmpgtw mm4, mm3  ; sign(c')
1015      pxor mm2, mm2
1016      pxor mm5, mm5
1017      pcmpeqw mm2, mm0  ; c is zero
1018      pcmpeqw mm5, mm3  ; c' is zero
1019      pandn mm2, mm6    ; offset = isZero ? 0 : quant_add
1020      pandn mm5, mm6
1021      pxor mm0, mm1     ; negate if negative
1022      pxor mm3, mm4     ; negate if negative
1023      psubw mm0, mm1
1024      psubw mm3, mm4
1025      pmullw mm0, mm7 ; *= 2Q
1026      pmullw mm3, mm7 ; *= 2Q
1027      paddw mm0, mm2 ; + offset
1028      paddw mm3, mm5 ; + offset
1029      paddw mm0, mm1 ; start restoring sign
1030      paddw mm3, mm4 ; start restoring sign
1031    
1032          ; saturates to +2047
1033      movq mm2, [mmx_2047]
1034      pminsw mm0, mm2
1035                  add eax, 2                  add eax, 2
1036                  cmp eax, 16    pminsw mm3, mm2
                 jnz     near .loop  
1037    
1038                  pop     edi    pxor mm0, mm1 ; finish restoring sign
1039                  pop     esi    pxor mm3, mm4 ; finish restoring sign
1040      movq [edx + 8*eax + 8*16   - 2*8], mm0
1041      movq [edx + 8*eax + 8*16+8 - 2*8], mm3
1042      jnz   near .loop
1043    
1044                  ret                  ret
1045    
   
1046  ;===========================================================================  ;===========================================================================
1047  ;  ;
1048  ; void dequant_inter_sse2(int16_t * data,  ; void dequant_inter_sse2(int16_t * data,
# Line 993  Line 1050 
1050  ;                                       const uint32_t quant);  ;                                       const uint32_t quant);
1051  ;  ;
1052  ;===========================================================================  ;===========================================================================
1053    align ALIGN
 align 16  
1054  cglobal dequant_inter_sse2  cglobal dequant_inter_sse2
1055  dequant_inter_sse2  dequant_inter_sse2
1056            mov edx, [esp + 4]      ; data
1057                  push    esi          mov ecx, [esp + 8]      ; coeff
1058                  push    edi          mov eax, [esp + 12]     ; quant
   
                 mov     edi, [esp + 8 + 4]      ; data  
                 mov     esi, [esp + 8 + 8]      ; coeff  
                 mov     eax, [esp + 8 + 12]     ; quant  
1059                  movq    mm6, [mmx_add + eax * 8 - 8]                  movq    mm6, [mmx_add + eax * 8 - 8]
1060                  movq    mm7, [mmx_mul + eax * 8 - 8]                  movq    mm7, [mmx_mul + eax * 8 - 8]
   
1061                  movq2dq xmm6, mm6                  movq2dq xmm6, mm6
1062                  movq2dq xmm7, mm7                  movq2dq xmm7, mm7
1063                  movlhps xmm6, xmm6                  movlhps xmm6, xmm6
1064                  movlhps xmm7, xmm7                  movlhps xmm7, xmm7
1065            mov eax, -16
1066    
1067                  xor eax, eax  align ALIGN
1068    .loop
1069            movdqa xmm0, [ecx + 8*16 + 8*eax]  ; c  = coeff[i]
1070            movdqa xmm3, [ecx + 8*16 + 8*eax + 16]
1071    
 align 16  
 .des2_loop  
                 movdqa  xmm0, [esi + eax*8]                     ; xmm0 = [coeff]  
                 movdqa  xmm3, [esi + eax*8 + 16]  
1072                  pxor    xmm1, xmm1                  pxor    xmm1, xmm1
1073                  pxor    xmm4, xmm4                  pxor    xmm4, xmm4
1074                  pcmpgtw xmm1, xmm0          pcmpgtw xmm1, xmm0  ; sign(c)
1075                  pcmpgtw xmm4, xmm3                  pcmpgtw xmm4, xmm3
1076                  pxor    xmm2, xmm2                  pxor    xmm2, xmm2
1077                  pxor    xmm5, xmm5                  pxor    xmm5, xmm5
1078                  pcmpeqw xmm2, xmm0          pcmpeqw xmm2, xmm0  ; c is zero
1079                  pcmpeqw xmm5, xmm3                  pcmpeqw xmm5, xmm3
1080                  pandn   xmm2, xmm6                  pandn   xmm2, xmm6
1081                  pandn   xmm5, xmm6                  pandn   xmm5, xmm6
1082                  pxor    xmm0, xmm1          pxor xmm0, xmm1  ; negate if negative
1083                  pxor    xmm3, xmm4                  pxor    xmm3, xmm4
1084                  psubw   xmm0, xmm1                  psubw   xmm0, xmm1
1085                  psubw   xmm3, xmm4                  psubw   xmm3, xmm4
1086                  pmullw  xmm0, xmm7          pmullw xmm0, xmm7  ; *= 2Q
1087                  pmullw  xmm3, xmm7                  pmullw  xmm3, xmm7
1088                  paddw   xmm0, xmm2          paddw xmm0, xmm2  ; + offset
1089                  paddw   xmm3, xmm5                  paddw   xmm3, xmm5
                 pxor    xmm0, xmm1  
                 pxor    xmm3, xmm4  
                 psubw   xmm0, xmm1  
                 psubw   xmm3, xmm4  
   
 %ifdef SATURATE  
                 movdqu  xmm2, [sse2_pos_2047]  
                 movdqu  xmm4, [sse2_neg_2048]  
                 pminsw  xmm0, xmm2  
                 pminsw  xmm3, xmm2  
                 pmaxsw  xmm0, xmm4  
                 pmaxsw  xmm3, xmm4  
 %endif  
1090    
1091                  movdqa  [edi + eax*8], xmm0          paddw xmm0, xmm1  ; start restoring sign
1092                  movdqa  [edi + eax*8 + 16], xmm3          paddw xmm3, xmm4
1093    
1094            ; saturates to +2047
1095            movdqa xmm2, [sse2_2047]
1096            pminsw xmm0, xmm2
1097                  add eax, 4                  add eax, 4
1098                  cmp eax, 16          pminsw xmm3, xmm2
                 jnz     near .des2_loop  
1099    
1100                  pop     edi          pxor xmm0, xmm1 ; finish restoring sign
1101                  pop     esi          pxor xmm3, xmm4
1102            movdqa [edx + 8*16 - 8*4 + 8*eax], xmm0
1103            movdqa [edx + 8*16 - 8*4 + 8*eax + 16], xmm3
1104            jnz     near .loop
1105    
1106                  ret                  ret

Legend:
Removed from v.135  
changed lines
  Added in v.463

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