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

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

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

revision 126, Wed Apr 17 10:54:19 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  ; * 26.12.2001  minor bug fixes, dequant saturate, further optimization  ; * $Id: quantize_mmx.asm,v 1.7 2002-11-17 00:41:20 edgomez Exp $
 ; * 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 258  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 377  Line 397 
397    
398  ;===========================================================================  ;===========================================================================
399  ;  ;
400    ; void quant_intra_sse2(int16_t * coeff,
401    ;                                       const int16_t const * data,
402    ;                                       const uint32_t quant,
403    ;                                       const uint32_t dcscalar);
404    ;
405    ;===========================================================================
406    
407    align ALIGN
408    cglobal quant_intra_sse2
409    quant_intra_sse2
410    
411                    push    esi
412                    push    edi
413    
414                    mov             edi, [esp + 8 + 4]                      ; coeff
415                    mov             esi, [esp + 8 + 8]                      ; data
416                    mov             eax, [esp + 8 + 12]                     ; quant
417    
418                    xor             ecx, ecx
419                    cmp             al, 1
420                    jz              near .qas2_q1loop
421    
422    .qas2_not1
423                    movq    mm7, [mmx_div + eax*8 - 8]
424                    movq2dq xmm7, mm7
425                    movlhps xmm7, xmm7
426    
427    align 16
428    .qas2_loop
429                    movdqa  xmm0, [esi + ecx*8]                     ; xmm0 = [1st]
430                    movdqa  xmm3, [esi + ecx*8 + 16]        ; xmm3 = [2nd]
431                    pxor    xmm1, xmm1
432                    pxor    xmm4, xmm4
433                    pcmpgtw xmm1, xmm0
434                    pcmpgtw xmm4, xmm3
435                    pxor    xmm0, xmm1
436                    pxor    xmm3, xmm4
437                    psubw   xmm0, xmm1
438                    psubw   xmm3, xmm4
439                    pmulhw  xmm0, xmm7
440                    pmulhw  xmm3, xmm7
441                    pxor    xmm0, xmm1
442                    pxor    xmm3, xmm4
443                    psubw   xmm0, xmm1
444                    psubw   xmm3, xmm4
445                    movdqa  [edi + ecx*8], xmm0
446                    movdqa  [edi + ecx*8 + 16], xmm3
447    
448                    add             ecx, 4
449                    cmp             ecx, 16
450                    jnz     .qas2_loop
451    
452    .qas2_done
453                    mov     ecx, [esp + 8 + 16]     ; dcscalar
454                    mov     edx, ecx
455                    movsx   eax, word [esi]
456                    shr     edx, 1
457                    cmp             eax, 0
458                    jg              .qas2_gtzero
459    
460                    sub             eax, edx
461                    jmp             short .qas2_mul
462    .qas2_gtzero
463                    add             eax, edx
464    .qas2_mul
465                    cdq
466                    idiv    ecx
467    
468                    mov             [edi], ax
469    
470                    pop             edi
471                    pop             esi
472    
473                    ret
474    
475    align 16
476    .qas2_q1loop
477                    movdqa  xmm0, [esi + ecx*8]                     ; xmm0 = [1st]
478                    movdqa  xmm3, [esi + ecx*8 + 16]        ; xmm3 = [2nd]
479                    pxor    xmm1, xmm1
480                    pxor    xmm4, xmm4
481                    pcmpgtw xmm1, xmm0
482                    pcmpgtw xmm4, xmm3
483                    pxor    xmm0, xmm1
484                    pxor    xmm3, xmm4
485                    psubw   xmm0, xmm1
486                    psubw   xmm3, xmm4
487                    psrlw   xmm0, 1
488                    psrlw   xmm3, 1
489                    pxor    xmm0, xmm1
490                    pxor    xmm3, xmm4
491                    psubw   xmm0, xmm1
492                    psubw   xmm3, xmm4
493                    movdqa  [edi + ecx*8], xmm0
494                    movdqa  [edi + ecx*8 + 16], xmm3
495    
496                    add             ecx, 4
497                    cmp             ecx, 16
498                    jnz             .qas2_q1loop
499                    jmp             near .qas2_done
500    
501    
502    
503    ;===========================================================================
504    ;
505  ; uint32_t quant_inter_mmx(int16_t * coeff,  ; uint32_t quant_inter_mmx(int16_t * coeff,
506  ;                                       const int16_t const * data,  ;                                       const int16_t const * data,
507  ;                                       const uint32_t quant);  ;                                       const uint32_t quant);
# Line 508  Line 633 
633                  movlhps xmm6, xmm6                                      ; duplicate into high 8 bytes                  movlhps xmm6, xmm6                                      ; duplicate into high 8 bytes
634    
635                  cmp             al, 1                  cmp             al, 1
636                  jnz             .not1                  jz              near .qes2_q1loop
                 jmp             .q1loop  
637    
638  .not1  .qes2_not1
639                  movq    mm0, [mmx_div + eax*8 - 8]      ; divider                  movq    mm0, [mmx_div + eax*8 - 8]      ; divider
640                  movq2dq xmm7, mm0                  movq2dq xmm7, mm0
641                  movlhps xmm7, xmm7                  movlhps xmm7, xmm7
642    
643  align 16  align 16
644  .loop  .qes2_loop
645                  movdqa  xmm0, [esi + ecx*8]                     ; xmm0 = [1st]                  movdqa  xmm0, [esi + ecx*8]                     ; xmm0 = [1st]
646                  movdqa  xmm3, [esi + ecx*8 + 16]        ; xmm3 = [2nd]                  movdqa  xmm3, [esi + ecx*8 + 16]        ; xmm3 = [2nd]
647                  pxor    xmm1, xmm1                                      ; xmm1 = 0                  pxor    xmm1, xmm1
648                  pxor    xmm4, xmm4                  pxor    xmm4, xmm4
649                  pcmpgtw xmm1, xmm0                                      ; xmm1 = (0 > xmm0)                  pcmpgtw xmm1, xmm0
650                  pcmpgtw xmm4, xmm3                  pcmpgtw xmm4, xmm3
651                  pxor    xmm0, xmm1                                      ; xmm0 = |xmm0|                  pxor    xmm0, xmm1
652                  pxor    xmm3, xmm4                  pxor    xmm3, xmm4
653                  psubw   xmm0, xmm1                                      ; displace                  psubw   xmm0, xmm1
654                  psubw   xmm3, xmm4                  psubw   xmm3, xmm4
655                  psubusw xmm0, xmm6                                      ; xmm0 -= sub (unsigned, dont go < 0)                  psubusw xmm0, xmm6
656                  psubusw xmm3, xmm6                  psubusw xmm3, xmm6
657                  pmulhw  xmm0, xmm7                                      ; xmm0 = (xmm0 / 2Q) >> 16                  pmulhw  xmm0, xmm7
658                  pmulhw  xmm3, xmm7                  pmulhw  xmm3, xmm7
659                  paddw   xmm5, xmm0                                      ; sum += xmm0                  paddw   xmm5, xmm0
660                  pxor    xmm0, xmm1                                      ; xmm0 *= sign(xmm0)                  pxor    xmm0, xmm1
661                  paddw   xmm5, xmm3                  paddw   xmm5, xmm3
662                  pxor    xmm3, xmm4                  pxor    xmm3, xmm4
663                  psubw   xmm0, xmm1                                      ; undisplace                  psubw   xmm0, xmm1
664                  psubw   xmm3, xmm4                  psubw   xmm3, xmm4
665                  movdqa  [edi + ecx*8], xmm0                  movdqa  [edi + ecx*8], xmm0
666                  movdqa  [edi + ecx*8 + 16], xmm3                  movdqa  [edi + ecx*8 + 16], xmm3
667    
668                  add             ecx, 4                  add             ecx, 4
669                  cmp             ecx, 16                  cmp             ecx, 16
670                  jnz             .loop                  jnz             .qes2_loop
671    
672  .done  .qes2_done
673                  pmaddwd xmm5, [plus_one]                  movdqu  xmm6, [plus_one]
674                    pmaddwd xmm5, xmm6
675                  movhlps xmm6, xmm5                  movhlps xmm6, xmm5
676                  paddd   xmm5, xmm6                  paddd   xmm5, xmm6
677                  movdq2q mm0, xmm5                  movdq2q mm0, xmm5
# Line 562  Line 687 
687                  ret                  ret
688    
689  align 16  align 16
690  .q1loop  .qes2_q1loop
691                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]                  movdqa  xmm0, [esi + ecx*8]                     ; xmm0 = [1st]
692                  movq    mm3, [esi + 8*ecx+ 8]           ;                  movdqa  xmm3, [esi + ecx*8 + 16]        ; xmm3 = [2nd]
693                  pxor    mm1, mm1                ; mm1 = 0                  pxor    xmm1, xmm1
694                  pxor    mm4, mm4                ;                  pxor    xmm4, xmm4
695                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw xmm1, xmm0
696                  pcmpgtw mm4, mm3                ;                  pcmpgtw xmm4, xmm3
697                  pxor    mm0, mm1                ; mm0 = |mm0|                  pxor    xmm0, xmm1
698                  pxor    mm3, mm4                ;                  pxor    xmm3, xmm4
699                  psubw   mm0, mm1                ; displace                  psubw   xmm0, xmm1
700                  psubw   mm3, mm4                ;                  psubw   xmm3, xmm4
701                  psubusw mm0, mm6                ; mm0 -= sub (unsigned, dont go < 0)                  psubusw xmm0, xmm6
702                  psubusw mm3, mm6                ;                  psubusw xmm3, xmm6
703                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)                  psrlw   xmm0, 1
704                  psrlw   mm3, 1                  ;                  psrlw   xmm3, 1
705                  paddw   mm5, mm0                ; sum += mm0                  paddw   xmm5, xmm0
706                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    xmm0, xmm1
707                  paddw   mm5, mm3                ;                  paddw   xmm5, xmm3
708                  pxor    mm3, mm4                ;                  pxor    xmm3, xmm4
709                  psubw   mm0, mm1                ; undisplace                  psubw   xmm0, xmm1
710                  psubw   mm3, mm4                  psubw   xmm3, xmm4
711                  movq    [edi + 8*ecx], mm0                  movdqa  [edi + ecx*8], xmm0
712                  movq    [edi + 8*ecx + 8], mm3                  movdqa  [edi + ecx*8 + 16], xmm3
713    
714                  add ecx,2                  add             ecx,4
715                  cmp ecx,16                  cmp ecx,16
716                  jnz     .q1loop                  jnz             .qes2_q1loop
717                    jmp             .qes2_done
                 jmp     .done  
   
718    
719    
720  ;===========================================================================  ;===========================================================================
# Line 603  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  
735    
736                  mov     edi, [esp + 8 + 4]              ; data    mov    edx, [esp+ 4]        ; data
737                  mov     esi, [esp + 8 + 8]              ; coeff    mov    ecx, [esp+ 8]        ; coeff
738                  mov     eax, [esp + 8 + 12]             ; quant    mov    eax, [esp+12]        ; quant
739      movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1
740                  movq    mm6, [mmx_add + eax * 8 - 8]    movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant
741                  movq    mm7, [mmx_mul + eax * 8 - 8]    mov eax, -16
                 xor eax, eax  
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      movq [edx + 8*eax + 8*16+8 - 2*8], mm3
780      jnz   near .loop
781    
782        ; deal with DC
783    
784      movd mm0, [ecx]
785      pmullw mm0, [esp+16]    ; dcscalar
786      movq mm2, [mmx_32767_minus_2047]
787      paddsw mm0, mm2
788      psubsw mm0, mm2
789      movq mm3, [mmx_32768_minus_2048]
790      psubsw mm0, mm3
791      paddsw mm0, mm3
792      movd eax, mm0
793      mov [edx], ax
794    
795      ret
796    
797    ;===========================================================================
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
810    cglobal dequant_intra_xmm
811    dequant_intra_xmm:
812    
813      mov    edx, [esp+ 4]        ; data
814      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
821    .loop
822      movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]
823      movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]
824      pxor mm1, mm1
825      pxor mm4, mm4
826      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                  add eax, 2
849                  cmp eax, 16    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                  jnz     near .loop
856    
857                  mov     ax, [esi]                                       ; ax = data[0]      ; deal with DC
                 imul ax, [esp + 8 + 16]                 ; eax = data[0] * dcscalar  
858    
859  %ifdef SATURATE    movd mm0, [ecx]
860                  cmp ax, -2048    pmullw mm0, [esp+16]    ; dcscalar
861                  jl .set_n2048    movq mm2, [mmx_32767_minus_2047]
862                  cmp ax, 2047    paddsw mm0, mm2
863                  jg .set_2047    psubsw mm0, mm2
864  %endif    movq mm2, [mmx_32768_minus_2048]
865                  mov     [edi], ax    psubsw mm0, mm2
866      paddsw mm0, mm2
867      movd eax, mm0
868      mov [edx], ax
869    
                 pop     edi  
                 pop     esi  
870                  ret                  ret
871    
872  %ifdef SATURATE  
873    ;===========================================================================
874    ;
875    ; void dequant_intra_sse2(int16_t *data,
876    ;                                       const int16_t const *coeff,
877    ;                                       const uint32_t quant,
878    ;                                       const uint32_t dcscalar);
879    ;
880    ;===========================================================================
881  align ALIGN  align ALIGN
882  .set_n2048  cglobal dequant_intra_sse2
883                  mov     word [edi], -2048  dequant_intra_sse2:
884                  pop     edi          mov edx, [esp+ 4]        ; data
885                  pop     esi          mov ecx, [esp+ 8]        ; coeff
886                  ret          mov eax, [esp+12]        ; quant
887            movq mm6, [mmx_add + eax * 8 - 8]
888            movq mm7, [mmx_mul + eax * 8 - 8]
889            movq2dq xmm6, mm6
890            movq2dq xmm7, mm7
891            movlhps xmm6, xmm6
892            movlhps xmm7, xmm7
893            mov eax, -16
894    
895  align ALIGN  align ALIGN
896  .set_2047  .loop
897                  mov     word [edi], 2047          movdqa xmm0, [ecx + 8*16 + 8*eax]      ; c  = coeff[i]
898                  pop     edi          movdqa xmm3, [ecx + 8*16 + 8*eax+ 16]
899                  pop     esi          pxor xmm1, xmm1
900            pxor xmm4, xmm4
901            pcmpgtw xmm1, xmm0  ; sign(c)
902            pcmpgtw xmm4, xmm3
903            pxor xmm2, xmm2
904            pxor xmm5, xmm5
905            pcmpeqw xmm2, xmm0  ; c is zero
906            pcmpeqw xmm5, xmm3
907            pandn xmm2, xmm6    ; offset = isZero ? 0 : quant_add
908            pandn xmm5, xmm6
909            pxor xmm0, xmm1     ; negate if negative
910            pxor xmm3, xmm4
911            psubw xmm0, xmm1
912            psubw xmm3, xmm4
913            pmullw xmm0, xmm7 ; *= 2Q
914            pmullw xmm3, xmm7
915            paddw xmm0, xmm2 ; + offset
916            paddw xmm3, xmm5
917            paddw xmm0, xmm1 ; negate back
918            paddw xmm3, xmm4
919    
920            ; saturates to +2047
921            movdqa xmm2, [sse2_2047]
922            pminsw xmm0, xmm2
923            add eax, 4
924            pminsw xmm3, xmm2
925    
926            pxor xmm0, xmm1
927            pxor xmm3, xmm4
928            movdqa [edx + 8*16 - 8*4 + 8*eax], xmm0
929            movdqa [edx + 8*16 - 8*4 + 8*eax + 16], xmm3
930            jnz     near .loop
931    
932            ; deal with DC
933            movd mm0, [ecx]
934            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    
944                  ret                  ret
945  %endif  
946    
947    
948    
949  ;===========================================================================  ;===========================================================================
950  ;  ;
# Line 706  Line 956 
956    
957  align ALIGN  align ALIGN
958  cglobal dequant_inter_mmx  cglobal dequant_inter_mmx
959  dequant_inter_mmx  dequant_inter_mmx:
960    
961                  push    esi    mov    edx, [esp+ 4]        ; data
962                  push    edi    mov    ecx, [esp+ 8]        ; coeff
963      mov    eax, [esp+12]        ; quant
964                  mov     edi, [esp + 8 + 4]      ; data    movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1
965                  mov     esi, [esp + 8 + 8]      ; coeff    movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant
966                  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  
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 779  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
   
 align 16  
1092  .loop  .loop
1093                  movdqa  xmm0, [esi + eax*8]                     ; xmm0 = [coeff]          movdqa xmm0, [ecx + 8*16 + 8*eax]  ; c  = coeff[i]
1094                  movdqa  xmm3, [esi + eax*8 + 16]          movdqa xmm3, [ecx + 8*16 + 8*eax + 16]
1095    
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  
1114    
1115  %ifdef SATURATE          paddw xmm0, xmm1  ; start restoring sign
1116                  movdqa  xmm2, [sse2_pos_2047]          paddw xmm3, xmm4
1117                  movdqa  xmm4, [sse2_neg_2048]  
1118            ; saturates to +2047
1119            movdqa xmm2, [sse2_2047]
1120                  pminsw  xmm0, xmm2                  pminsw  xmm0, xmm2
1121            add eax, 4
1122                  pminsw  xmm3, xmm2                  pminsw  xmm3, xmm2
                 pmaxsw  xmm0, xmm4  
                 pmaxsw  xmm3, xmm4  
 %endif  
   
                 movdqa  [edi + eax*8], xmm0  
                 movdqa  [edi + eax*8 + 16], xmm3  
1123    
1124                  add eax, 4          pxor xmm0, xmm1 ; finish restoring sign
1125                  cmp eax, 16          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                  jnz     near .loop
1129    
                 pop     edi  
                 pop     esi  
   
1130                  ret                  ret

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

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