[cvs] / xvidcore / src / quant / x86_asm / quantize_mpeg_mmx.asm Repository:
ViewVC logotype

Diff of /xvidcore/src/quant/x86_asm/quantize_mpeg_mmx.asm

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

revision 1.1.2.1, Tue Oct 7 13:02:35 2003 UTC revision 1.6, Mon Jul 10 08:09:59 2006 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  ; *                                                                            *  ; *  - 3dne 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-2003 Peter Ross <pross@xvid.org>
7  ; *  software module in hardware or software products are advised that its     *  ; *                2002-2003 Michael Militzer <isibaar@xvid.org>
8  ; *  use may infringe existing patents or copyrights, and any such use         *  ; *                2002-2003 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 program is free software ; you can redistribute it and/or modify
11  ; *  companies, will have no liability for use of this software or             *  ; *  it under the terms of the GNU General Public License as published by
12  ; *  modifications or derivatives thereof.                                     *  ; *  the Free Software Foundation ; either version 2 of the License, or
13  ; *                                                                            *  ; *  (at your option) any later version.
14  ; *  XviD is free software; you can redistribute it and/or modify it           *  ; *
15  ; *  under the terms of the GNU General Public License as published by         *  ; *  This program is distributed in the hope that it will be useful,
16  ; *  the Free Software Foundation; either version 2 of the License, or         *  ; *  but WITHOUT ANY WARRANTY ; without even the implied warranty of
17  ; *  (at your option) any later version.                                       *  ; *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  ; *                                                                            *  ; *  GNU General Public License for more details.
19  ; *  XviD is distributed in the hope that it will be useful, but               *  ; *
20  ; *  WITHOUT ANY WARRANTY; without even the implied warranty of                *  ; *  You should have received a copy of the GNU General Public License
21  ; *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *  ; *  along with this program ; if not, write to the Free Software
22  ; *  GNU General Public License for more details.                              *  ; *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23  ; *                                                                            *  ; *
24  ; *  You should have received a copy of the GNU General Public License         *  ; * $Id$
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  *  ; *************************************************************************/
 ; *                                                                            *  
 ; ******************************************************************************/  
 ;  
 ;/******************************************************************************  
 ; *                                                                            *  
 ; *  quantize4.asm, MMX optimized MPEG quantization/dequantization             *  
 ; *                                                                            *  
 ; *  Copyright (C) 2002 - Peter Ross <pross@cs.rmit.edu.au>                    *  
 ; *  Copyright (C) 2002 - Michael Militzer <isibaar@xvid.org>                  *  
 ; *                                                                            *  
 ; *  For more information visit the XviD homepage: http://www.xvid.org         *  
 ; *                                                                            *  
 ; ******************************************************************************/  
 ;  
 ;/******************************************************************************  
 ; *                                                                            *  
 ; *  Revision history:                                                         *  
 ; *                                                                            *  
 ; *  14.06.2002  mmx dequant4_* funcs revamped  -Skal-                         *  
 ; *  22.01.2002 initial version                                                *  
 ; *                                                                            *  
 ; ******************************************************************************/  
   
 ; data/text alignment  
 %define ALIGN 8  
27    
28  %define SATURATE  %define SATURATE
29    
30  bits 32  BITS 32
   
 %ifdef FORMAT_COFF  
 SECTION .data data  
 %else  
 SECTION .data data align=8  
 %endif  
   
31    
32  %macro cglobal 1  %macro cglobal 1
33          %ifdef PREFIX          %ifdef PREFIX
34                    %ifdef MARK_FUNCS
35                            global _%1:function %1.endfunc-%1
36                            %define %1 _%1:function %1.endfunc-%1
37                    %else
38                  global _%1                  global _%1
39                  %define %1 _%1                  %define %1 _%1
40                    %endif
41            %else
42                    %ifdef MARK_FUNCS
43                            global %1:function %1.endfunc-%1
44          %else          %else
45                  global %1                  global %1
46          %endif          %endif
47            %endif
48  %endmacro  %endmacro
49    
50  %macro cextern 1  %macro cextern 1
# Line 79  Line 56 
56          %endif          %endif
57  %endmacro  %endmacro
58    
59  mmx_one times 4 dw       1  ;=============================================================================
60    ; Local data (Read Only)
61  ;===========================================================================  ;=============================================================================
 ;  
 ; divide by 2Q table  
 ;  
 ;===========================================================================  
   
 %macro MMX_DIV  1  
 times 4 dw  (1 << 17) / (%1 * 2) + 1  
 %endmacro  
   
 align ALIGN  
 mmx_div  
                 MMX_DIV 1  
                 MMX_DIV 2  
                 MMX_DIV 3  
                 MMX_DIV 4  
                 MMX_DIV 5  
                 MMX_DIV 6  
                 MMX_DIV 7  
                 MMX_DIV 8  
                 MMX_DIV 9  
                 MMX_DIV 10  
                 MMX_DIV 11  
                 MMX_DIV 12  
                 MMX_DIV 13  
                 MMX_DIV 14  
                 MMX_DIV 15  
                 MMX_DIV 16  
                 MMX_DIV 17  
                 MMX_DIV 18  
                 MMX_DIV 19  
                 MMX_DIV 20  
                 MMX_DIV 21  
                 MMX_DIV 22  
                 MMX_DIV 23  
                 MMX_DIV 24  
                 MMX_DIV 25  
                 MMX_DIV 26  
                 MMX_DIV 27  
                 MMX_DIV 28  
                 MMX_DIV 29  
                 MMX_DIV 30  
                 MMX_DIV 31  
   
   
 ;===========================================================================  
 ;  
 ; intra matrix  
 ;  
 ;===========================================================================  
62    
63  cextern intra_matrix  %ifdef FORMAT_COFF
64  cextern intra_matrix_fix  SECTION .rodata
65    %else
66    SECTION .rodata align=16
67    %endif
68    
69  ;===========================================================================  mmx_one:
70  ;          times 4 dw       1
 ; inter matrix  
 ;  
 ;===========================================================================  
71    
72  cextern inter_matrix  ;-----------------------------------------------------------------------------
73  cextern inter_matrix_fix  ; divide by 2Q table
74    ;-----------------------------------------------------------------------------
75    
76    ALIGN 16
77    mmx_div:
78            times 4 dw 65535 ; the div by 2 formula will overflow for the case
79                             ; quant=1 but we don't care much because quant=1
80                             ; is handled by a different piece of code that
81                             ; doesn't use this table.
82    %assign quant 2
83    %rep 30
84            times 4 dw  (1<<17) / (quant*2) + 1
85            %assign quant quant+1
86    %endrep
87    
88  %define VM18P 3  %define VM18P 3
89  %define VM18Q 4  %define VM18Q 4
90    
91    
92  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
93  ; quantd table  ; quantd table
94  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
   
 %macro MMX_QUANTD  1  
 times 4 dw ((VM18P*%1) + (VM18Q/2)) / VM18Q  
 %endmacro  
   
 quantd  
                 MMX_QUANTD 1  
                 MMX_QUANTD 2  
                 MMX_QUANTD 3  
                 MMX_QUANTD 4  
                 MMX_QUANTD 5  
                 MMX_QUANTD 6  
                 MMX_QUANTD 7  
                 MMX_QUANTD 8  
                 MMX_QUANTD 9  
                 MMX_QUANTD 10  
                 MMX_QUANTD 11  
                 MMX_QUANTD 12  
                 MMX_QUANTD 13  
                 MMX_QUANTD 14  
                 MMX_QUANTD 15  
                 MMX_QUANTD 16  
                 MMX_QUANTD 17  
                 MMX_QUANTD 18  
                 MMX_QUANTD 19  
                 MMX_QUANTD 20  
                 MMX_QUANTD 21  
                 MMX_QUANTD 22  
                 MMX_QUANTD 23  
                 MMX_QUANTD 24  
                 MMX_QUANTD 25  
                 MMX_QUANTD 26  
                 MMX_QUANTD 27  
                 MMX_QUANTD 28  
                 MMX_QUANTD 29  
                 MMX_QUANTD 30  
                 MMX_QUANTD 31  
95    
96    quantd:
97    %assign quant 1
98    %rep 31
99            times 4 dw  ((VM18P*quant) + (VM18Q/2)) / VM18Q
100            %assign quant quant+1
101    %endrep
102    
103  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
104  ; multiple by 2Q table  ; multiple by 2Q table
105  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
   
 %macro MMX_MUL_QUANT  1  
 times 4   dw  %1  
 %endmacro  
106    
107  mmx_mul_quant  mmx_mul_quant:
108          MMX_MUL_QUANT 1  %assign quant 1
109          MMX_MUL_QUANT 2  %rep 31
110          MMX_MUL_QUANT 3          times 4 dw  quant
111          MMX_MUL_QUANT 4          %assign quant quant+1
112          MMX_MUL_QUANT 5  %endrep
         MMX_MUL_QUANT 6  
         MMX_MUL_QUANT 7  
         MMX_MUL_QUANT 8  
         MMX_MUL_QUANT 9  
         MMX_MUL_QUANT 10  
         MMX_MUL_QUANT 11  
         MMX_MUL_QUANT 12  
         MMX_MUL_QUANT 13  
         MMX_MUL_QUANT 14  
         MMX_MUL_QUANT 15  
         MMX_MUL_QUANT 16  
         MMX_MUL_QUANT 17  
         MMX_MUL_QUANT 18  
         MMX_MUL_QUANT 19  
         MMX_MUL_QUANT 20  
         MMX_MUL_QUANT 21  
         MMX_MUL_QUANT 22  
         MMX_MUL_QUANT 23  
         MMX_MUL_QUANT 24  
         MMX_MUL_QUANT 25  
         MMX_MUL_QUANT 26  
         MMX_MUL_QUANT 27  
         MMX_MUL_QUANT 28  
         MMX_MUL_QUANT 29  
         MMX_MUL_QUANT 30  
         MMX_MUL_QUANT 31  
113    
114  ;===========================================================================  ;-----------------------------------------------------------------------------
 ;  
115  ; saturation limits  ; saturation limits
116  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
117    
118  align 16  ALIGN 16
119    
120  mmx_32767_minus_2047                            times 4 dw (32767-2047)  mmx_32767_minus_2047:
121  mmx_32768_minus_2048                            times 4 dw (32768-2048)          times 4 dw (32767-2047)
122  mmx_2047 times 4 dw 2047  mmx_32768_minus_2048:
123  mmx_minus_2048 times 4 dw (-2048)          times 4 dw (32768-2048)
124  zero times 4 dw 0  mmx_2047:
125            times 4 dw 2047
126    mmx_minus_2048:
127            times 4 dw (-2048)
128    zero:
129            times 4 dw 0
130    
131    ;=============================================================================
132    ; rounding
133    ;=============================================================================
134    
135    mmx_rounding:
136            dw (1<<13)
137            dw 0
138            dw (1<<13)
139            dw 0
140    
141    ;=============================================================================
142    ; Code
143    ;=============================================================================
144    
145  section .text  SECTION .text
   
 ;===========================================================================  
 ;  
 ; void quant_intra4_mmx(int16_t * coeff,  
 ;                                       const int16_t const * data,  
 ;                                       const uint32_t quant,  
 ;                                       const uint32_t dcscalar);  
 ;  
 ;===========================================================================  
146    
 align ALIGN  
147  cglobal quant_mpeg_intra_mmx  cglobal quant_mpeg_intra_mmx
148  quant_mpeg_intra_mmx:  cglobal quant_mpeg_inter_mmx
149    cglobal dequant_mpeg_intra_mmx
150                  push    ecx  cglobal dequant_mpeg_inter_mmx
                 push    esi  
                 push    edi  
   
                 mov     edi, [esp + 12 + 4]             ; coeff  
                 mov     esi, [esp + 12 + 8]             ; data  
                 mov     eax, [esp + 12 + 12]    ; quant  
   
                 movq    mm5, [quantd + eax * 8 - 8] ; quantd -> mm5  
   
                 xor ecx, ecx  
                 cmp     al, 1  
                 jz      near .q1loop  
   
                 cmp     al, 2  
                 jz      near .q2loop  
   
                 movq    mm7, [mmx_div + eax * 8 - 8] ; multipliers[quant] -> mm7  
   
 align ALIGN  
 .loop  
                 movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]  
                 movq    mm3, [esi + 8*ecx + 8]  ;  
   
                 pxor    mm1, mm1                ; mm1 = 0  
                 pxor    mm4, mm4  
   
                 pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)  
                 pcmpgtw mm4, mm3  
   
                 pxor    mm0, mm1                ; mm0 = |mm0|  
                 pxor    mm3, mm4                ;  
                 psubw   mm0, mm1                ; displace  
                 psubw   mm3, mm4                ;  
   
                 psllw   mm0, 4                  ; level << 4  
                 psllw   mm3, 4                  ;  
   
                 movq    mm2, [intra_matrix + 8*ecx]  
                 psrlw   mm2, 1                  ; intra_matrix[i]>>1  
                 paddw   mm0, mm2  
151    
                 movq    mm2, [intra_matrix_fix + ecx*8]  
                 pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]  
152    
153                  movq    mm2, [intra_matrix + 8*ecx + 8]  %macro QUANT_MMX        1
154                  psrlw   mm2, 1          movq    mm0, [eax + 16*(%1)]                    ; data
155                  paddw   mm3, mm2          movq    mm2, [ecx + 16*(%1) + 128]              ; intra_matrix_rec
156            movq    mm4, [eax + 16*(%1) + 8]                ; data
157            movq    mm6, [ecx + 16*(%1) + 128 + 8]  ; intra_matrix_rec
158    
159                  movq    mm2, [intra_matrix_fix + ecx*8 + 8]          movq    mm1, mm0
160                  pmulhw  mm3, mm2          movq    mm5, mm4
161    
162              paddw   mm0, mm5            ; + quantd          pmullw  mm0, mm2                                        ; low results
163                  paddw   mm3, mm5          pmulhw  mm1, mm2                                        ; high results
164            pmullw  mm4, mm6                                        ; low results
165            pmulhw  mm5, mm6                                        ; high results
166    
167            movq    mm2, mm0
168            movq    mm6, mm4
169    
170            punpckhwd mm0, mm1
171            punpcklwd mm2, mm1
172            punpckhwd mm4, mm5
173            punpcklwd mm6, mm5
174    
175            paddd   mm2, mm7
176            paddd   mm0, mm7
177            paddd   mm6, mm7
178            paddd   mm4, mm7
179    
180            psrad   mm2, 14
181            psrad   mm0, 14
182            psrad   mm6, 14
183            psrad   mm4, 14
184    
185                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16          packssdw mm2, mm0
186                  pmulhw  mm3, mm7                ;          packssdw mm6, mm4
                 psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17  
                 psrlw   mm3, 1  
187    
188                  pxor    mm0, mm1                ; mm0 *= sign(mm0)          movq    [edi + 16*(%1)], mm2
189                  pxor    mm3, mm4                ;          movq    [edi + 16*(%1)+8], mm6
190                  psubw   mm0, mm1                ; undisplace  %endmacro
                 psubw   mm3, mm4                ;  
191    
192                  movq    [edi + 8*ecx], mm0  ;-----------------------------------------------------------------------------
193                  movq    [edi + 8*ecx + 8], mm3  ;
194    ; uint32_t quant_mpeg_intra_mmx(int16_t * coeff,
195    ;                               const int16_t const * data,
196    ;                               const uint32_t quant,
197    ;                               const uint32_t dcscalar,
198    ;                               const uint16_t *mpeg_matrices);
199    ;
200    ;-----------------------------------------------------------------------------
201    
202                  add ecx,2  ALIGN 16
203                  cmp ecx,16  quant_mpeg_intra_mmx:
                 jnz     near .loop  
204    
205  .done    push edi
206                  ; caclulate  data[0] // (int32_t)dcscalar)    movq mm7, [mmx_rounding]
207    
208                  mov     ecx, [esp + 12 + 16]    ; dcscalar    mov eax, [esp + 4 + 8]                ; data
209      mov ecx, [esp + 4 + 20]               ; mpeg_quant_matrices
210      mov edi, [esp + 4 + 4]                ; coeff
211    
212      QUANT_MMX(0)
213      QUANT_MMX(1)
214      QUANT_MMX(2)
215      QUANT_MMX(3)
216      QUANT_MMX(4)
217      QUANT_MMX(5)
218      QUANT_MMX(6)
219      QUANT_MMX(7)
220    
221      ; calculate DC
222      movsx eax, word [eax]     ; data[0]
223      mov ecx, [esp + 4 + 16]   ; dcscalar
224                  mov     edx, ecx                  mov     edx, ecx
                 movsx   eax, word [esi] ; data[0]  
225                  shr     edx, 1                  ; edx = dcscalar /2                  shr     edx, 1                  ; edx = dcscalar /2
226                  cmp             eax, 0    mov edi, edx
227                  jg              .gtzero    neg edi
228    
229      cmp eax, 0
230      cmovg edx, edi
231                  sub             eax, edx                  sub             eax, edx
232                  jmp             short .mul  
233  .gtzero    mov edi, [esp + 4 + 4]        ; coeff again
234                  add             eax, edx  
 .mul  
235                  cdq                             ; expand eax -> edx:eax                  cdq                             ; expand eax -> edx:eax
236                  idiv    ecx                     ; eax = edx:eax / dcscalar                  idiv    ecx                     ; eax = edx:eax / dcscalar
237    
238                  mov     [edi], ax               ; coeff[0] = ax                  mov     [edi], ax               ; coeff[0] = ax
239    
240                  pop     edi                  pop     edi
                 pop     esi  
                 pop     ecx  
241    
242      xor eax, eax              ; return(0);
243                  ret                  ret
244    
 align ALIGN  
 .q1loop  
                 movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]  
                 movq    mm3, [esi + 8*ecx + 8]  ;  
245    
                 pxor    mm1, mm1                ; mm1 = 0  
                 pxor    mm4, mm4                ;  
246    
247                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)  ;-----------------------------------------------------------------------------
                 pcmpgtw mm4, mm3                ;  
   
                 pxor    mm0, mm1                ; mm0 = |mm0|  
                 pxor    mm3, mm4                ;  
                 psubw   mm0, mm1                ; displace  
                 psubw   mm3, mm4                ;  
   
                 psllw   mm0, 4  
                 psllw   mm3, 4  
   
                 movq    mm2, [intra_matrix + 8*ecx]  
                 psrlw   mm2, 1  
                 paddw   mm0, mm2  
   
                 movq    mm2, [intra_matrix_fix + ecx*8]  
                 pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]  
   
                 movq    mm2, [intra_matrix + 8*ecx + 8]  
                 psrlw   mm2, 1  
                 paddw   mm3, mm2  
   
                 movq    mm2, [intra_matrix_fix + ecx*8 + 8]  
                 pmulhw  mm3, mm2  
   
         paddw   mm0, mm5  
                 paddw   mm3, mm5  
   
                 psrlw   mm0, 1                  ; mm0 >>= 1   (/2)  
                 psrlw   mm3, 1                  ;  
   
                 pxor    mm0, mm1                ; mm0 *= sign(mm0)  
                 pxor    mm3, mm4        ;  
                 psubw   mm0, mm1                ; undisplace  
                 psubw   mm3, mm4                ;  
   
                 movq    [edi + 8*ecx], mm0  
                 movq    [edi + 8*ecx + 8], mm3  
   
                 add ecx,2  
                 cmp ecx,16  
                 jnz     near .q1loop  
                 jmp     near .done  
   
   
 align ALIGN  
 .q2loop  
                 movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]  
                 movq    mm3, [esi + 8*ecx + 8]  ;  
   
                 pxor    mm1, mm1                ; mm1 = 0  
                 pxor    mm4, mm4                ;  
   
                 pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)  
                 pcmpgtw mm4, mm3                ;  
   
                 pxor    mm0, mm1                ; mm0 = |mm0|  
                 pxor    mm3, mm4                ;  
                 psubw   mm0, mm1                ; displace  
                 psubw   mm3, mm4                ;  
   
                 psllw   mm0, 4  
                 psllw   mm3, 4  
   
                 movq    mm2, [intra_matrix + 8*ecx]  
                 psrlw   mm2, 1  
                 paddw   mm0, mm2  
   
                 movq    mm2, [intra_matrix_fix + ecx*8]  
                 pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]  
   
                 movq    mm2, [intra_matrix + 8*ecx + 8]  
                 psrlw   mm2, 1  
                 paddw   mm3, mm2  
   
                 movq    mm2, [intra_matrix_fix + ecx*8 + 8]  
                 pmulhw  mm3, mm2  
   
         paddw   mm0, mm5  
                 paddw   mm3, mm5  
   
                 psrlw   mm0, 2                  ; mm0 >>= 1   (/4)  
                 psrlw   mm3, 2                  ;  
   
                 pxor    mm0, mm1                ; mm0 *= sign(mm0)  
                 pxor    mm3, mm4        ;  
                 psubw   mm0, mm1                ; undisplace  
                 psubw   mm3, mm4                ;  
   
                 movq    [edi + 8*ecx], mm0  
                 movq    [edi + 8*ecx + 8], mm3  
   
                 add ecx,2  
                 cmp ecx,16  
                 jnz     near .q2loop  
                 jmp     near .done  
   
   
 ;===========================================================================  
248  ;  ;
249  ; uint32_t quant4_inter_mmx(int16_t * coeff,  ; uint32_t quant_mpeg_inter_mmx(int16_t * coeff,
250  ;                                       const int16_t const * data,  ;                                       const int16_t const * data,
251  ;                                       const uint32_t quant);  ;                               const uint32_t quant,
252    ;                               const uint16_t *mpeg_matrices);
253  ;  ;
254  ;===========================================================================  ;-----------------------------------------------------------------------------
255    
256  align ALIGN  ALIGN 16
 cglobal quant_mpeg_inter_mmx  
257  quant_mpeg_inter_mmx:  quant_mpeg_inter_mmx:
258    
259                  push    ecx                  push    ecx
260                  push    esi                  push    esi
261                  push    edi                  push    edi
262      push ebx
263    
264                  mov     edi, [esp + 12 + 4]             ; coeff    mov edi, [esp + 16 + 4]       ; coeff
265                  mov     esi, [esp + 12 + 8]             ; data    mov esi, [esp + 16 + 8]       ; data
266                  mov     eax, [esp + 12 + 12]    ; quant    mov eax, [esp + 16 + 12]  ; quant
267      mov ebx, [esp + 16 + 16]              ; mpeg_quant_matrices
268    
269                  xor ecx, ecx                  xor ecx, ecx
270    
# Line 501  Line 278 
278    
279                  movq    mm7, [mmx_div + eax * 8 - 8]    ; divider                  movq    mm7, [mmx_div + eax * 8 - 8]    ; divider
280    
281  align ALIGN  ALIGN 16
282  .loop  .loop
283                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
284                  movq    mm3, [esi + 8*ecx + 8]  ;                  movq    mm3, [esi + 8*ecx + 8]  ;
# Line 513  Line 290 
290                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
291                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
292                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
293                  psllw   mm0, 4                  psllw   mm0, 4
294                  psllw   mm3, 4                  psllw   mm3, 4
295      movq mm2, [ebx + 512 + 8*ecx]
                 movq    mm2, [inter_matrix + 8*ecx]  
296                  psrlw   mm2, 1                  psrlw   mm2, 1
297                  paddw   mm0, mm2                  paddw   mm0, mm2
298      movq mm2, [ebx + 768 + ecx*8]
                 movq    mm2, [inter_matrix_fix + ecx*8]  
299                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
300      movq mm2, [ebx + 512 + 8*ecx + 8]
                 movq    mm2, [inter_matrix + 8*ecx + 8]  
301                  psrlw   mm2, 1                  psrlw   mm2, 1
302                  paddw   mm3, mm2                  paddw   mm3, mm2
303      movq mm2, [ebx + 768 + ecx*8 + 8]
                 movq    mm2, [inter_matrix_fix + ecx*8 + 8]  
304                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
305                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16
306                  pmulhw  mm3, mm7                ;                  pmulhw  mm3, mm7                ;
307                  psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17                  psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17
308                  psrlw   mm3, 1                  psrlw   mm3, 1
   
309                  paddw   mm5, mm0                ; sum += mm0                  paddw   mm5, mm0                ; sum += mm0
310                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
311                  paddw   mm5, mm3                ;                  paddw   mm5, mm3                ;
# Line 556  Line 326 
326                  paddd   mm0, mm5                  paddd   mm0, mm5
327                  movd    eax, mm0                ; return sum                  movd    eax, mm0                ; return sum
328    
329      pop ebx
330                  pop     edi                  pop     edi
331                  pop     esi                  pop     esi
332                  pop ecx                  pop ecx
333    
334                  ret                  ret
335    
336  align ALIGN  ALIGN 16
337  .q1loop  .q1loop
338                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
339                  movq    mm3, [esi + 8*ecx+ 8]                  movq    mm3, [esi + 8*ecx+ 8]
                                 ;  
340                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
341                  pxor    mm4, mm4                ;                  pxor    mm4, mm4                ;
   
342                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
343                  pcmpgtw mm4, mm3                ;                  pcmpgtw mm4, mm3                ;
   
344                  pxor    mm0, mm1                ; mm0 = |mm0|                  pxor    mm0, mm1                ; mm0 = |mm0|
345                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
346                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
347                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
348                  psllw   mm0, 4                  psllw   mm0, 4
349                  psllw   mm3, 4                  psllw   mm3, 4
350      movq mm2, [ebx + 512 + 8*ecx]
                 movq    mm2, [inter_matrix + 8*ecx]  
351                  psrlw   mm2, 1                  psrlw   mm2, 1
352                  paddw   mm0, mm2                  paddw   mm0, mm2
353      movq mm2, [ebx + 768 + ecx*8]
                 movq    mm2, [inter_matrix_fix + ecx*8]  
354                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
355      movq mm2, [ebx + 512 + 8*ecx + 8]
                 movq    mm2, [inter_matrix + 8*ecx + 8]  
356                  psrlw   mm2, 1                  psrlw   mm2, 1
357                  paddw   mm3, mm2                  paddw   mm3, mm2
358      movq mm2, [ebx + 768 + ecx*8 + 8]
                 movq    mm2, [inter_matrix_fix + ecx*8 + 8]  
359                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
360                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)
361                  psrlw   mm3, 1                  ;                  psrlw   mm3, 1                  ;
   
362                  paddw   mm5, mm0                ; sum += mm0                  paddw   mm5, mm0                ; sum += mm0
363                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
364                  paddw   mm5, mm3                ;                  paddw   mm5, mm3                ;
365                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
366                  psubw   mm0, mm1                ; undisplace                  psubw   mm0, mm1                ; undisplace
367                  psubw   mm3, mm4                  psubw   mm3, mm4
   
368                  movq    [edi + 8*ecx], mm0                  movq    [edi + 8*ecx], mm0
369                  movq    [edi + 8*ecx + 8], mm3                  movq    [edi + 8*ecx + 8], mm3
370    
# Line 614  Line 374 
374    
375                  jmp     .done                  jmp     .done
376    
377    ALIGN 16
 align ALIGN  
378  .q2loop  .q2loop
379                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
380                  movq    mm3, [esi + 8*ecx+ 8]                  movq    mm3, [esi + 8*ecx+ 8]
                                 ;  
381                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
382                  pxor    mm4, mm4                ;                  pxor    mm4, mm4                ;
   
383                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
384                  pcmpgtw mm4, mm3                ;                  pcmpgtw mm4, mm3                ;
   
385                  pxor    mm0, mm1                ; mm0 = |mm0|                  pxor    mm0, mm1                ; mm0 = |mm0|
386                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
387                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
388                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
389                  psllw   mm0, 4                  psllw   mm0, 4
390                  psllw   mm3, 4                  psllw   mm3, 4
391      movq mm2, [ebx + 512 + 8*ecx]
                 movq    mm2, [inter_matrix + 8*ecx]  
392                  psrlw   mm2, 1                  psrlw   mm2, 1
393                  paddw   mm0, mm2                  paddw   mm0, mm2
394      movq mm2, [ebx + 768 + ecx*8]
                 movq    mm2, [inter_matrix_fix + ecx*8]  
395                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
396      movq mm2, [ebx + 512 + 8*ecx + 8]
                 movq    mm2, [inter_matrix + 8*ecx + 8]  
397                  psrlw   mm2, 1                  psrlw   mm2, 1
398                  paddw   mm3, mm2                  paddw   mm3, mm2
399      movq mm2, [ebx + 768 + ecx*8 + 8]
                 movq    mm2, [inter_matrix_fix + ecx*8 + 8]  
400                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
401                  psrlw   mm0, 2                  ; mm0 >>= 1   (/2)                  psrlw   mm0, 2                  ; mm0 >>= 1   (/2)
402                  psrlw   mm3, 2                  ;                  psrlw   mm3, 2                  ;
   
403                  paddw   mm5, mm0                ; sum += mm0                  paddw   mm5, mm0                ; sum += mm0
404                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
405                  paddw   mm5, mm3                ;                  paddw   mm5, mm3                ;
406                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
407                  psubw   mm0, mm1                ; undisplace                  psubw   mm0, mm1                ; undisplace
408                  psubw   mm3, mm4                  psubw   mm3, mm4
   
409                  movq    [edi + 8*ecx], mm0                  movq    [edi + 8*ecx], mm0
410                  movq    [edi + 8*ecx + 8], mm3                  movq    [edi + 8*ecx + 8], mm3
411    
# Line 666  Line 414 
414                  jnz     near .q2loop                  jnz     near .q2loop
415    
416                  jmp     .done                  jmp     .done
417    .endfunc
418    
419    
420  ;===========================================================================  ;-----------------------------------------------------------------------------
421  ;  ;
422  ; void dequant4_intra_mmx(int16_t *data,  ; uint32_t dequant_mpeg_intra_mmx(int16_t *data,
423  ;                    const int16_t const *coeff,  ;                    const int16_t const *coeff,
424  ;                    const uint32_t quant,  ;                    const uint32_t quant,
425  ;                    const uint32_t dcscalar);  ;                                 const uint32_t dcscalar,
426    ;                                 const uint16_t *mpeg_matrices);
427  ;  ;
428  ;===========================================================================  ;-----------------------------------------------------------------------------
429    
430    ;   Note: in order to saturate 'easily', we pre-shift the quantifier    ;   Note: in order to saturate 'easily', we pre-shift the quantifier
431    ; by 4. Then, the high-word of (coeff[]*matrix[i]*quant) are used to    ; by 4. Then, the high-word of (coeff[]*matrix[i]*quant) are used to
# Line 696  Line 446 
446    psubw mm0, mm1    ; -> mm0 = abs(coeff[i]), mm1 = sign of coeff[i]    psubw mm0, mm1    ; -> mm0 = abs(coeff[i]), mm1 = sign of coeff[i]
447    
448    movq mm2, mm7     ; mm2 = quant    movq mm2, mm7     ; mm2 = quant
449    pmullw mm2,  [intra_matrix + 8*eax + 8*16 ]  ; matrix[i]*quant.    pmullw mm2, [ebx + 8*eax + 8*16 ]  ; matrix[i]*quant.
450    
451    movq mm6, mm2    movq mm6, mm2
452    pmulhw mm2, mm0   ; high of coeff*(matrix*quant)  (should be 0 if no overflow)    pmulhw mm2, mm0   ; high of coeff*(matrix*quant)  (should be 0 if no overflow)
# Line 716  Line 466 
466    
467    ;********************************************************************    ;********************************************************************
468    
469  align 16  ALIGN 16
 cglobal dequant_mpeg_intra_mmx  
470  dequant_mpeg_intra_mmx:  dequant_mpeg_intra_mmx:
471    
472    mov edx, [esp+4]  ; data    push ebx
473    mov ecx, [esp+8]  ; coeff  
474    mov eax, [esp+12] ; quant    mov edx, [esp + 4 + 4]  ; data
475      mov ecx, [esp + 4 + 8]  ; coeff
476      mov eax, [esp + 4 + 12] ; quant
477      mov ebx, [esp + 4 + 20] ; mpeg_quant_matrices
478    
479    movq mm7, [mmx_mul_quant  + eax*8 - 8]    movq mm7, [mmx_mul_quant  + eax*8 - 8]
480    mov eax, -16   ; to keep aligned, we regularly process coeff[0]    mov eax, -16      ; to keep ALIGNed, we regularly process coeff[0]
481    psllw mm7, 2   ; << 2. See comment.    psllw mm7, 2   ; << 2. See comment.
482    pxor mm6, mm6   ; this is a NOP    pxor mm6, mm6   ; this is a NOP
483    
484  align 16  ALIGN 16
485  .loop  .loop
486    movq mm0, [ecx+8*eax + 8*16]   ; mm0 = c  = coeff[i]    movq mm0, [ecx+8*eax + 8*16]   ; mm0 = c  = coeff[i]
487    movq mm3, [ecx+8*eax + 8*16 +8]; mm3 = c' = coeff[i+1]    movq mm3, [ecx+8*eax + 8*16 +8]; mm3 = c' = coeff[i+1]
# Line 739  Line 491 
491    movq mm2, mm7     ; mm2 = quant    movq mm2, mm7     ; mm2 = quant
492    
493    pcmpgtw mm4, mm3  ; mm4 = sgn(c')    pcmpgtw mm4, mm3  ; mm4 = sgn(c')
494    pmullw mm2,  [intra_matrix + 8*eax + 8*16 ]  ; matrix[i]*quant    pmullw mm2,  [ebx + 8*eax + 8*16 ]  ; matrix[i]*quant
495    
496    pxor mm0, mm1     ; negate if negative    pxor mm0, mm1     ; negate if negative
497    pxor mm3, mm4     ; negate if negative    pxor mm3, mm4     ; negate if negative
# Line 755  Line 507 
507    pmulhw mm0, mm5   ; high of coeff*(matrix*quant)    pmulhw mm0, mm5   ; high of coeff*(matrix*quant)
508    movq mm5, mm7     ; mm2 = quant    movq mm5, mm7     ; mm2 = quant
509    
510    pmullw mm5,  [intra_matrix + 8*eax + 8*16 +8]  ; matrix[i+1]*quant    pmullw mm5,  [ebx + 8*eax + 8*16 +8]  ; matrix[i+1]*quant
511    
512    movq mm6, mm5    movq mm6, mm5
513    add eax,2   ; z-flag will be tested later    add eax,2   ; z-flag will be tested later
# Line 786  Line 538 
538    jnz near .loop    jnz near .loop
539    
540      ; deal with DC      ; deal with DC
   
541    movd mm0, [ecx]    movd mm0, [ecx]
542    pmullw mm0, [esp+16]  ; dcscalar    pmullw mm0, [esp + 4 + 16]  ; dcscalar
543    movq mm2, [mmx_32767_minus_2047]    movq mm2, [mmx_32767_minus_2047]
544    paddsw mm0, mm2    paddsw mm0, mm2
545    psubsw mm0, mm2    psubsw mm0, mm2
# Line 798  Line 549 
549    movd eax, mm0    movd eax, mm0
550    mov [edx], ax    mov [edx], ax
551    
552      xor eax, eax
553    
554      pop ebx
555    
556    ret    ret
557    .endfunc
558    
559  ;===========================================================================  ;-----------------------------------------------------------------------------
560  ;  ;
561  ; void dequant4_inter_mmx(int16_t * data,  ; uint32_t dequant_mpeg_inter_mmx(int16_t * data,
562  ;                    const int16_t * const coeff,  ;                    const int16_t * const coeff,
563  ;                    const uint32_t quant);  ;                                 const uint32_t quant,
564    ;                                 const uint16_t *mpeg_matrices);
565  ;  ;
566  ;===========================================================================  ;-----------------------------------------------------------------------------
567    
568      ; Note:  We use (2*c + sgn(c) - sgn(-c)) as multiplier      ; Note:  We use (2*c + sgn(c) - sgn(-c)) as multiplier
569      ; so we handle the 3 cases: c<0, c==0, and c>0 in one shot.      ; so we handle the 3 cases: c<0, c==0, and c>0 in one shot.
570      ; sgn(x) is the result of 'pcmpgtw 0,x':  0 if x>=0, -1 if x<0.      ; sgn(x) is the result of 'pcmpgtw 0,x':  0 if x>=0, -1 if x<0.
571      ; It's mixed with the extraction of the absolute value.      ; It's mixed with the extraction of the absolute value.
572    
573  align 16  ALIGN 16
 cglobal dequant_mpeg_inter_mmx  
574  dequant_mpeg_inter_mmx:  dequant_mpeg_inter_mmx:
575    
576    mov    edx, [esp+ 4]        ; data    push ebx
577    mov    ecx, [esp+ 8]        ; coeff  
578    mov    eax, [esp+12]        ; quant    mov edx, [esp + 4 + 4]        ; data
579      mov ecx, [esp + 4 + 8]        ; coeff
580      mov eax, [esp + 4 + 12]        ; quant
581      mov ebx, [esp + 4 + 16]                  ; mpeg_quant_matrices
582    
583    movq mm7, [mmx_mul_quant  + eax*8 - 8]    movq mm7, [mmx_mul_quant  + eax*8 - 8]
584    mov eax, -16    mov eax, -16
585    paddw mm7, mm7    ; << 1    paddw mm7, mm7    ; << 1
586    pxor mm6, mm6 ; mismatch sum    pxor mm6, mm6 ; mismatch sum
587    
588  align 16  ALIGN 16
589  .loop  .loop
590    movq mm0, [ecx+8*eax + 8*16   ]   ; mm0 = coeff[i]    movq mm0, [ecx+8*eax + 8*16   ]   ; mm0 = coeff[i]
591    movq mm2, [ecx+8*eax + 8*16 +8]   ; mm2 = coeff[i+1]    movq mm2, [ecx+8*eax + 8*16 +8]   ; mm2 = coeff[i+1]
# Line 854  Line 614 
614      ; we're short on register, here. Poor pairing...      ; we're short on register, here. Poor pairing...
615    
616    movq mm4, mm7     ; (matrix*quant)    movq mm4, mm7     ; (matrix*quant)
617    pmullw mm4,  [inter_matrix + 8*eax + 8*16 -2*8]    pmullw mm4,  [ebx + 512 + 8*eax + 8*16 -2*8]
618    movq mm5, mm4    movq mm5, mm4
619    pmulhw mm5, mm0   ; high of c*(matrix*quant)    pmulhw mm5, mm0   ; high of c*(matrix*quant)
620    pmullw mm0, mm4   ; low  of c*(matrix*quant)    pmullw mm0, mm4   ; low  of c*(matrix*quant)
621    
622    movq mm4, mm7     ; (matrix*quant)    movq mm4, mm7     ; (matrix*quant)
623    pmullw mm4,  [inter_matrix + 8*eax + 8*16 -2*8 + 8]    pmullw mm4,  [ebx + 512 + 8*eax + 8*16 -2*8 + 8]
624    
625    pcmpgtw mm5, [zero]    pcmpgtw mm5, [zero]
626    paddusw mm0, mm5    paddusw mm0, mm5
# Line 903  Line 663 
663    xor eax, 1    xor eax, 1
664    xor word [edx + 2*63], ax    xor word [edx + 2*63], ax
665    
666      xor eax, eax
667    
668      pop ebx
669    
670    ret    ret
671    .endfunc
672    

Legend:
Removed from v.1.1.2.1  
changed lines
  Added in v.1.6

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