[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 3, Fri Mar 8 02:46:11 2002 UTC revision 269, Sun Jul 7 13:21:34 2002 UTC
# Line 32  Line 32 
32  ; *  ; *
33  ; *     History:  ; *     History:
34  ; *  ; *
35    ; * 14.06.2002  mmx+xmm dequant_* funcs revamped  -Skal-
36    ; * 24.02.2002  sse2 quant_intra / dequant_intra (have to use movdqu ???)
37    ; * 17.04.2002  sse2 quant_inter / dequant_inter
38  ; * 26.12.2001  minor bug fixes, dequant saturate, further optimization  ; * 26.12.2001  minor bug fixes, dequant saturate, further optimization
39  ; * 19.11.2001  quant_inter_mmx now returns sum of abs. coefficient values  ; * 19.11.2001  quant_inter_mmx now returns sum of abs. coefficient values
40  ; *     04.11.2001      nasm version; (c)2001 peter ross <pross@cs.rmit.edu.au>  ; *     04.11.2001      nasm version; (c)2001 peter ross <pross@cs.rmit.edu.au>
# Line 58  Line 61 
61          %endif          %endif
62  %endmacro  %endmacro
63    
64  plus_one times 4        dw       1  align 16
65    
66    plus_one times 8        dw       1
67    
68  ;===========================================================================  ;===========================================================================
69  ;  ;
# Line 70  Line 75 
75  times 4 dw %1 / 2  times 4 dw %1 / 2
76  %endmacro  %endmacro
77    
78  align ALIGN  align 16
79  mmx_sub  mmx_sub
80                  MMX_SUB 1                  MMX_SUB 1
81                  MMX_SUB 2                  MMX_SUB 2
# Line 120  Line 125 
125  times 4 dw  (1 << 16) / (%1 * 2) + 1  times 4 dw  (1 << 16) / (%1 * 2) + 1
126  %endmacro  %endmacro
127    
128  align ALIGN  align 16
129  mmx_div  mmx_div
130                  MMX_DIV 1                  MMX_DIV 1
131                  MMX_DIV 2                  MMX_DIV 2
# Line 170  Line 175 
175  %endif  %endif
176  %endmacro  %endmacro
177    
178  align ALIGN  align 16
179  mmx_add  mmx_add
180                  MMX_ADD 1                  MMX_ADD 1
181                  MMX_ADD 2                  MMX_ADD 2
# Line 215  Line 220 
220  times 4 dw %1 * 2  times 4 dw %1 * 2
221  %endmacro  %endmacro
222    
223  align ALIGN  align 16
224  mmx_mul  mmx_mul
225                  MMX_MUL 1                  MMX_MUL 1
226                  MMX_MUL 2                  MMX_MUL 2
# Line 256  Line 261 
261  ;  ;
262  ;===========================================================================  ;===========================================================================
263    
264  align ALIGN  align 8
265  mmx_32768_minus_2048                            times 4 dw (32768-2048)  mmx_32768_minus_2048                            times 4 dw (32768-2048)
266  mmx_32767_minus_2047                            times 4 dw (32767-2047)  mmx_32767_minus_2047                            times 4 dw (32767-2047)
267    
268    align 16
269    mmx_2047 times 4 dw 2047
270    
271    align 16
272    sse2_pos_2047                                           times 8 dw 2047
273    sse2_neg_2048                                           times 8 dw -2048
274    
275    
276  section .text  section .text
277    
# Line 371  Line 383 
383    
384  ;===========================================================================  ;===========================================================================
385  ;  ;
386    ; void quant_intra_sse2(int16_t * coeff,
387    ;                                       const int16_t const * data,
388    ;                                       const uint32_t quant,
389    ;                                       const uint32_t dcscalar);
390    ;
391    ;===========================================================================
392    
393    align ALIGN
394    cglobal quant_intra_sse2
395    quant_intra_sse2
396    
397                    push    esi
398                    push    edi
399    
400                    mov             edi, [esp + 8 + 4]                      ; coeff
401                    mov             esi, [esp + 8 + 8]                      ; data
402                    mov             eax, [esp + 8 + 12]                     ; quant
403    
404                    xor             ecx, ecx
405                    cmp             al, 1
406                    jz              near .qas2_q1loop
407    
408    .qas2_not1
409                    movq    mm7, [mmx_div + eax*8 - 8]
410                    movq2dq xmm7, mm7
411                    movlhps xmm7, xmm7
412    
413    align 16
414    .qas2_loop
415                    movdqa  xmm0, [esi + ecx*8]                     ; xmm0 = [1st]
416                    movdqa  xmm3, [esi + ecx*8 + 16]        ; xmm3 = [2nd]
417                    pxor    xmm1, xmm1
418                    pxor    xmm4, xmm4
419                    pcmpgtw xmm1, xmm0
420                    pcmpgtw xmm4, xmm3
421                    pxor    xmm0, xmm1
422                    pxor    xmm3, xmm4
423                    psubw   xmm0, xmm1
424                    psubw   xmm3, xmm4
425                    pmulhw  xmm0, xmm7
426                    pmulhw  xmm3, xmm7
427                    pxor    xmm0, xmm1
428                    pxor    xmm3, xmm4
429                    psubw   xmm0, xmm1
430                    psubw   xmm3, xmm4
431                    movdqa  [edi + ecx*8], xmm0
432                    movdqa  [edi + ecx*8 + 16], xmm3
433    
434                    add             ecx, 4
435                    cmp             ecx, 16
436                    jnz     .qas2_loop
437    
438    .qas2_done
439                    mov     ecx, [esp + 8 + 16]     ; dcscalar
440                    mov     edx, ecx
441                    movsx   eax, word [esi]
442                    shr     edx, 1
443                    cmp             eax, 0
444                    jg              .qas2_gtzero
445    
446                    sub             eax, edx
447                    jmp             short .qas2_mul
448    .qas2_gtzero
449                    add             eax, edx
450    .qas2_mul
451                    cdq
452                    idiv    ecx
453    
454                    mov             [edi], ax
455    
456                    pop             edi
457                    pop             esi
458    
459                    ret
460    
461    align 16
462    .qas2_q1loop
463                    movdqa  xmm0, [esi + ecx*8]                     ; xmm0 = [1st]
464                    movdqa  xmm3, [esi + ecx*8 + 16]        ; xmm3 = [2nd]
465                    pxor    xmm1, xmm1
466                    pxor    xmm4, xmm4
467                    pcmpgtw xmm1, xmm0
468                    pcmpgtw xmm4, xmm3
469                    pxor    xmm0, xmm1
470                    pxor    xmm3, xmm4
471                    psubw   xmm0, xmm1
472                    psubw   xmm3, xmm4
473                    psrlw   xmm0, 1
474                    psrlw   xmm3, 1
475                    pxor    xmm0, xmm1
476                    pxor    xmm3, xmm4
477                    psubw   xmm0, xmm1
478                    psubw   xmm3, xmm4
479                    movdqa  [edi + ecx*8], xmm0
480                    movdqa  [edi + ecx*8 + 16], xmm3
481    
482                    add             ecx, 4
483                    cmp             ecx, 16
484                    jnz             .qas2_q1loop
485                    jmp             near .qas2_done
486    
487    
488    
489    ;===========================================================================
490    ;
491  ; uint32_t quant_inter_mmx(int16_t * coeff,  ; uint32_t quant_inter_mmx(int16_t * coeff,
492  ;                                       const int16_t const * data,  ;                                       const int16_t const * data,
493  ;                                       const uint32_t quant);  ;                                       const uint32_t quant);
# Line 476  Line 593 
593    
594  ;===========================================================================  ;===========================================================================
595  ;  ;
596    ; uint32_t quant_inter_sse2(int16_t * coeff,
597    ;                                       const int16_t const * data,
598    ;                                       const uint32_t quant);
599    ;
600    ;===========================================================================
601    
602    align 16
603    cglobal quant_inter_sse2
604                    quant_inter_sse2
605    
606                    push    esi
607                    push    edi
608    
609                    mov             edi, [esp + 8 + 4]                      ; coeff
610                    mov             esi, [esp + 8 + 8]                      ; data
611                    mov             eax, [esp + 8 + 12]                     ; quant
612    
613                    xor             ecx, ecx
614    
615                    pxor    xmm5, xmm5                                      ; sum
616    
617                    movq    mm0, [mmx_sub + eax*8 - 8]      ; sub
618                    movq2dq xmm6, mm0                                       ; load into low 8 bytes
619                    movlhps xmm6, xmm6                                      ; duplicate into high 8 bytes
620    
621                    cmp             al, 1
622                    jz              near .qes2_q1loop
623    
624    .qes2_not1
625                    movq    mm0, [mmx_div + eax*8 - 8]      ; divider
626                    movq2dq xmm7, mm0
627                    movlhps xmm7, xmm7
628    
629    align 16
630    .qes2_loop
631                    movdqa  xmm0, [esi + ecx*8]                     ; xmm0 = [1st]
632                    movdqa  xmm3, [esi + ecx*8 + 16]        ; xmm3 = [2nd]
633                    pxor    xmm1, xmm1
634                    pxor    xmm4, xmm4
635                    pcmpgtw xmm1, xmm0
636                    pcmpgtw xmm4, xmm3
637                    pxor    xmm0, xmm1
638                    pxor    xmm3, xmm4
639                    psubw   xmm0, xmm1
640                    psubw   xmm3, xmm4
641                    psubusw xmm0, xmm6
642                    psubusw xmm3, xmm6
643                    pmulhw  xmm0, xmm7
644                    pmulhw  xmm3, xmm7
645                    paddw   xmm5, xmm0
646                    pxor    xmm0, xmm1
647                    paddw   xmm5, xmm3
648                    pxor    xmm3, xmm4
649                    psubw   xmm0, xmm1
650                    psubw   xmm3, xmm4
651                    movdqa  [edi + ecx*8], xmm0
652                    movdqa  [edi + ecx*8 + 16], xmm3
653    
654                    add             ecx, 4
655                    cmp             ecx, 16
656                    jnz             .qes2_loop
657    
658    .qes2_done
659                    movdqu  xmm6, [plus_one]
660                    pmaddwd xmm5, xmm6
661                    movhlps xmm6, xmm5
662                    paddd   xmm5, xmm6
663                    movdq2q mm0, xmm5
664    
665                    movq    mm5, mm0
666                    psrlq   mm5, 32
667                    paddd   mm0, mm5
668                    movd    eax, mm0                                        ; return sum
669    
670                    pop             edi
671                    pop             esi
672    
673                    ret
674    
675    align 16
676    .qes2_q1loop
677                    movdqa  xmm0, [esi + ecx*8]                     ; xmm0 = [1st]
678                    movdqa  xmm3, [esi + ecx*8 + 16]        ; xmm3 = [2nd]
679                    pxor    xmm1, xmm1
680                    pxor    xmm4, xmm4
681                    pcmpgtw xmm1, xmm0
682                    pcmpgtw xmm4, xmm3
683                    pxor    xmm0, xmm1
684                    pxor    xmm3, xmm4
685                    psubw   xmm0, xmm1
686                    psubw   xmm3, xmm4
687                    psubusw xmm0, xmm6
688                    psubusw xmm3, xmm6
689                    psrlw   xmm0, 1
690                    psrlw   xmm3, 1
691                    paddw   xmm5, xmm0
692                    pxor    xmm0, xmm1
693                    paddw   xmm5, xmm3
694                    pxor    xmm3, xmm4
695                    psubw   xmm0, xmm1
696                    psubw   xmm3, xmm4
697                    movdqa  [edi + ecx*8], xmm0
698                    movdqa  [edi + ecx*8 + 16], xmm3
699    
700                    add             ecx,4
701                    cmp             ecx,16
702                    jnz             .qes2_q1loop
703                    jmp             .qes2_done
704    
705    
706    ;===========================================================================
707    ;
708  ; void dequant_intra_mmx(int16_t *data,  ; void dequant_intra_mmx(int16_t *data,
709  ;                                       const int16_t const *coeff,  ;                                       const int16_t const *coeff,
710  ;                                       const uint32_t quant,  ;                                       const uint32_t quant,
# Line 483  Line 712 
712  ;  ;
713  ;===========================================================================  ;===========================================================================
714    
715      ; note: we only saturate to +2047 *before* restoring the sign.
716      ; Hence, final clamp really is [-2048,2047]
717    
718  align ALIGN  align ALIGN
719  cglobal dequant_intra_mmx  cglobal dequant_intra_mmx
720  dequant_intra_mmx  dequant_intra_mmx:
721    
722      mov    edx, [esp+ 4]        ; data
723      mov    ecx, [esp+ 8]        ; coeff
724      mov    eax, [esp+12]        ; quant
725      movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1
726      movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant
727      mov eax, -16
728    
729    align ALIGN
730    .loop
731      movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]
732      movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]
733      pxor mm1, mm1
734      pxor mm4, mm4
735      pcmpgtw mm1, mm0  ; sign(c)
736      pcmpgtw mm4, mm3  ; sign(c')
737      pxor mm2, mm2
738      pxor mm5, mm5
739      pcmpeqw mm2, mm0  ; c is zero
740      pcmpeqw mm5, mm3  ; c' is zero
741      pandn mm2, mm6    ; offset = isZero ? 0 : quant_add
742      pandn mm5, mm6
743      pxor mm0, mm1     ; negate if negative
744      pxor mm3, mm4     ; negate if negative
745      psubw mm0, mm1
746      psubw mm3, mm4
747      pmullw mm0, mm7 ; *= 2Q
748      pmullw mm3, mm7 ; *= 2Q
749      paddw mm0, mm2 ; + offset
750      paddw mm3, mm5 ; + offset
751      paddw mm0, mm1 ; negate back
752      paddw mm3, mm4 ; negate back
753    
754        ; saturates to +2047
755      movq mm2, [mmx_32767_minus_2047]
756      add eax, 2
757      paddsw mm0, mm2
758      paddsw mm3, mm2
759      psubsw mm0, mm2
760      psubsw mm3, mm2
761    
762      pxor mm0, mm1
763      pxor mm3, mm4
764      movq [edx + 8*eax + 8*16   - 2*8], mm0
765      movq [edx + 8*eax + 8*16+8 - 2*8], mm3
766      jnz   near .loop
767    
768        ; deal with DC
769    
770      movd mm0, [ecx]
771      pmullw mm0, [esp+16]    ; dcscalar
772      movq mm2, [mmx_32767_minus_2047]
773      paddsw mm0, mm2
774      psubsw mm0, mm2
775      movq mm3, [mmx_32768_minus_2048]
776      psubsw mm0, mm3
777      paddsw mm0, mm3
778      movd eax, mm0
779      mov [edx], ax
780    
781      ret
782    
783    ;===========================================================================
784    ;
785    ; void dequant_intra_xmm(int16_t *data,
786    ;                                       const int16_t const *coeff,
787    ;                                       const uint32_t quant,
788    ;                                       const uint32_t dcscalar);
789    ;
790    ;===========================================================================
791    
792      ; this is the same as dequant_inter_mmx, except that we're
793      ; saturating using 'pminsw' (saves 2 cycles/loop => ~5% faster)
794    
795    align ALIGN
796    cglobal dequant_intra_xmm
797    dequant_intra_xmm:
798    
799      mov    edx, [esp+ 4]        ; data
800      mov    ecx, [esp+ 8]        ; coeff
801      mov    eax, [esp+12]        ; quant
802      movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1
803      movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant
804      mov eax, -16
805    
806    align ALIGN
807    .loop
808      movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]
809      movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]
810      pxor mm1, mm1
811      pxor mm4, mm4
812      pcmpgtw mm1, mm0  ; sign(c)
813      pcmpgtw mm4, mm3  ; sign(c')
814      pxor mm2, mm2
815      pxor mm5, mm5
816      pcmpeqw mm2, mm0  ; c is zero
817      pcmpeqw mm5, mm3  ; c' is zero
818      pandn mm2, mm6    ; offset = isZero ? 0 : quant_add
819      pandn mm5, mm6
820      pxor mm0, mm1     ; negate if negative
821      pxor mm3, mm4     ; negate if negative
822      psubw mm0, mm1
823      psubw mm3, mm4
824      pmullw mm0, mm7 ; *= 2Q
825      pmullw mm3, mm7 ; *= 2Q
826      paddw mm0, mm2 ; + offset
827      paddw mm3, mm5 ; + offset
828      paddw mm0, mm1 ; negate back
829      paddw mm3, mm4 ; negate back
830    
831        ; saturates to +2047
832      movq mm2, [mmx_2047]
833      pminsw mm0, mm2
834      add eax, 2
835      pminsw mm3, mm2
836    
837      pxor mm0, mm1
838      pxor mm3, mm4
839      movq [edx + 8*eax + 8*16   - 2*8], mm0
840      movq [edx + 8*eax + 8*16+8 - 2*8], mm3
841      jnz   near .loop
842    
843        ; deal with DC
844    
845      movd mm0, [ecx]
846      pmullw mm0, [esp+16]    ; dcscalar
847      movq mm2, [mmx_32767_minus_2047]
848      paddsw mm0, mm2
849      psubsw mm0, mm2
850      movq mm2, [mmx_32768_minus_2048]
851      psubsw mm0, mm2
852      paddsw mm0, mm2
853      movd eax, mm0
854      mov [edx], ax
855    
856      ret
857    
858    ;===========================================================================
859    ;
860    ; void dequant_intra_sse2(int16_t *data,
861    ;                                       const int16_t const *coeff,
862    ;                                       const uint32_t quant,
863    ;                                       const uint32_t dcscalar);
864    ;
865    ;===========================================================================
866    
867    align 16
868    cglobal dequant_intra_sse2
869    dequant_intra_sse2:
870    
871                  push    esi                  push    esi
872                  push    edi                  push    edi
# Line 496  Line 877 
877    
878                  movq    mm6, [mmx_add + eax * 8 - 8]                  movq    mm6, [mmx_add + eax * 8 - 8]
879                  movq    mm7, [mmx_mul + eax * 8 - 8]                  movq    mm7, [mmx_mul + eax * 8 - 8]
880                    movq2dq xmm6, mm6
881                    movq2dq xmm7, mm7
882                    movlhps xmm6, xmm6
883                    movlhps xmm7, xmm7
884    
885                  xor eax, eax                  xor eax, eax
886    
887  align ALIGN  align 16
888  .loop  .das2_loop
889                  movq    mm0, [esi + 8*eax]              ; mm0 = [coeff]                  movdqa  xmm0, [esi + eax*8]
890                  movq    mm3, [esi + 8*eax + 8]  ;                  movdqa  xmm3, [esi + eax*8 + 16]
891                  pxor    mm1, mm1                ; mm1 = 0                  pxor    xmm1, xmm1
892                  pxor    mm4, mm4                ;                  pxor    xmm4, xmm4
893                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw xmm1, xmm0
894                  pcmpgtw mm4, mm3                ;                  pcmpgtw xmm4, xmm3
895                  pxor    mm2, mm2                ; mm2 = 0                  pxor    xmm2, xmm2
896                  pxor    mm5, mm5                ;                  pxor    xmm5, xmm5
897                  pcmpeqw mm2, mm0                ; mm2 = (0 == mm0)                  pcmpeqw xmm2, xmm0
898                  pcmpeqw mm5, mm3                ;                  pcmpeqw xmm5, xmm3
899                  pandn   mm2, mm6                ; mm2 = (iszero ? 0 : add)                  pandn   xmm2, xmm6
900                  pandn   mm5, mm6                ;                  pandn   xmm5, xmm6
901                  pxor    mm0, mm1                ; mm0 = |mm0|                  pxor    xmm0, xmm1
902                  pxor    mm3, mm4                ;                  pxor    xmm3, xmm4
903                  psubw   mm0, mm1                ; displace                  psubw   xmm0, xmm1
904                  psubw   mm3, mm4                ;                  psubw   xmm3, xmm4
905                  pmullw  mm0, mm7                ; mm0 *= 2Q                  pmullw  xmm0, xmm7
906                  pmullw  mm3, mm7                ;                  pmullw  xmm3, xmm7
907                  paddw   mm0, mm2                ; mm0 += mm2 (add)                  paddw   xmm0, xmm2
908                  paddw   mm3, mm5                ;                  paddw   xmm3, xmm5
909                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    xmm0, xmm1
910                  pxor    mm3, mm4                ;                  pxor    xmm3, xmm4
911                  psubw   mm0, mm1                ; undisplace                  psubw   xmm0, xmm1
912                  psubw   mm3, mm4                  psubw   xmm3, xmm4
913    
914  %ifdef SATURATE  %ifdef SATURATE
915                  movq mm2, [mmx_32767_minus_2047]                  movdqu  xmm2, [sse2_pos_2047]
916                  movq mm4, [mmx_32768_minus_2048]                  movdqu  xmm4, [sse2_neg_2048]
917                  paddsw  mm0, mm2                  pminsw  xmm0, xmm2
918                  paddsw  mm3, mm2                  pminsw  xmm3, xmm2
919                  psubsw  mm0, mm2                  pmaxsw  xmm0, xmm4
920                  psubsw  mm3, mm2                  pmaxsw  xmm3, xmm4
                 psubsw  mm0, mm4  
                 psubsw  mm3, mm4  
                 paddsw  mm0, mm4  
                 paddsw  mm3, mm4  
921  %endif  %endif
922    
923                  movq    [edi + 8*eax], mm0              ; [data] = mm0                  movdqa  [edi + eax*8], xmm0
924                  movq    [edi + 8*eax + 8], mm3                  movdqa  [edi + eax*8 + 16], xmm3
925    
926                  add eax, 2                  add             eax, 4
927                  cmp eax, 16                  cmp eax, 16
928                  jnz     near .loop                  jnz             near .das2_loop
929    
930                  mov     ax, [esi]                                       ; ax = data[0]                  mov     ax, [esi]                                       ; ax = data[0]
931                  imul ax, [esp + 8 + 16]                 ; eax = data[0] * dcscalar                  imul ax, [esp + 8 + 16]                 ; eax = data[0] * dcscalar
932    
933  %ifdef SATURATE  %ifdef SATURATE
934                  cmp ax, -2048                  cmp ax, -2048
935                  jl .set_n2048                  jl              .das2_set_n2048
936                  cmp ax, 2047                  cmp ax, 2047
937                  jg .set_2047                  jg              .das2_set_2047
938  %endif  %endif
939                  mov     [edi], ax                  mov     [edi], ax
940    
# Line 561  Line 943 
943                  ret                  ret
944    
945  %ifdef SATURATE  %ifdef SATURATE
946  align ALIGN  align 16
947  .set_n2048  .das2_set_n2048
948                  mov     word [edi], -2048                  mov     word [edi], -2048
949                  pop     edi                  pop     edi
950                  pop     esi                  pop     esi
951                  ret                  ret
952    
953  align ALIGN  align 16
954  .set_2047  .das2_set_2047
955                  mov     word [edi], 2047                  mov     word [edi], 2047
956                  pop     edi                  pop     edi
957                  pop     esi                  pop     esi
# Line 586  Line 968 
968    
969  align ALIGN  align ALIGN
970  cglobal dequant_inter_mmx  cglobal dequant_inter_mmx
971  dequant_inter_mmx  dequant_inter_mmx:
972    
973      mov    edx, [esp+ 4]        ; data
974      mov    ecx, [esp+ 8]        ; coeff
975      mov    eax, [esp+12]        ; quant
976      movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1
977      movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant
978      mov eax, -16
979    
980    align ALIGN
981    .loop
982      movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]
983      movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]
984      pxor mm1, mm1
985      pxor mm4, mm4
986      pcmpgtw mm1, mm0  ; sign(c)
987      pcmpgtw mm4, mm3  ; sign(c')
988      pxor mm2, mm2
989      pxor mm5, mm5
990      pcmpeqw mm2, mm0  ; c is zero
991      pcmpeqw mm5, mm3  ; c' is zero
992      pandn mm2, mm6    ; offset = isZero ? 0 : quant_add
993      pandn mm5, mm6
994      pxor mm0, mm1     ; negate if negative
995      pxor mm3, mm4     ; negate if negative
996      psubw mm0, mm1
997      psubw mm3, mm4
998      pmullw mm0, mm7 ; *= 2Q
999      pmullw mm3, mm7 ; *= 2Q
1000      paddw mm0, mm2 ; + offset
1001      paddw mm3, mm5 ; + offset
1002      paddw mm0, mm1 ; negate back
1003      paddw mm3, mm4 ; negate back
1004    
1005        ; saturates to +2047
1006      movq mm2, [mmx_32767_minus_2047]
1007      add eax, 2
1008      paddsw mm0, mm2
1009      paddsw mm3, mm2
1010      psubsw mm0, mm2
1011      psubsw mm3, mm2
1012    
1013      pxor mm0, mm1
1014      pxor mm3, mm4
1015      movq [edx + 8*eax + 8*16   - 2*8], mm0
1016      movq [edx + 8*eax + 8*16+8 - 2*8], mm3
1017      jnz   near .loop
1018    
1019      ret
1020    
1021    ;===========================================================================
1022    ;
1023    ; void dequant_inter_xmm(int16_t * data,
1024    ;                                       const int16_t * const coeff,
1025    ;                                       const uint32_t quant);
1026    ;
1027    ;===========================================================================
1028    
1029      ; this is the same as dequant_inter_mmx,
1030      ; except that we're saturating using 'pminsw' (saves 2 cycles/loop)
1031    
1032    align ALIGN
1033    cglobal dequant_inter_xmm
1034    dequant_inter_xmm:
1035    
1036      mov    edx, [esp+ 4]        ; data
1037      mov    ecx, [esp+ 8]        ; coeff
1038      mov    eax, [esp+12]        ; quant
1039      movq mm6, [mmx_add + eax*8 - 8]  ; quant or quant-1
1040      movq mm7, [mmx_mul + eax*8 - 8]  ; 2*quant
1041      mov eax, -16
1042    
1043    align ALIGN
1044    .loop
1045      movq mm0, [ecx+8*eax+8*16]      ; c  = coeff[i]
1046      movq mm3, [ecx+8*eax+8*16 + 8]  ; c' = coeff[i+1]
1047      pxor mm1, mm1
1048      pxor mm4, mm4
1049      pcmpgtw mm1, mm0  ; sign(c)
1050      pcmpgtw mm4, mm3  ; sign(c')
1051      pxor mm2, mm2
1052      pxor mm5, mm5
1053      pcmpeqw mm2, mm0  ; c is zero
1054      pcmpeqw mm5, mm3  ; c' is zero
1055      pandn mm2, mm6    ; offset = isZero ? 0 : quant_add
1056      pandn mm5, mm6
1057      pxor mm0, mm1     ; negate if negative
1058      pxor mm3, mm4     ; negate if negative
1059      psubw mm0, mm1
1060      psubw mm3, mm4
1061      pmullw mm0, mm7 ; *= 2Q
1062      pmullw mm3, mm7 ; *= 2Q
1063      paddw mm0, mm2 ; + offset
1064      paddw mm3, mm5 ; + offset
1065      paddw mm0, mm1 ; start restoring sign
1066      paddw mm3, mm4 ; start restoring sign
1067    
1068          ; saturates to +2047
1069      movq mm2, [mmx_2047]
1070      pminsw mm0, mm2
1071      add eax, 2
1072      pminsw mm3, mm2
1073    
1074      pxor mm0, mm1 ; finish restoring sign
1075      pxor mm3, mm4 ; finish restoring sign
1076      movq [edx + 8*eax + 8*16   - 2*8], mm0
1077      movq [edx + 8*eax + 8*16+8 - 2*8], mm3
1078      jnz   near .loop
1079    
1080      ret
1081    
1082    ;===========================================================================
1083    ;
1084    ; void dequant_inter_sse2(int16_t * data,
1085    ;                                       const int16_t * const coeff,
1086    ;                                       const uint32_t quant);
1087    ;
1088    ;===========================================================================
1089    
1090    align 16
1091    cglobal dequant_inter_sse2
1092    dequant_inter_sse2
1093    
1094                  push    esi                  push    esi
1095                  push    edi                  push    edi
# Line 597  Line 1100 
1100                  movq    mm6, [mmx_add + eax * 8 - 8]                  movq    mm6, [mmx_add + eax * 8 - 8]
1101                  movq    mm7, [mmx_mul + eax * 8 - 8]                  movq    mm7, [mmx_mul + eax * 8 - 8]
1102    
1103                    movq2dq xmm6, mm6
1104                    movq2dq xmm7, mm7
1105                    movlhps xmm6, xmm6
1106                    movlhps xmm7, xmm7
1107    
1108                  xor eax, eax                  xor eax, eax
1109    
1110  align ALIGN  align 16
1111  .loop  .des2_loop
1112                  movq    mm0, [esi + 8*eax]                      ; mm0 = [coeff]                  movdqa  xmm0, [esi + eax*8]                     ; xmm0 = [coeff]
1113                  movq    mm3, [esi + 8*eax + 8]          ;                  movdqa  xmm3, [esi + eax*8 + 16]
1114                  pxor    mm1, mm1                ; mm1 = 0                  pxor    xmm1, xmm1
1115                  pxor    mm4, mm4                ;                  pxor    xmm4, xmm4
1116                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw xmm1, xmm0
1117                  pcmpgtw mm4, mm3                ;                  pcmpgtw xmm4, xmm3
1118                  pxor    mm2, mm2                ; mm2 = 0                  pxor    xmm2, xmm2
1119                  pxor    mm5, mm5                ;                  pxor    xmm5, xmm5
1120                  pcmpeqw mm2, mm0                ; mm2 = (0 == mm0)                  pcmpeqw xmm2, xmm0
1121                  pcmpeqw mm5, mm3                ;                  pcmpeqw xmm5, xmm3
1122                  pandn   mm2, mm6                ; mm2 = (iszero ? 0 : add)                  pandn   xmm2, xmm6
1123                  pandn   mm5, mm6                ;                  pandn   xmm5, xmm6
1124                  pxor    mm0, mm1                ; mm0 = |mm0|                  pxor    xmm0, xmm1
1125                  pxor    mm3, mm4                ;                  pxor    xmm3, xmm4
1126                  psubw   mm0, mm1                ; displace                  psubw   xmm0, xmm1
1127                  psubw   mm3, mm4                ;                  psubw   xmm3, xmm4
1128                  pmullw  mm0, mm7                ; mm0 *= 2Q                  pmullw  xmm0, xmm7
1129                  pmullw  mm3, mm7                ;                  pmullw  xmm3, xmm7
1130                  paddw   mm0, mm2                ; mm0 += mm2 (add)                  paddw   xmm0, xmm2
1131                  paddw   mm3, mm5                ;                  paddw   xmm3, xmm5
1132                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    xmm0, xmm1
1133                  pxor    mm3, mm4                ;                  pxor    xmm3, xmm4
1134                  psubw   mm0, mm1                ; undisplace                  psubw   xmm0, xmm1
1135                  psubw   mm3, mm4                  psubw   xmm3, xmm4
1136    
1137  %ifdef SATURATE  %ifdef SATURATE
1138                  movq mm2, [mmx_32767_minus_2047]                  movdqu  xmm2, [sse2_pos_2047]
1139                  movq mm4, [mmx_32768_minus_2048]                  movdqu  xmm4, [sse2_neg_2048]
1140                  paddsw  mm0, mm2                  pminsw  xmm0, xmm2
1141                  paddsw  mm3, mm2                  pminsw  xmm3, xmm2
1142                  psubsw  mm0, mm2                  pmaxsw  xmm0, xmm4
1143                  psubsw  mm3, mm2                  pmaxsw  xmm3, xmm4
                 psubsw  mm0, mm4  
                 psubsw  mm3, mm4  
                 paddsw  mm0, mm4  
                 paddsw  mm3, mm4  
1144  %endif  %endif
1145    
1146                  movq    [edi + 8*eax], mm0                  movdqa  [edi + eax*8], xmm0
1147                  movq    [edi + 8*eax + 8], mm3                  movdqa  [edi + eax*8 + 16], xmm3
1148    
1149                  add eax, 2                  add eax, 4
1150                  cmp eax, 16                  cmp eax, 16
1151                  jnz     near .loop                  jnz     near .des2_loop
1152    
1153                  pop     edi                  pop     edi
1154                  pop     esi                  pop     esi

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

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