[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 653, Sun Nov 17 00:41:20 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  ; *     This program is an implementation of a part of one or more MPEG-4  ; *  Copyright(C) 2002 Peter Ross <pross@xvid.org>
7  ; *     Video tools as specified in ISO/IEC 14496-2 standard.  Those intending  ; *  Copyright(C) 2002 Michael Militzer <michael@xvid.org>
8  ; *     to use this software module in hardware or software products are  ; *  Copyright(C) 2002 Pascal Massimino <skal@planet-d.net>
 ; *     advised that its use may infringe existing patents or copyrights, and  
 ; *     any such use would be at such party's own risk.  The original  
 ; *     developer of this software module and his/her company, and subsequent  
 ; *     editors and their companies, will have no liability for use of this  
 ; *     software or modifications or derivatives thereof.  
9  ; *  ; *
10  ; *     This program is free software; you can redistribute it and/or modify  ; *  This file is part of XviD, a free MPEG-4 video encoder/decoder
11  ; *     it under the terms of the GNU General Public License as published by  ; *
12    ; *  XviD is free software; you can redistribute it and/or modify it
13    ; *  under the terms of the GNU General Public License as published by
14  ; *     the Free Software Foundation; either version 2 of the License, or  ; *     the Free Software Foundation; either version 2 of the License, or
15  ; *     (at your option) any later version.  ; *     (at your option) any later version.
16  ; *  ; *
# Line 24  Line 21 
21  ; *  ; *
22  ; *     You should have received a copy of the GNU General Public License  ; *     You should have received a copy of the GNU General Public License
23  ; *     along with this program; if not, write to the Free Software  ; *     along with this program; if not, write to the Free Software
24  ; *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  ; *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
25  ; *  ; *
26  ; *************************************************************************/  ; *  Under section 8 of the GNU General Public License, the copyright
27    ; *  holders of XVID explicitly forbid distribution in the following
28  ;/**************************************************************************  ; *  countries:
29    ; *
30    ; *    - Japan
31    ; *    - United States of America
32    ; *
33    ; *  Linking XviD statically or dynamically with other modules is making a
34    ; *  combined work based on XviD.  Thus, the terms and conditions of the
35    ; *  GNU General Public License cover the whole combination.
36    ; *
37    ; *  As a special exception, the copyright holders of XviD give you
38    ; *  permission to link XviD with independent modules that communicate with
39    ; *  XviD solely through the VFW1.1 and DShow interfaces, regardless of the
40    ; *  license terms of these independent modules, and to copy and distribute
41    ; *  the resulting combined work under terms of your choice, provided that
42    ; *  every copy of the combined work is accompanied by a complete copy of
43    ; *  the source code of XviD (the version of XviD used to produce the
44    ; *  combined work), being distributed under the terms of the GNU General
45    ; *  Public License plus this exception.  An independent module is a module
46    ; *  which is not derived from or based on XviD.
47  ; *  ; *
48  ; *     History:  ; *  Note that people who make modified versions of XviD are not obligated
49    ; *  to grant this special exception for their modified versions; it is
50    ; *  their choice whether to do so.  The GNU General Public License gives
51    ; *  permission to release a modified version without this exception; this
52    ; *  exception also makes it possible to release a modified version which
53    ; *  carries forward this exception.
54  ; *  ; *
55  ; * 24.02.2002  sse2 quant_intra / dequant_intra (have to use movdqu ???)  ; * $Id: quantize_mmx.asm,v 1.7 2002-11-17 00:41:20 edgomez Exp $
 ; * 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>  
56  ; *  ; *
57  ; *************************************************************************/  ; *************************************************************************/
58    
# Line 64  Line 80 
80    
81  plus_one times 8        dw       1  plus_one times 8        dw       1
82    
   
83  ;===========================================================================  ;===========================================================================
84  ;  ;
85  ; subtract by Q/2 table  ; subtract by Q/2 table
# Line 261  Line 276 
276  ;  ;
277  ;===========================================================================  ;===========================================================================
278    
279  align ALIGN  align 16
280  mmx_32768_minus_2048                            times 4 dw (32768-2048)  sse2_2047       times 8 dw 2047
 mmx_32767_minus_2047                            times 4 dw (32767-2047)  
281    
282  align 16  align 16
283  sse2_pos_2047                                           times 8 dw 2047  mmx_2047        times 4 dw 2047
284  sse2_neg_2048                                           times 8 dw -2048  
285    align 8
286    mmx_32768_minus_2048                            times 4 dw (32768-2048)
287    mmx_32767_minus_2047                            times 4 dw (32767-2047)
288    
289    
290  section .text  section .text
# Line 700  Line 717 
717                  jmp             .qes2_done                  jmp             .qes2_done
718    
719    
   
720  ;===========================================================================  ;===========================================================================
721  ;  ;
722  ; void dequant_intra_mmx(int16_t *data,  ; void dequant_intra_mmx(int16_t *data,
# Line 710  Line 726 
726  ;  ;
727  ;===========================================================================  ;===========================================================================
728    
729      ; note: we only saturate to +2047 *before* restoring the sign.
730      ; Hence, final clamp really is [-2048,2047]
731    
732  align ALIGN  align ALIGN
733  cglobal dequant_intra_mmx  cglobal dequant_intra_mmx
734  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  
735    
736                  movq    mm6, [mmx_add + eax * 8 - 8]    mov    edx, [esp+ 4]        ; data
737                  movq    mm7, [mmx_mul + eax * 8 - 8]    mov    ecx, [esp+ 8]        ; coeff
738                  xor eax, eax    mov    eax, [esp+12]        ; quant
739      movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1
740      movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant
741      mov eax, -16
742    
743  align ALIGN  align ALIGN
744  .loop  .loop
745                  movq    mm0, [esi + 8*eax]              ; mm0 = [coeff]    movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]
746                  movq    mm3, [esi + 8*eax + 8]  ;    movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]
747                  pxor    mm1, mm1                ; mm1 = 0    pxor mm1, mm1
748                  pxor    mm4, mm4                ;    pxor mm4, mm4
749                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)    pcmpgtw mm1, mm0  ; sign(c)
750                  pcmpgtw mm4, mm3                ;    pcmpgtw mm4, mm3  ; sign(c')
751                  pxor    mm2, mm2                ; mm2 = 0    pxor mm2, mm2
752                  pxor    mm5, mm5                ;    pxor mm5, mm5
753                  pcmpeqw mm2, mm0                ; mm2 = (0 == mm0)    pcmpeqw mm2, mm0  ; c is zero
754                  pcmpeqw mm5, mm3                ;    pcmpeqw mm5, mm3  ; c' is zero
755                  pandn   mm2, mm6                ; mm2 = (iszero ? 0 : add)    pandn mm2, mm6    ; offset = isZero ? 0 : quant_add
756                  pandn   mm5, mm6                ;    pandn mm5, mm6
757                  pxor    mm0, mm1                ; mm0 = |mm0|    pxor mm0, mm1     ; negate if negative
758                  pxor    mm3, mm4                ;    pxor mm3, mm4     ; negate if negative
759                  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  
760                  psubw   mm3, mm4                  psubw   mm3, mm4
761      pmullw mm0, mm7 ; *= 2Q
762      pmullw mm3, mm7 ; *= 2Q
763      paddw mm0, mm2 ; + offset
764      paddw mm3, mm5 ; + offset
765      paddw mm0, mm1 ; negate back
766      paddw mm3, mm4 ; negate back
767    
768  %ifdef SATURATE      ; saturates to +2047
769                  movq mm2, [mmx_32767_minus_2047]                  movq mm2, [mmx_32767_minus_2047]
770                  movq mm4, [mmx_32768_minus_2048]    add eax, 2
771                  paddsw  mm0, mm2                  paddsw  mm0, mm2
772                  paddsw  mm3, mm2                  paddsw  mm3, mm2
773                  psubsw  mm0, mm2                  psubsw  mm0, mm2
774                  psubsw  mm3, mm2                  psubsw  mm3, mm2
                 psubsw  mm0, mm4  
                 psubsw  mm3, mm4  
                 paddsw  mm0, mm4  
                 paddsw  mm3, mm4  
 %endif  
775    
776                  movq    [edi + 8*eax], mm0              ; [data] = mm0    pxor mm0, mm1
777                  movq    [edi + 8*eax + 8], mm3    pxor mm3, mm4
778      movq [edx + 8*eax + 8*16   - 2*8], mm0
779                  add eax, 2    movq [edx + 8*eax + 8*16+8 - 2*8], mm3
                 cmp eax, 16  
780                  jnz     near .loop                  jnz     near .loop
781    
782                  mov     ax, [esi]                                       ; ax = data[0]      ; deal with DC
                 imul ax, [esp + 8 + 16]                 ; eax = data[0] * dcscalar  
783    
784  %ifdef SATURATE    movd mm0, [ecx]
785                  cmp ax, -2048    pmullw mm0, [esp+16]    ; dcscalar
786                  jl .set_n2048    movq mm2, [mmx_32767_minus_2047]
787                  cmp ax, 2047    paddsw mm0, mm2
788                  jg .set_2047    psubsw mm0, mm2
789  %endif    movq mm3, [mmx_32768_minus_2048]
790                  mov     [edi], ax    psubsw mm0, mm3
791      paddsw mm0, mm3
792      movd eax, mm0
793      mov [edx], ax
794    
                 pop     edi  
                 pop     esi  
795                  ret                  ret
796    
797  %ifdef SATURATE  ;===========================================================================
798    ;
799    ; void dequant_intra_xmm(int16_t *data,
800    ;                                       const int16_t const *coeff,
801    ;                                       const uint32_t quant,
802    ;                                       const uint32_t dcscalar);
803    ;
804    ;===========================================================================
805    
806      ; this is the same as dequant_inter_mmx, except that we're
807      ; saturating using 'pminsw' (saves 2 cycles/loop => ~5% faster)
808    
809  align ALIGN  align ALIGN
810  .set_n2048  cglobal dequant_intra_xmm
811                  mov     word [edi], -2048  dequant_intra_xmm:
812                  pop     edi  
813                  pop     esi    mov    edx, [esp+ 4]        ; data
814                  ret    mov    ecx, [esp+ 8]        ; coeff
815      mov    eax, [esp+12]        ; quant
816      movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1
817      movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant
818      mov eax, -16
819    
820  align ALIGN  align ALIGN
821  .set_2047  .loop
822                  mov     word [edi], 2047    movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]
823                  pop     edi    movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]
824                  pop     esi    pxor mm1, mm1
825                  ret    pxor mm4, mm4
826  %endif    pcmpgtw mm1, mm0  ; sign(c)
827      pcmpgtw mm4, mm3  ; sign(c')
828      pxor mm2, mm2
829      pxor mm5, mm5
830      pcmpeqw mm2, mm0  ; c is zero
831      pcmpeqw mm5, mm3  ; c' is zero
832      pandn mm2, mm6    ; offset = isZero ? 0 : quant_add
833      pandn mm5, mm6
834      pxor mm0, mm1     ; negate if negative
835      pxor mm3, mm4     ; negate if negative
836      psubw mm0, mm1
837      psubw mm3, mm4
838      pmullw mm0, mm7 ; *= 2Q
839      pmullw mm3, mm7 ; *= 2Q
840      paddw mm0, mm2 ; + offset
841      paddw mm3, mm5 ; + offset
842      paddw mm0, mm1 ; negate back
843      paddw mm3, mm4 ; negate back
844    
845        ; saturates to +2047
846      movq mm2, [mmx_2047]
847      pminsw mm0, mm2
848      add eax, 2
849      pminsw mm3, mm2
850    
851      pxor mm0, mm1
852      pxor mm3, mm4
853      movq [edx + 8*eax + 8*16   - 2*8], mm0
854      movq [edx + 8*eax + 8*16+8 - 2*8], mm3
855      jnz   near .loop
856    
857        ; deal with DC
858    
859      movd mm0, [ecx]
860      pmullw mm0, [esp+16]    ; dcscalar
861      movq mm2, [mmx_32767_minus_2047]
862      paddsw mm0, mm2
863      psubsw mm0, mm2
864      movq mm2, [mmx_32768_minus_2048]
865      psubsw mm0, mm2
866      paddsw mm0, mm2
867      movd eax, mm0
868      mov [edx], ax
869    
870      ret
871    
872    
873  ;===========================================================================  ;===========================================================================
# Line 813  Line 878 
878  ;                                       const uint32_t dcscalar);  ;                                       const uint32_t dcscalar);
879  ;  ;
880  ;===========================================================================  ;===========================================================================
881    align ALIGN
 align 16  
882  cglobal dequant_intra_sse2  cglobal dequant_intra_sse2
883  dequant_intra_sse2  dequant_intra_sse2:
884            mov edx, [esp+ 4]        ; data
885                  push    esi          mov ecx, [esp+ 8]        ; coeff
886                  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  
   
887                  movq    mm6, [mmx_add + eax*8 - 8]                  movq    mm6, [mmx_add + eax*8 - 8]
888                  movq    mm7, [mmx_mul + eax*8 - 8]                  movq    mm7, [mmx_mul + eax*8 - 8]
889                  movq2dq xmm6, mm6                  movq2dq xmm6, mm6
890                  movq2dq xmm7, mm7                  movq2dq xmm7, mm7
891                  movlhps xmm6, xmm6                  movlhps xmm6, xmm6
892                  movlhps xmm7, xmm7                  movlhps xmm7, xmm7
893            mov eax, -16
894    
895                  xor             eax, eax  align ALIGN
896    .loop
897  align 16          movdqa xmm0, [ecx + 8*16 + 8*eax]      ; c  = coeff[i]
898  .das2_loop          movdqa xmm3, [ecx + 8*16 + 8*eax+ 16]
                 movdqa  xmm0, [esi + eax*8]  
                 movdqa  xmm3, [esi + eax*8 + 16]  
899                  pxor    xmm1, xmm1                  pxor    xmm1, xmm1
900                  pxor    xmm4, xmm4                  pxor    xmm4, xmm4
901                  pcmpgtw xmm1, xmm0          pcmpgtw xmm1, xmm0  ; sign(c)
902                  pcmpgtw xmm4, xmm3                  pcmpgtw xmm4, xmm3
903                  pxor    xmm2, xmm2                  pxor    xmm2, xmm2
904                  pxor    xmm5, xmm5                  pxor    xmm5, xmm5
905                  pcmpeqw xmm2, xmm0          pcmpeqw xmm2, xmm0  ; c is zero
906                  pcmpeqw xmm5, xmm3                  pcmpeqw xmm5, xmm3
907                  pandn   xmm2, xmm6          pandn xmm2, xmm6    ; offset = isZero ? 0 : quant_add
908                  pandn   xmm5, xmm6                  pandn   xmm5, xmm6
909                  pxor    xmm0, xmm1          pxor xmm0, xmm1     ; negate if negative
910                  pxor    xmm3, xmm4                  pxor    xmm3, xmm4
911                  psubw   xmm0, xmm1                  psubw   xmm0, xmm1
912                  psubw   xmm3, xmm4                  psubw   xmm3, xmm4
913                  pmullw  xmm0, xmm7          pmullw xmm0, xmm7 ; *= 2Q
914                  pmullw  xmm3, xmm7                  pmullw  xmm3, xmm7
915                  paddw   xmm0, xmm2          paddw xmm0, xmm2 ; + offset
916                  paddw   xmm3, xmm5                  paddw   xmm3, xmm5
917                  pxor    xmm0, xmm1          paddw xmm0, xmm1 ; negate back
918                  pxor    xmm3, xmm4          paddw xmm3, xmm4
                 psubw   xmm0, xmm1  
                 psubw   xmm3, xmm4  
919    
920  %ifdef SATURATE          ; saturates to +2047
921                  movdqu  xmm2, [sse2_pos_2047]          movdqa xmm2, [sse2_2047]
                 movdqu  xmm4, [sse2_neg_2048]  
922                  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  
   
923                  add             eax, 4                  add             eax, 4
924                  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  
925    
926  %ifdef SATURATE          pxor xmm0, xmm1
927                  cmp             ax, -2048          pxor xmm3, xmm4
928                  jl              .das2_set_n2048          movdqa [edx + 8*16 - 8*4 + 8*eax], xmm0
929                  cmp             ax, 2047          movdqa [edx + 8*16 - 8*4 + 8*eax + 16], xmm3
930                  jg              .das2_set_2047          jnz     near .loop
 %endif  
                 mov             [edi], ax  
931    
932                  pop             edi          ; deal with DC
933                  pop             esi          movd mm0, [ecx]
934                  ret          pmullw mm0, [esp+16]    ; dcscalar
935            movq mm2, [mmx_32767_minus_2047]
936            paddsw mm0, mm2
937            psubsw mm0, mm2
938            movq mm2, [mmx_32768_minus_2048]
939            psubsw mm0, mm2
940            paddsw mm0, mm2
941            movd eax, mm0
942            mov [edx], ax
943    
 %ifdef SATURATE  
 align 16  
 .das2_set_n2048  
                 mov             word [edi], -2048  
                 pop             edi  
                 pop             esi  
944                  ret                  ret
945    
 align 16  
 .das2_set_2047  
                 mov             word [edi], 2047  
                 pop             edi  
                 pop             esi  
                 ret  
 %endif  
946    
947    
948    
# Line 920  Line 956 
956    
957  align ALIGN  align ALIGN
958  cglobal dequant_inter_mmx  cglobal dequant_inter_mmx
959  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]  
960    
961                  xor eax, eax    mov    edx, [esp+ 4]        ; data
962      mov    ecx, [esp+ 8]        ; coeff
963      mov    eax, [esp+12]        ; quant
964      movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1
965      movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant
966      mov eax, -16
967    
968  align ALIGN  align ALIGN
969  .loop  .loop
970                  movq    mm0, [esi + 8*eax]                      ; mm0 = [coeff]    movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]
971                  movq    mm3, [esi + 8*eax + 8]          ;    movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]
972                  pxor    mm1, mm1                ; mm1 = 0    pxor mm1, mm1
973                  pxor    mm4, mm4                ;    pxor mm4, mm4
974                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)    pcmpgtw mm1, mm0  ; sign(c)
975                  pcmpgtw mm4, mm3                ;    pcmpgtw mm4, mm3  ; sign(c')
976                  pxor    mm2, mm2                ; mm2 = 0    pxor mm2, mm2
977                  pxor    mm5, mm5                ;    pxor mm5, mm5
978                  pcmpeqw mm2, mm0                ; mm2 = (0 == mm0)    pcmpeqw mm2, mm0  ; c is zero
979                  pcmpeqw mm5, mm3                ;    pcmpeqw mm5, mm3  ; c' is zero
980                  pandn   mm2, mm6                ; mm2 = (iszero ? 0 : add)    pandn mm2, mm6    ; offset = isZero ? 0 : quant_add
981                  pandn   mm5, mm6                ;    pandn mm5, mm6
982                  pxor    mm0, mm1                ; mm0 = |mm0|    pxor mm0, mm1     ; negate if negative
983                  pxor    mm3, mm4                ;    pxor mm3, mm4     ; negate if negative
984                  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  
985                  psubw   mm3, mm4                  psubw   mm3, mm4
986      pmullw mm0, mm7 ; *= 2Q
987      pmullw mm3, mm7 ; *= 2Q
988      paddw mm0, mm2 ; + offset
989      paddw mm3, mm5 ; + offset
990      paddw mm0, mm1 ; negate back
991      paddw mm3, mm4 ; negate back
992    
993  %ifdef SATURATE      ; saturates to +2047
994                  movq mm2, [mmx_32767_minus_2047]                  movq mm2, [mmx_32767_minus_2047]
995                  movq mm4, [mmx_32768_minus_2048]    add eax, 2
996                  paddsw  mm0, mm2                  paddsw  mm0, mm2
997                  paddsw  mm3, mm2                  paddsw  mm3, mm2
998                  psubsw  mm0, mm2                  psubsw  mm0, mm2
999                  psubsw  mm3, mm2                  psubsw  mm3, mm2
                 psubsw  mm0, mm4  
                 psubsw  mm3, mm4  
                 paddsw  mm0, mm4  
                 paddsw  mm3, mm4  
 %endif  
1000    
1001                  movq    [edi + 8*eax], mm0    pxor mm0, mm1
1002                  movq    [edi + 8*eax + 8], mm3    pxor mm3, mm4
1003      movq [edx + 8*eax + 8*16   - 2*8], mm0
1004      movq [edx + 8*eax + 8*16+8 - 2*8], mm3
1005      jnz   near .loop
1006    
1007      ret
1008    
1009    ;===========================================================================
1010    ;
1011    ; void dequant_inter_xmm(int16_t * data,
1012    ;                                       const int16_t * const coeff,
1013    ;                                       const uint32_t quant);
1014    ;
1015    ;===========================================================================
1016    
1017      ; this is the same as dequant_inter_mmx,
1018      ; except that we're saturating using 'pminsw' (saves 2 cycles/loop)
1019    
1020    align ALIGN
1021    cglobal dequant_inter_xmm
1022    dequant_inter_xmm:
1023    
1024      mov    edx, [esp+ 4]        ; data
1025      mov    ecx, [esp+ 8]        ; coeff
1026      mov    eax, [esp+12]        ; quant
1027      movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1
1028      movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant
1029      mov eax, -16
1030    
1031    align ALIGN
1032    .loop
1033      movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]
1034      movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]
1035      pxor mm1, mm1
1036      pxor mm4, mm4
1037      pcmpgtw mm1, mm0  ; sign(c)
1038      pcmpgtw mm4, mm3  ; sign(c')
1039      pxor mm2, mm2
1040      pxor mm5, mm5
1041      pcmpeqw mm2, mm0  ; c is zero
1042      pcmpeqw mm5, mm3  ; c' is zero
1043      pandn mm2, mm6    ; offset = isZero ? 0 : quant_add
1044      pandn mm5, mm6
1045      pxor mm0, mm1     ; negate if negative
1046      pxor mm3, mm4     ; negate if negative
1047      psubw mm0, mm1
1048      psubw mm3, mm4
1049      pmullw mm0, mm7 ; *= 2Q
1050      pmullw mm3, mm7 ; *= 2Q
1051      paddw mm0, mm2 ; + offset
1052      paddw mm3, mm5 ; + offset
1053      paddw mm0, mm1 ; start restoring sign
1054      paddw mm3, mm4 ; start restoring sign
1055    
1056          ; saturates to +2047
1057      movq mm2, [mmx_2047]
1058      pminsw mm0, mm2
1059                  add eax, 2                  add eax, 2
1060                  cmp eax, 16    pminsw mm3, mm2
                 jnz     near .loop  
1061    
1062                  pop     edi    pxor mm0, mm1 ; finish restoring sign
1063                  pop     esi    pxor mm3, mm4 ; finish restoring sign
1064      movq [edx + 8*eax + 8*16   - 2*8], mm0
1065      movq [edx + 8*eax + 8*16+8 - 2*8], mm3
1066      jnz   near .loop
1067    
1068                  ret                  ret
1069    
   
1070  ;===========================================================================  ;===========================================================================
1071  ;  ;
1072  ; void dequant_inter_sse2(int16_t * data,  ; void dequant_inter_sse2(int16_t * data,
# Line 993  Line 1074 
1074  ;                                       const uint32_t quant);  ;                                       const uint32_t quant);
1075  ;  ;
1076  ;===========================================================================  ;===========================================================================
1077    align ALIGN
 align 16  
1078  cglobal dequant_inter_sse2  cglobal dequant_inter_sse2
1079  dequant_inter_sse2  dequant_inter_sse2
1080            mov edx, [esp + 4]      ; data
1081                  push    esi          mov ecx, [esp + 8]      ; coeff
1082                  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  
1083                  movq    mm6, [mmx_add + eax * 8 - 8]                  movq    mm6, [mmx_add + eax * 8 - 8]
1084                  movq    mm7, [mmx_mul + eax * 8 - 8]                  movq    mm7, [mmx_mul + eax * 8 - 8]
   
1085                  movq2dq xmm6, mm6                  movq2dq xmm6, mm6
1086                  movq2dq xmm7, mm7                  movq2dq xmm7, mm7
1087                  movlhps xmm6, xmm6                  movlhps xmm6, xmm6
1088                  movlhps xmm7, xmm7                  movlhps xmm7, xmm7
1089            mov eax, -16
1090    
1091                  xor eax, eax  align ALIGN
1092    .loop
1093            movdqa xmm0, [ecx + 8*16 + 8*eax]  ; c  = coeff[i]
1094            movdqa xmm3, [ecx + 8*16 + 8*eax + 16]
1095    
 align 16  
 .des2_loop  
                 movdqa  xmm0, [esi + eax*8]                     ; xmm0 = [coeff]  
                 movdqa  xmm3, [esi + eax*8 + 16]  
1096                  pxor    xmm1, xmm1                  pxor    xmm1, xmm1
1097                  pxor    xmm4, xmm4                  pxor    xmm4, xmm4
1098                  pcmpgtw xmm1, xmm0          pcmpgtw xmm1, xmm0  ; sign(c)
1099                  pcmpgtw xmm4, xmm3                  pcmpgtw xmm4, xmm3
1100                  pxor    xmm2, xmm2                  pxor    xmm2, xmm2
1101                  pxor    xmm5, xmm5                  pxor    xmm5, xmm5
1102                  pcmpeqw xmm2, xmm0          pcmpeqw xmm2, xmm0  ; c is zero
1103                  pcmpeqw xmm5, xmm3                  pcmpeqw xmm5, xmm3
1104                  pandn   xmm2, xmm6                  pandn   xmm2, xmm6
1105                  pandn   xmm5, xmm6                  pandn   xmm5, xmm6
1106                  pxor    xmm0, xmm1          pxor xmm0, xmm1  ; negate if negative
1107                  pxor    xmm3, xmm4                  pxor    xmm3, xmm4
1108                  psubw   xmm0, xmm1                  psubw   xmm0, xmm1
1109                  psubw   xmm3, xmm4                  psubw   xmm3, xmm4
1110                  pmullw  xmm0, xmm7          pmullw xmm0, xmm7  ; *= 2Q
1111                  pmullw  xmm3, xmm7                  pmullw  xmm3, xmm7
1112                  paddw   xmm0, xmm2          paddw xmm0, xmm2  ; + offset
1113                  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  
1114    
1115                  movdqa  [edi + eax*8], xmm0          paddw xmm0, xmm1  ; start restoring sign
1116                  movdqa  [edi + eax*8 + 16], xmm3          paddw xmm3, xmm4
1117    
1118            ; saturates to +2047
1119            movdqa xmm2, [sse2_2047]
1120            pminsw xmm0, xmm2
1121                  add eax, 4                  add eax, 4
1122                  cmp eax, 16          pminsw xmm3, xmm2
                 jnz     near .des2_loop  
1123    
1124                  pop     edi          pxor xmm0, xmm1 ; finish restoring sign
1125                  pop     esi          pxor xmm3, xmm4
1126            movdqa [edx + 8*16 - 8*4 + 8*eax], xmm0
1127            movdqa [edx + 8*16 - 8*4 + 8*eax + 16], xmm3
1128            jnz     near .loop
1129    
1130                  ret                  ret

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

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