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

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

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

revision 3, Fri Mar 8 02:46:11 2002 UTC revision 653, Sun Nov 17 00:41:20 2002 UTC
# Line 1  Line 1 
1  ;/******************************************************************************  ;/*****************************************************************************
2  ; *                                                                            *  ; *
3  ; *  This file is part of XviD, a free MPEG-4 video encoder/decoder            *  ; *  XVID MPEG-4 VIDEO CODEC
4  ; *                                                                            *  ; *  mmx optimized MPEG quantization/dequantization
5  ; *  XviD is an implementation of a part of one or more MPEG-4 Video tools     *  ; *
6  ; *  as specified in ISO/IEC 14496-2 standard.  Those intending to use this    *  ; *  Copyright(C) 2002 Peter Ross <pross@xvid.org>
7  ; *  software module in hardware or software products are advised that its     *  ; *  Copyright(C) 2002 Michael Militzer <michael@xvid.org>
8  ; *  use may infringe existing patents or copyrights, and any such use         *  ; *  Copyright(C) 2002 Pascal Massimino <skal@planet-d.net>
9  ; *  would be at such party's own risk.  The original developer of this        *  ; *
10  ; *  software module and his/her company, and subsequent editors and their     *  ; *  This file is part of XviD, a free MPEG-4 video encoder/decoder
11  ; *  companies, will have no liability for use of this software or             *  ; *
12  ; *  modifications or derivatives thereof.                                     *  ; *  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  ; *  XviD is free software; you can redistribute it and/or modify it           *  ; *  the Free Software Foundation; either version 2 of the License, or
15  ; *  under the terms of the GNU General Public License as published by         *  ; *  (at your option) any later version.
16  ; *  the Free Software Foundation; either version 2 of the License, or         *  ; *
17  ; *  (at your option) any later version.                                       *  ; *  This program is distributed in the hope that it will be useful,
18  ; *                                                                            *  ; *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  ; *  XviD is distributed in the hope that it will be useful, but               *  ; *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  ; *  WITHOUT ANY WARRANTY; without even the implied warranty of                *  ; *  GNU General Public License for more details.
21  ; *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *  ; *
22  ; *  GNU General Public License for more details.                              *  ; *  You should have received a copy of the GNU General Public License
23  ; *                                                                            *  ; *  along with this program; if not, write to the Free Software
24  ; *  You should have received a copy of the GNU General Public License         *  ; *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
25  ; *  along with this program; if not, write to the Free Software               *  ; *
26  ; *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA  *  ; *  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  ; *  quantize4.asm, MMX optimized MPEG quantization/dequantization             *  ; *
33  ; *                                                                            *  ; *  Linking XviD statically or dynamically with other modules is making a
34  ; *  Copyright (C) 2002 - Peter Ross <pross@cs.rmit.edu.au>                    *  ; *  combined work based on XviD.  Thus, the terms and conditions of the
35  ; *  Copyright (C) 2002 - Michael Militzer <isibaar@xvid.org>                  *  ; *  GNU General Public License cover the whole combination.
36  ; *                                                                            *  ; *
37  ; *  For more information visit the XviD homepage: http://www.xvid.org         *  ; *  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  ; *  Revision history:                                                         *  ; *  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  ; *  22.01.2002 initial version                                                *  ; *  Public License plus this exception.  An independent module is a module
46  ; *                                                                            *  ; *  which is not derived from or based on XviD.
47  ; ******************************************************************************/  ; *
48    ; *  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    ; * $Id: quantize4_mmx.asm,v 1.7 2002-11-17 00:41:20 edgomez Exp $
56    ; *
57    ; *************************************************************************/
58    
59  ; data/text alignment  ; data/text alignment
60  %define ALIGN 8  %define ALIGN 8
# Line 64  Line 74 
74          %endif          %endif
75  %endmacro  %endmacro
76    
77    %macro cextern 1
78            %ifdef PREFIX
79                    extern _%1
80                    %define %1 _%1
81            %else
82                    extern %1
83            %endif
84    %endmacro
85    
86  mmx_one times 4 dw       1  mmx_one times 4 dw       1
87    
88  ;===========================================================================  ;===========================================================================
# Line 113  Line 132 
132    
133  ;===========================================================================  ;===========================================================================
134  ;  ;
135  ; default intra matrix  ; intra matrix
136  ;  ;
137  ;===========================================================================  ;===========================================================================
138    
139  mmx_intra_matrix  cextern intra_matrix
140                  dw 8, 17, 18, 19  cextern intra_matrix_fix
                 dw 21, 23, 25, 27  
                 dw 17, 18, 19, 21  
                 dw 23, 25, 27, 28  
                 dw 20, 21, 22, 23  
                 dw 24, 26, 28, 30  
                 dw 21, 22, 23, 24  
                 dw 26, 28, 30, 32  
                 dw 22, 23, 24, 26  
                 dw 28, 30, 32, 35  
                 dw 23, 24, 26, 28  
                 dw 30, 32, 35, 38  
                 dw 25, 26, 28, 30  
                 dw 32, 35, 38, 41  
                 dw 27, 28, 30, 32  
                 dw 35, 38, 41, 45  
   
 %macro MMX_FIX  4  
 dw (1 << 16) / (%1) + 1, (1 << 16) / (%2) + 1, (1 << 16) / (%3) + 1, (1 << 16) / (%4) + 1  
 %endmacro  
   
 mmx_intra_matrix_fix  
                 MMX_FIX 8, 17, 18, 19  
                 MMX_FIX 21, 23, 25, 27  
                 MMX_FIX 17, 18, 19, 21  
                 MMX_FIX 23, 25, 27, 28  
                 MMX_FIX 20, 21, 22, 23  
                 MMX_FIX 24, 26, 28, 30  
                 MMX_FIX 21, 22, 23, 24  
                 MMX_FIX 26, 28, 30, 32  
                 MMX_FIX 22, 23, 24, 26  
                 MMX_FIX 28, 30, 32, 35  
                 MMX_FIX 23, 24, 26, 28  
                 MMX_FIX 30, 32, 35, 38  
                 MMX_FIX 25, 26, 28, 30  
                 MMX_FIX 32, 35, 38, 41  
                 MMX_FIX 27, 28, 30, 32  
                 MMX_FIX 35, 38, 41, 45  
   
141    
142  ;===========================================================================  ;===========================================================================
143  ;  ;
144  ; default inter matrix  ; inter matrix
145  ;  ;
146  ;===========================================================================  ;===========================================================================
147    
148  mmx_inter_matrix  cextern inter_matrix
149                  dw 16,17,18,19  cextern inter_matrix_fix
150                  dw 20,21,22,23  
                 dw 17,18,19,20  
                 dw 21,22,23,24  
                 dw 18,19,20,21  
                 dw 22,23,24,25  
                 dw 19,20,21,22  
                 dw 23,24,26,27  
                 dw 20,21,22,23  
                 dw 25,26,27,28  
                 dw 21,22,23,24  
                 dw 26,27,28,30  
                 dw 22,23,24,26  
                 dw 27,28,30,31  
                 dw 23,24,25,27  
                 dw 28,30,31,33  
   
   
 mmx_inter_matrix_fix  
                 MMX_FIX 16,17,18,19  
                 MMX_FIX 20,21,22,23  
                 MMX_FIX 17,18,19,20  
                 MMX_FIX 21,22,23,24  
                 MMX_FIX 18,19,20,21  
                 MMX_FIX 22,23,24,25  
                 MMX_FIX 19,20,21,22  
                 MMX_FIX 23,24,26,27  
                 MMX_FIX 20,21,22,23  
                 MMX_FIX 25,26,27,28  
                 MMX_FIX 21,22,23,24  
                 MMX_FIX 26,27,28,30  
                 MMX_FIX 22,23,24,26  
                 MMX_FIX 27,28,30,31  
                 MMX_FIX 23,24,25,27  
                 MMX_FIX 28,30,31,33  
151    
152  %define VM18P 3  %define VM18P 3
153  %define VM18Q 4  %define VM18Q 4
154    
155    
156  ;===========================================================================  ;===========================================================================
157  ;  ;
158  ; quantd table  ; quantd table
# Line 250  Line 199 
199    
200  ;===========================================================================  ;===========================================================================
201  ;  ;
 ; multiple by matrix table  
 ;  
 ;===========================================================================  
   
 %macro MMX_MUL 4  
 dw  %1  
 dw  %2  
 dw  %3  
 dw  %4  
 %endmacro  
   
 default_inter_matrix_mul  
         MMX_MUL    16,17,18,19  
         MMX_MUL    20,21,22,23  
         MMX_MUL    17,18,19,20  
         MMX_MUL    21,22,23,24  
         MMX_MUL    18,19,20,21  
         MMX_MUL    22,23,24,25  
         MMX_MUL    19,20,21,22  
         MMX_MUL    23,24,26,27  
         MMX_MUL    20,21,22,23  
         MMX_MUL    25,26,27,28  
         MMX_MUL    21,22,23,24  
         MMX_MUL    26,27,28,30  
         MMX_MUL    22,23,24,26  
         MMX_MUL    27,28,30,31  
         MMX_MUL    23,24,25,27  
         MMX_MUL    28,30,31,33  
   
   
 default_intra_matrix_mul  
         MMX_MUL 8,17,18,19  
         MMX_MUL 21,23,25,27  
         MMX_MUL 17,18,19,21  
         MMX_MUL 23,25,27,28  
         MMX_MUL 20,21,22,23  
         MMX_MUL 24,26,28,30  
         MMX_MUL 21,22,23,24  
         MMX_MUL 26,28,30,32  
         MMX_MUL 22,23,24,26  
         MMX_MUL 28,30,32,35  
         MMX_MUL 23,24,26,28  
         MMX_MUL 30,32,35,38  
         MMX_MUL 25,26,28,30  
         MMX_MUL 32,35,38,41  
         MMX_MUL 27,28,30,32  
         MMX_MUL 35,38,41,45  
   
   
 ;===========================================================================  
 ;  
202  ; multiple by 2Q table  ; multiple by 2Q table
203  ;  ;
204  ;===========================================================================  ;===========================================================================
# Line 349  Line 247 
247  ;===========================================================================  ;===========================================================================
248    
249  align 16  align 16
250  mmx_32768_minus_2048                times 4 dw (32768-2048)  
251  mmx_32767_minus_2047                times 4 dw (32767-2047)  mmx_32767_minus_2047                times 4 dw (32767-2047)
252    mmx_32768_minus_2048                            times 4 dw (32768-2048)
253    mmx_2047 times 4 dw 2047
254    mmx_minus_2048 times 4 dw (-2048)
255    zero times 4 dw 0
256    
257  section .text  section .text
258    
# Line 405  Line 307 
307                  psllw   mm0, 4                  ; level << 4                  psllw   mm0, 4                  ; level << 4
308                  psllw   mm3, 4                  ;                  psllw   mm3, 4                  ;
309    
310                  movq    mm2, [mmx_intra_matrix + 8*ecx]                  movq    mm2, [intra_matrix + 8*ecx]
311                  psrlw   mm2, 1                  ; intra_matrix[i]>>1                  psrlw   mm2, 1                  ; intra_matrix[i]>>1
312                  paddw   mm0, mm2                  paddw   mm0, mm2
313    
314                  movq    mm2, [mmx_intra_matrix_fix + ecx*8]                  movq    mm2, [intra_matrix_fix + ecx*8]
315                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
316    
317                  movq    mm2, [mmx_intra_matrix + 8*ecx + 8]                  movq    mm2, [intra_matrix + 8*ecx + 8]
318                  psrlw   mm2, 1                  psrlw   mm2, 1
319                  paddw   mm3, mm2                  paddw   mm3, mm2
320    
321                  movq    mm2, [mmx_intra_matrix_fix + ecx*8 + 8]                  movq    mm2, [intra_matrix_fix + ecx*8 + 8]
322                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
323    
324              paddw   mm0, mm5            ; + quantd              paddw   mm0, mm5            ; + quantd
# Line 484  Line 386 
386                  psllw   mm0, 4                  psllw   mm0, 4
387                  psllw   mm3, 4                  psllw   mm3, 4
388    
389                  movq    mm2, [mmx_intra_matrix + 8*ecx]                  movq    mm2, [intra_matrix + 8*ecx]
390                  psrlw   mm2, 1                  psrlw   mm2, 1
391                  paddw   mm0, mm2                  paddw   mm0, mm2
392    
393                  movq    mm2, [mmx_intra_matrix_fix + ecx*8]                  movq    mm2, [intra_matrix_fix + ecx*8]
394                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
395    
396                  movq    mm2, [mmx_intra_matrix + 8*ecx + 8]                  movq    mm2, [intra_matrix + 8*ecx + 8]
397                  psrlw   mm2, 1                  psrlw   mm2, 1
398                  paddw   mm3, mm2                  paddw   mm3, mm2
399    
400                  movq    mm2, [mmx_intra_matrix_fix + ecx*8 + 8]                  movq    mm2, [intra_matrix_fix + ecx*8 + 8]
401                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
402    
403          paddw   mm0, mm5          paddw   mm0, mm5
# Line 537  Line 439 
439                  psllw   mm0, 4                  psllw   mm0, 4
440                  psllw   mm3, 4                  psllw   mm3, 4
441    
442                  movq    mm2, [mmx_intra_matrix + 8*ecx]                  movq    mm2, [intra_matrix + 8*ecx]
443                  psrlw   mm2, 1                  psrlw   mm2, 1
444                  paddw   mm0, mm2                  paddw   mm0, mm2
445    
446                  movq    mm2, [mmx_intra_matrix_fix + ecx*8]                  movq    mm2, [intra_matrix_fix + ecx*8]
447                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
448    
449                  movq    mm2, [mmx_intra_matrix + 8*ecx + 8]                  movq    mm2, [intra_matrix + 8*ecx + 8]
450                  psrlw   mm2, 1                  psrlw   mm2, 1
451                  paddw   mm3, mm2                  paddw   mm3, mm2
452    
453                  movq    mm2, [mmx_intra_matrix_fix + ecx*8 + 8]                  movq    mm2, [intra_matrix_fix + ecx*8 + 8]
454                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
455    
456          paddw   mm0, mm5          paddw   mm0, mm5
# Line 619  Line 521 
521                  psllw   mm0, 4                  psllw   mm0, 4
522                  psllw   mm3, 4                  psllw   mm3, 4
523    
524                  movq    mm2, [mmx_inter_matrix + 8*ecx]                  movq    mm2, [inter_matrix + 8*ecx]
525                  psrlw   mm2, 1                  psrlw   mm2, 1
526                  paddw   mm0, mm2                  paddw   mm0, mm2
527    
528                  movq    mm2, [mmx_inter_matrix_fix + ecx*8]                  movq    mm2, [inter_matrix_fix + ecx*8]
529                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
530    
531                  movq    mm2, [mmx_inter_matrix + 8*ecx + 8]                  movq    mm2, [inter_matrix + 8*ecx + 8]
532                  psrlw   mm2, 1                  psrlw   mm2, 1
533                  paddw   mm3, mm2                  paddw   mm3, mm2
534    
535                  movq    mm2, [mmx_inter_matrix_fix + ecx*8 + 8]                  movq    mm2, [inter_matrix_fix + ecx*8 + 8]
536                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
537    
538                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16
# Line 683  Line 585 
585                  psllw   mm0, 4                  psllw   mm0, 4
586                  psllw   mm3, 4                  psllw   mm3, 4
587    
588                  movq    mm2, [mmx_inter_matrix + 8*ecx]                  movq    mm2, [inter_matrix + 8*ecx]
589                  psrlw   mm2, 1                  psrlw   mm2, 1
590                  paddw   mm0, mm2                  paddw   mm0, mm2
591    
592                  movq    mm2, [mmx_inter_matrix_fix + ecx*8]                  movq    mm2, [inter_matrix_fix + ecx*8]
593                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
594    
595                  movq    mm2, [mmx_inter_matrix + 8*ecx + 8]                  movq    mm2, [inter_matrix + 8*ecx + 8]
596                  psrlw   mm2, 1                  psrlw   mm2, 1
597                  paddw   mm3, mm2                  paddw   mm3, mm2
598    
599                  movq    mm2, [mmx_inter_matrix_fix + ecx*8 + 8]                  movq    mm2, [inter_matrix_fix + ecx*8 + 8]
600                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
601    
602                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)
# Line 736  Line 638 
638                  psllw   mm0, 4                  psllw   mm0, 4
639                  psllw   mm3, 4                  psllw   mm3, 4
640    
641                  movq    mm2, [mmx_inter_matrix + 8*ecx]                  movq    mm2, [inter_matrix + 8*ecx]
642                  psrlw   mm2, 1                  psrlw   mm2, 1
643                  paddw   mm0, mm2                  paddw   mm0, mm2
644    
645                  movq    mm2, [mmx_inter_matrix_fix + ecx*8]                  movq    mm2, [inter_matrix_fix + ecx*8]
646                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
647    
648                  movq    mm2, [mmx_inter_matrix + 8*ecx + 8]                  movq    mm2, [inter_matrix + 8*ecx + 8]
649                  psrlw   mm2, 1                  psrlw   mm2, 1
650                  paddw   mm3, mm2                  paddw   mm3, mm2
651    
652                  movq    mm2, [mmx_inter_matrix_fix + ecx*8 + 8]                  movq    mm2, [inter_matrix_fix + ecx*8 + 8]
653                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
654    
655                  psrlw   mm0, 2                  ; mm0 >>= 1   (/2)                  psrlw   mm0, 2                  ; mm0 >>= 1   (/2)
# Line 779  Line 681 
681  ;  ;
682  ;===========================================================================  ;===========================================================================
683    
684  align 16    ;   Note: in order to saturate 'easily', we pre-shift the quantifier
685  cglobal dequant4_intra_mmx    ; by 4. Then, the high-word of (coeff[]*matrix[i]*quant) are used to
686  dequant4_intra_mmx    ; build a saturating mask. It is non-zero only when an overflow occured.
687      ; We thus avoid packing/unpacking toward double-word.
688      ; Moreover, we perform the mult (matrix[i]*quant) first, instead of, e.g.,
689      ; (coeff[i]*matrix[i]). This is less prone to overflow if coeff[] are not
690      ; checked. Input ranges are: coeff in [-127,127], inter_matrix in [1..255],a
691      ; and quant in [1..31].
692      ;
693      ; The original loop is:
694      ;
695    %if 0
696      movq mm0, [ecx+8*eax + 8*16]   ; mm0 = coeff[i]
697      pxor mm1, mm1
698      pcmpgtw mm1, mm0
699      pxor mm0, mm1     ; change sign if negative
700      psubw mm0, mm1    ; -> mm0 = abs(coeff[i]), mm1 = sign of coeff[i]
701    
702      movq mm2, mm7     ; mm2 = quant
703      pmullw mm2,  [intra_matrix + 8*eax + 8*16 ]  ; matrix[i]*quant.
704    
705      movq mm6, mm2
706      pmulhw mm2, mm0   ; high of coeff*(matrix*quant)  (should be 0 if no overflow)
707      pmullw mm0, mm6   ; low  of coeff*(matrix*quant)
708    
709      pxor mm5, mm5
710      pcmpgtw mm2, mm5  ; otherflow?
711      psrlw mm2, 5      ; =0 if no clamp, 2047 otherwise
712      psrlw mm0, 5
713      paddw mm0, mm1    ; start restoring sign
714      por mm0, mm2      ; saturate to 2047 if needed
715      pxor mm0, mm1     ; finish negating back
716    
717          push    esi    movq [edx + 8*eax + 8*16], mm0   ; data[i]
718          push    edi    add eax, 1
719    %endif
720    
721          mov    edi, [esp + 8 + 4]        ; data    ;********************************************************************
         mov    esi, [esp + 8 + 8]        ; coeff  
         mov    eax, [esp + 8 + 12]        ; quant  
722    
723          movq mm7, [mmx_mul_quant  + eax*8 - 8]  align 16
724    cglobal dequant4_intra_mmx
725    dequant4_intra_mmx:
726    
727          xor eax, eax    mov edx, [esp+4]  ; data
728      mov ecx, [esp+8]  ; coeff
729      mov eax, [esp+12] ; quant
730    
731      movq mm7, [mmx_mul_quant  + eax*8 - 8]
732      mov eax, -16   ; to keep aligned, we regularly process coeff[0]
733      psllw mm7, 2   ; << 2. See comment.
734      pxor mm6, mm6   ; this is a NOP
735    
736  align 16  align 16
737  .loop  .loop
738          movq    mm0, [esi + 8*eax]        ; mm0 = [coeff]    movq mm0, [ecx+8*eax + 8*16]   ; mm0 = c  = coeff[i]
739      movq mm3, [ecx+8*eax + 8*16 +8]; mm3 = c' = coeff[i+1]
740      pxor mm1, mm1
741      pxor mm4, mm4
742      pcmpgtw mm1, mm0  ; mm1 = sgn(c)
743      movq mm2, mm7     ; mm2 = quant
744    
745          pxor    mm1, mm1                ; mm1 = 0    pcmpgtw mm4, mm3  ; mm4 = sgn(c')
746          pcmpeqw    mm1, mm0                ; mm1 = (0 == mm0)    pmullw mm2,  [intra_matrix + 8*eax + 8*16 ]  ; matrix[i]*quant
747    
748          pxor    mm2, mm2                ; mm2 = 0    pxor mm0, mm1     ; negate if negative
749          pcmpgtw    mm2, mm0                ; mm2 = (0 > mm0)    pxor mm3, mm4     ; negate if negative
         pxor    mm0, mm2                ; mm0 = |mm0|  
         psubw    mm0, mm2                ; displace  
750    
751          pmullw    mm0, mm7                ; mm0 *= quant    psubw mm0, mm1
752      psubw mm3, mm4
753    
754          movq    mm3, [default_intra_matrix_mul + 8*eax]      ; we're short on register, here. Poor pairing...
755    
756          movq  mm4, mm0                    ;    movq mm5, mm2
757          pmullw    mm0, mm3                ; mm0 = low(mm0 * mm3)    pmullw mm2, mm0   ; low  of coeff*(matrix*quant)
         pmulhw    mm3, mm4                ; mm3 = high(mm0 * mm3)  
758    
759          movq    mm4, mm0                ; mm0,mm4 = unpack(mm3, mm0)    pmulhw mm0, mm5   ; high of coeff*(matrix*quant)
760          punpcklwd mm0, mm3                ;    movq mm5, mm7     ; mm2 = quant
         punpckhwd mm4, mm3                ;  
         psrld mm0, 3                    ; mm0,mm4 /= 8  
         psrld mm4, 3                    ;  
         packssdw mm0, mm4                ; mm0 = pack(mm4, mm0)  
761    
762          pxor    mm0, mm2                ; mm0 *= sign(mm0)    pmullw mm5,  [intra_matrix + 8*eax + 8*16 +8]  ; matrix[i+1]*quant
         psubw    mm0, mm2                ; undisplace  
         pandn    mm1, mm0                ; mm1 = ~(iszero) & mm0  
763    
764  %ifdef SATURATE    movq mm6, mm5
765          movq mm2, [mmx_32767_minus_2047]    add eax,2   ; z-flag will be tested later
         movq mm6, [mmx_32768_minus_2048]  
         paddsw    mm1, mm2  
         psubsw    mm1, mm2  
         psubsw    mm1, mm6  
         paddsw    mm1, mm6  
 %endif  
766    
767          movq    [edi + 8*eax], mm1        ; [data] = mm0    pmullw mm6, mm3   ; low  of coeff*(matrix*quant)
768      pmulhw mm3, mm5   ; high of coeff*(matrix*quant)
769    
770          add eax, 1    pcmpgtw mm0, [zero]
771          cmp eax, 16    paddusw mm2, mm0
772          jnz    near .loop    psrlw mm2, 5
773    
774          mov    ax, [esi]                    ; ax = data[0]    pcmpgtw mm3, [zero]
775          imul     ax, [esp + 8 + 16]        ; eax = data[0] * dcscalar    paddusw mm6, mm3
776          mov    [edi], ax                    ; data[0] = ax    psrlw mm6, 5
   
 %ifdef SATURATE  
         cmp ax, -2048  
         jl .set_n2048  
         cmp ax, 2047  
         jg .set_2047  
 %endif  
777    
778          pop    edi    pxor mm2, mm1  ; start negating back
779          pop    esi    pxor mm6, mm4  ; start negating back
         ret  
780    
781  %ifdef SATURATE    psubusw mm1, mm0
782  .set_n2048    psubusw mm4, mm3
         mov    word [edi], -2048  
         pop    edi  
         pop    esi  
         ret  
783    
784  .set_2047    psubw mm2, mm1 ; finish negating back
785          mov    word [edi], 2047    psubw mm6, mm4 ; finish negating back
         pop    edi  
         pop    esi  
786    
787                  ret    movq [edx + 8*eax + 8*16   -2*8   ], mm2   ; data[i]
788  %endif    movq [edx + 8*eax + 8*16   -2*8 +8], mm6   ; data[i+1]
789    
790      jnz near .loop
791    
792        ; deal with DC
793    
794      movd mm0, [ecx]
795      pmullw mm0, [esp+16]  ; dcscalar
796      movq mm2, [mmx_32767_minus_2047]
797      paddsw mm0, mm2
798      psubsw mm0, mm2
799      movq mm2, [mmx_32768_minus_2048]
800      psubsw mm0, mm2
801      paddsw mm0, mm2
802      movd eax, mm0
803      mov [edx], ax
804    
805      ret
806    
807  ;===========================================================================  ;===========================================================================
808  ;  ;
# Line 881  Line 812 
812  ;  ;
813  ;===========================================================================  ;===========================================================================
814    
815        ; Note:  We use (2*c + sgn(c) - sgn(-c)) as multiplier
816        ; so we handle the 3 cases: c<0, c==0, and c>0 in one shot.
817        ; sgn(x) is the result of 'pcmpgtw 0,x':  0 if x>=0, -1 if x<0.
818        ; It's mixed with the extraction of the absolute value.
819    
820  align 16  align 16
821  cglobal dequant4_inter_mmx  cglobal dequant4_inter_mmx
822  dequant4_inter_mmx  dequant4_inter_mmx:
823    
824          push    esi    mov    edx, [esp+ 4]        ; data
825          push    edi    mov    ecx, [esp+ 8]        ; coeff
826      mov    eax, [esp+12]        ; quant
         mov    edi, [esp + 8 + 4]        ; data  
         mov    esi, [esp + 8 + 8]        ; coeff  
         mov    eax, [esp + 8 + 12]        ; quant  
827          movq mm7, [mmx_mul_quant  + eax*8 - 8]          movq mm7, [mmx_mul_quant  + eax*8 - 8]
828          movq mm6, [mmx_one]    mov eax, -16
829          xor eax, eax    paddw mm7, mm7    ; << 1
830          pxor mm5, mm5        ; mismatch sum    pxor mm6, mm6 ; mismatch sum
   
831    
832  align 16  align 16
833  .loop  .loop
834          movq    mm0, [esi + 8*eax]                        ; mm0 = [coeff]    movq mm0, [ecx+8*eax + 8*16   ]   ; mm0 = coeff[i]
835      movq mm2, [ecx+8*eax + 8*16 +8]   ; mm2 = coeff[i+1]
836          pxor    mm1, mm1                ; mm1 = 0    add eax,2
837          pcmpeqw    mm1, mm0                ; mm1 = (0 == mm0)  
838      pxor mm1, mm1
839          pxor    mm2, mm2                ; mm2 = 0    pxor mm3, mm3
840          pcmpgtw    mm2, mm0                ; mm2 = (0 > mm0)    pcmpgtw mm1, mm0  ; mm1 = sgn(c)    (preserved)
841          pxor    mm0, mm2                ; mm0 = |mm0|    pcmpgtw mm3, mm2  ; mm3 = sgn(c')   (preserved)
842          psubw    mm0, mm2                ; displace    paddsw mm0, mm1   ; c += sgn(c)
843      paddsw mm2, mm3   ; c += sgn(c')
844          psllw    mm0, 1                ;    paddw mm0, mm0    ; c *= 2
845          paddsw    mm0, mm6            ; mm0 = 2*mm0 + 1    paddw mm2, mm2    ; c'*= 2
         pmullw    mm0, mm7            ; mm0 *= quant  
   
         movq    mm3, [default_inter_matrix_mul + 8*eax]  
   
         movq  mm4, mm0  
         pmullw    mm0, mm3            ; mm0 = low(mm0 * mm3)  
         pmulhw    mm3, mm4            ; mm3 = high(mm0 * mm3)  
   
         movq    mm4, mm0            ; mm0,mm4 = unpack(mm3, mm0)  
         punpcklwd mm0, mm3            ;  
         punpckhwd mm4, mm3            ;  
   
         psrad mm0, 4                ; mm0,mm4 /= 16  
         psrad mm4, 4                ;  
         packssdw mm0, mm4            ; mm0 = pack(mm4, mm0)  
   
         pxor    mm0, mm2            ; mm0 *= sign(mm0)  
         psubw    mm0, mm2            ; undisplace  
         pandn    mm1, mm0            ; mm1 = ~(iszero) & mm0  
   
   
 ;%ifdef SATURATE  
         movq mm2, [mmx_32767_minus_2047]  
         movq mm4, [mmx_32768_minus_2048]  
         paddsw    mm1, mm2  
         psubsw    mm1, mm2  
         psubsw    mm1, mm4  
         paddsw    mm1, mm4  
 ;%endif  
846    
847          pxor mm5, mm1        ; mismatch    pxor mm4, mm4
848      pxor mm5, mm5
849          movq    [edi + 8*eax], mm1        ; [data] = mm0    psubw mm4, mm0    ; -c
850      psubw mm5, mm2    ; -c'
851      psraw mm4, 16     ; mm4 = sgn(-c)
852      psraw mm5, 16     ; mm5 = sgn(-c')
853      psubsw mm0, mm4   ; c  -= sgn(-c)
854      psubsw mm2, mm5   ; c' -= sgn(-c')
855      pxor mm0, mm1     ; finish changing sign if needed
856      pxor mm2, mm3     ; finish changing sign if needed
857    
858        ; we're short on register, here. Poor pairing...
859    
860      movq mm4, mm7     ; (matrix*quant)
861      pmullw mm4,  [inter_matrix + 8*eax + 8*16 -2*8]
862      movq mm5, mm4
863      pmulhw mm5, mm0   ; high of c*(matrix*quant)
864      pmullw mm0, mm4   ; low  of c*(matrix*quant)
865    
866      movq mm4, mm7     ; (matrix*quant)
867      pmullw mm4,  [inter_matrix + 8*eax + 8*16 -2*8 + 8]
868    
869      pcmpgtw mm5, [zero]
870      paddusw mm0, mm5
871      psrlw mm0, 5
872      pxor mm0, mm1     ; start restoring sign
873      psubusw mm1, mm5
874    
875      movq mm5, mm4
876      pmulhw mm5, mm2   ; high of c*(matrix*quant)
877      pmullw mm2, mm4   ; low  of c*(matrix*quant)
878      psubw mm0, mm1    ; finish restoring sign
879    
880      pcmpgtw mm5, [zero]
881      paddusw mm2, mm5
882      psrlw mm2, 5
883      pxor mm2, mm3    ; start restoring sign
884      psubusw mm3, mm5
885      psubw mm2, mm3   ; finish restoring sign
886    
887      pxor mm6, mm0     ; mismatch control
888      movq [edx + 8*eax + 8*16 -2*8   ], mm0   ; data[i]
889      pxor mm6, mm2     ; mismatch control
890      movq [edx + 8*eax + 8*16 -2*8 +8], mm2   ; data[i+1]
891    
         add eax, 1  
         cmp eax, 16  
892          jnz    near .loop          jnz    near .loop
893    
894          ; mismatch control          ; mismatch control
895    
896          movq mm0, mm5    movq mm0, mm6
         movq mm1, mm5  
         movq mm2, mm5  
897          psrlq mm0, 48          psrlq mm0, 48
898      movq mm1, mm6
899      movq mm2, mm6
900          psrlq mm1, 32          psrlq mm1, 32
901      pxor mm6, mm0
902          psrlq mm2, 16          psrlq mm2, 16
903          pxor mm5, mm0    pxor mm6, mm1
904          pxor mm5, mm1    pxor mm6, mm2
905          pxor mm5, mm2    movd eax, mm6
906      and eax, 1
907          movd eax, mm5    xor eax, 1
908          test eax, 0x1    xor word [edx + 2*63], ax
         jnz .done  
   
         xor word [edi + 2*63], 1  
   
 .done  
         pop    edi  
         pop    esi  
909    
910          ret          ret
911    

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

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