[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.4, Sun Aug 22 11:46:10 2004 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
36                            %define %1 _%1:function
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
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  
   
62    
63  ;===========================================================================  %ifdef FORMAT_COFF
64  ;  SECTION .rodata
65  ; intra matrix  %else
66  ;  SECTION .rodata align=16
67  ;===========================================================================  %endif
   
 cextern intra_matrix  
 cextern intra_matrix_fix  
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  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
95    
96  %macro MMX_QUANTD  1  quantd:
97  times 4 dw ((VM18P*%1) + (VM18Q/2)) / VM18Q  %assign quant 1
98  %endmacro  %rep 31
99            times 4 dw  ((VM18P*quant) + (VM18Q/2)) / VM18Q
100            %assign quant quant+1
101    %endrep
102    
103  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  
   
   
 ;===========================================================================  
 ;  
104  ; multiple by 2Q table  ; multiple by 2Q table
105  ;  ;-----------------------------------------------------------------------------
 ;===========================================================================  
106    
107  %macro MMX_MUL_QUANT  1  mmx_mul_quant:
108  times 4   dw  %1  %assign quant 1
109  %endmacro  %rep 31
110            times 4 dw  quant
111  mmx_mul_quant          %assign quant quant+1
112          MMX_MUL_QUANT 1  %endrep
         MMX_MUL_QUANT 2  
         MMX_MUL_QUANT 3  
         MMX_MUL_QUANT 4  
         MMX_MUL_QUANT 5  
         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    ; Code
133    ;=============================================================================
134    
135  section .text  SECTION .text
136    
137  ;===========================================================================  cglobal quant_mpeg_intra_mmx
138    cglobal quant_mpeg_inter_mmx
139    cglobal dequant_mpeg_intra_mmx
140    cglobal dequant_mpeg_inter_mmx
141    
142    ;-----------------------------------------------------------------------------
143  ;  ;
144  ; void quant_intra4_mmx(int16_t * coeff,  ; uint32_t quant_mpeg_intra_mmx(int16_t * coeff,
145  ;                                       const int16_t const * data,  ;                                       const int16_t const * data,
146  ;                                       const uint32_t quant,  ;                                       const uint32_t quant,
147  ;                                       const uint32_t dcscalar);  ;                               const uint32_t dcscalar,
148    ;                               const uint16_t *mpeg_matrices);
149  ;  ;
150  ;===========================================================================  ;-----------------------------------------------------------------------------
151    
152  align ALIGN  ALIGN 16
 cglobal quant_mpeg_intra_mmx  
153  quant_mpeg_intra_mmx:  quant_mpeg_intra_mmx:
154    
155                  push    ecx                  push    ecx
156                  push    esi                  push    esi
157                  push    edi                  push    edi
158      push ebx
159    
160                  mov     edi, [esp + 12 + 4]             ; coeff    mov edi, [esp + 16 + 4]       ; coeff
161                  mov     esi, [esp + 12 + 8]             ; data    mov esi, [esp + 16 + 8]       ; data
162                  mov     eax, [esp + 12 + 12]    ; quant    mov eax, [esp + 16 + 12]      ; quant
163      mov ebx, [esp + 16 + 20]              ; mpeg_quant_matrices
164    
165                  movq    mm5, [quantd + eax * 8 - 8] ; quantd -> mm5                  movq    mm5, [quantd + eax * 8 - 8] ; quantd -> mm5
166    
# Line 284  Line 173 
173    
174                  movq    mm7, [mmx_div + eax * 8 - 8] ; multipliers[quant] -> mm7                  movq    mm7, [mmx_div + eax * 8 - 8] ; multipliers[quant] -> mm7
175    
176  align ALIGN  ALIGN 16
177  .loop  .loop
178                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
179                  movq    mm3, [esi + 8*ecx + 8]  ;                  movq    mm3, [esi + 8*ecx + 8]  ;
   
180                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
181                  pxor    mm4, mm4                  pxor    mm4, mm4
   
182                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
183                  pcmpgtw mm4, mm3                  pcmpgtw mm4, mm3
   
184                  pxor    mm0, mm1                ; mm0 = |mm0|                  pxor    mm0, mm1                ; mm0 = |mm0|
185                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
186                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
187                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
188                  psllw   mm0, 4                  ; level << 4                  psllw   mm0, 4                  ; level << 4
189                  psllw   mm3, 4                  ;    psllw mm3, 4
190      movq mm2, [ebx + 8*ecx]
                 movq    mm2, [intra_matrix + 8*ecx]  
191                  psrlw   mm2, 1                  ; intra_matrix[i]>>1                  psrlw   mm2, 1                  ; intra_matrix[i]>>1
192                  paddw   mm0, mm2                  paddw   mm0, mm2
193      movq mm2, [ebx + 256 + ecx*8]
                 movq    mm2, [intra_matrix_fix + ecx*8]  
194                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
195      movq mm2, [ebx + 8*ecx + 8]
                 movq    mm2, [intra_matrix + 8*ecx + 8]  
196                  psrlw   mm2, 1                  psrlw   mm2, 1
197                  paddw   mm3, mm2                  paddw   mm3, mm2
198      movq mm2, [ebx + 256 + ecx*8 + 8]
                 movq    mm2, [intra_matrix_fix + ecx*8 + 8]  
199                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
200              paddw   mm0, mm5            ; + quantd              paddw   mm0, mm5            ; + quantd
201                  paddw   mm3, mm5                  paddw   mm3, mm5
   
202                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16
203                  pmulhw  mm3, mm7                ;                  pmulhw  mm3, mm7                ;
204                  psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17                  psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17
205                  psrlw   mm3, 1                  psrlw   mm3, 1
   
206                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
207                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
208                  psubw   mm0, mm1                ; undisplace                  psubw   mm0, mm1                ; undisplace
# Line 339  Line 217 
217    
218  .done  .done
219                  ; caclulate  data[0] // (int32_t)dcscalar)                  ; caclulate  data[0] // (int32_t)dcscalar)
220      mov ecx, [esp + 16 + 16]  ; dcscalar
                 mov     ecx, [esp + 12 + 16]    ; dcscalar  
221                  mov     edx, ecx                  mov     edx, ecx
222                  movsx   eax, word [esi] ; data[0]                  movsx   eax, word [esi] ; data[0]
223                  shr     edx, 1                  ; edx = dcscalar /2                  shr     edx, 1                  ; edx = dcscalar /2
# Line 357  Line 234 
234    
235                  mov     [edi], ax               ; coeff[0] = ax                  mov     [edi], ax               ; coeff[0] = ax
236    
237      pop ebx
238                  pop     edi                  pop     edi
239                  pop     esi                  pop     esi
240                  pop     ecx                  pop     ecx
241    
242      xor eax, eax              ; return(0);
243                  ret                  ret
244    
245  align ALIGN  ALIGN 16
246  .q1loop  .q1loop
247                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
248                  movq    mm3, [esi + 8*ecx + 8]  ;                  movq    mm3, [esi + 8*ecx + 8]  ;
   
249                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
250                  pxor    mm4, mm4                ;                  pxor    mm4, mm4                ;
   
251                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
252                  pcmpgtw mm4, mm3                ;                  pcmpgtw mm4, mm3                ;
   
253                  pxor    mm0, mm1                ; mm0 = |mm0|                  pxor    mm0, mm1                ; mm0 = |mm0|
254                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
255                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
256                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
257                  psllw   mm0, 4                  psllw   mm0, 4
258                  psllw   mm3, 4                  psllw   mm3, 4
259      movq mm2, [ebx + 8*ecx]
                 movq    mm2, [intra_matrix + 8*ecx]  
260                  psrlw   mm2, 1                  psrlw   mm2, 1
261                  paddw   mm0, mm2                  paddw   mm0, mm2
262      movq mm2, [ebx + 256 + ecx*8]
                 movq    mm2, [intra_matrix_fix + ecx*8]  
263                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
264      movq mm2, [ebx + 8*ecx + 8]
                 movq    mm2, [intra_matrix + 8*ecx + 8]  
265                  psrlw   mm2, 1                  psrlw   mm2, 1
266                  paddw   mm3, mm2                  paddw   mm3, mm2
267      movq mm2, [ebx + 256 + ecx*8 + 8]
                 movq    mm2, [intra_matrix_fix + ecx*8 + 8]  
268                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
269          paddw   mm0, mm5          paddw   mm0, mm5
270                  paddw   mm3, mm5                  paddw   mm3, mm5
   
271                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)
272                  psrlw   mm3, 1                  ;                  psrlw   mm3, 1                  ;
   
273                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
274                  pxor    mm3, mm4        ;                  pxor    mm3, mm4        ;
275                  psubw   mm0, mm1                ; undisplace                  psubw   mm0, mm1                ; undisplace
276                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
277                  movq    [edi + 8*ecx], mm0                  movq    [edi + 8*ecx], mm0
278                  movq    [edi + 8*ecx + 8], mm3                  movq    [edi + 8*ecx + 8], mm3
279    
# Line 416  Line 283 
283                  jmp     near .done                  jmp     near .done
284    
285    
286  align ALIGN  ALIGN 16
287  .q2loop  .q2loop
288                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
289                  movq    mm3, [esi + 8*ecx + 8]  ;                  movq    mm3, [esi + 8*ecx + 8]  ;
   
290                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
291                  pxor    mm4, mm4                ;                  pxor    mm4, mm4                ;
   
292                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
293                  pcmpgtw mm4, mm3                ;                  pcmpgtw mm4, mm3                ;
   
294                  pxor    mm0, mm1                ; mm0 = |mm0|                  pxor    mm0, mm1                ; mm0 = |mm0|
295                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
296                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
297                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
298                  psllw   mm0, 4                  psllw   mm0, 4
299                  psllw   mm3, 4                  psllw   mm3, 4
300      movq mm2, [ebx + 8*ecx]
                 movq    mm2, [intra_matrix + 8*ecx]  
301                  psrlw   mm2, 1                  psrlw   mm2, 1
302                  paddw   mm0, mm2                  paddw   mm0, mm2
303      movq mm2, [ebx + 256 + ecx*8]
                 movq    mm2, [intra_matrix_fix + ecx*8]  
304                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + intra_matrix[i]>>1) / intra_matrix[i]
305      movq mm2, [ebx + 8*ecx + 8]
                 movq    mm2, [intra_matrix + 8*ecx + 8]  
306                  psrlw   mm2, 1                  psrlw   mm2, 1
307                  paddw   mm3, mm2                  paddw   mm3, mm2
308      movq mm2, [ebx + 256 + ecx*8 + 8]
                 movq    mm2, [intra_matrix_fix + ecx*8 + 8]  
309                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
310          paddw   mm0, mm5          paddw   mm0, mm5
311                  paddw   mm3, mm5                  paddw   mm3, mm5
   
312                  psrlw   mm0, 2                  ; mm0 >>= 1   (/4)                  psrlw   mm0, 2                  ; mm0 >>= 1   (/4)
313                  psrlw   mm3, 2                  ;                  psrlw   mm3, 2                  ;
   
314                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
315                  pxor    mm3, mm4        ;                  pxor    mm3, mm4        ;
316                  psubw   mm0, mm1                ; undisplace                  psubw   mm0, mm1                ; undisplace
317                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
318                  movq    [edi + 8*ecx], mm0                  movq    [edi + 8*ecx], mm0
319                  movq    [edi + 8*ecx + 8], mm3                  movq    [edi + 8*ecx + 8], mm3
320    
# Line 469  Line 324 
324                  jmp     near .done                  jmp     near .done
325    
326    
327  ;===========================================================================  ;-----------------------------------------------------------------------------
328  ;  ;
329  ; uint32_t quant4_inter_mmx(int16_t * coeff,  ; uint32_t quant_mpeg_inter_mmx(int16_t * coeff,
330  ;                                       const int16_t const * data,  ;                                       const int16_t const * data,
331  ;                                       const uint32_t quant);  ;                               const uint32_t quant,
332    ;                               const uint16_t *mpeg_matrices);
333  ;  ;
334  ;===========================================================================  ;-----------------------------------------------------------------------------
335    
336  align ALIGN  ALIGN 16
 cglobal quant_mpeg_inter_mmx  
337  quant_mpeg_inter_mmx:  quant_mpeg_inter_mmx:
338    
339                  push    ecx                  push    ecx
340                  push    esi                  push    esi
341                  push    edi                  push    edi
342      push ebx
343    
344                  mov     edi, [esp + 12 + 4]             ; coeff    mov edi, [esp + 16 + 4]       ; coeff
345                  mov     esi, [esp + 12 + 8]             ; data    mov esi, [esp + 16 + 8]       ; data
346                  mov     eax, [esp + 12 + 12]    ; quant    mov eax, [esp + 16 + 12]  ; quant
347      mov ebx, [esp + 16 + 16]              ; mpeg_quant_matrices
348    
349                  xor ecx, ecx                  xor ecx, ecx
350    
# Line 501  Line 358 
358    
359                  movq    mm7, [mmx_div + eax * 8 - 8]    ; divider                  movq    mm7, [mmx_div + eax * 8 - 8]    ; divider
360    
361  align ALIGN  ALIGN 16
362  .loop  .loop
363                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
364                  movq    mm3, [esi + 8*ecx + 8]  ;                  movq    mm3, [esi + 8*ecx + 8]  ;
# Line 513  Line 370 
370                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
371                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
372                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
373                  psllw   mm0, 4                  psllw   mm0, 4
374                  psllw   mm3, 4                  psllw   mm3, 4
375      movq mm2, [ebx + 512 + 8*ecx]
                 movq    mm2, [inter_matrix + 8*ecx]  
376                  psrlw   mm2, 1                  psrlw   mm2, 1
377                  paddw   mm0, mm2                  paddw   mm0, mm2
378      movq mm2, [ebx + 768 + ecx*8]
                 movq    mm2, [inter_matrix_fix + ecx*8]  
379                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
380      movq mm2, [ebx + 512 + 8*ecx + 8]
                 movq    mm2, [inter_matrix + 8*ecx + 8]  
381                  psrlw   mm2, 1                  psrlw   mm2, 1
382                  paddw   mm3, mm2                  paddw   mm3, mm2
383      movq mm2, [ebx + 768 + ecx*8 + 8]
                 movq    mm2, [inter_matrix_fix + ecx*8 + 8]  
384                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
385                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16                  pmulhw  mm0, mm7                ; mm0 = (mm0 / 2Q) >> 16
386                  pmulhw  mm3, mm7                ;                  pmulhw  mm3, mm7                ;
387                  psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17                  psrlw   mm0, 1                  ; additional shift by 1 => 16 + 1 = 17
388                  psrlw   mm3, 1                  psrlw   mm3, 1
   
389                  paddw   mm5, mm0                ; sum += mm0                  paddw   mm5, mm0                ; sum += mm0
390                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
391                  paddw   mm5, mm3                ;                  paddw   mm5, mm3                ;
# Line 556  Line 406 
406                  paddd   mm0, mm5                  paddd   mm0, mm5
407                  movd    eax, mm0                ; return sum                  movd    eax, mm0                ; return sum
408    
409      pop ebx
410                  pop     edi                  pop     edi
411                  pop     esi                  pop     esi
412                  pop ecx                  pop ecx
413    
414                  ret                  ret
415    
416  align ALIGN  ALIGN 16
417  .q1loop  .q1loop
418                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
419                  movq    mm3, [esi + 8*ecx+ 8]                  movq    mm3, [esi + 8*ecx+ 8]
                                 ;  
420                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
421                  pxor    mm4, mm4                ;                  pxor    mm4, mm4                ;
   
422                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
423                  pcmpgtw mm4, mm3                ;                  pcmpgtw mm4, mm3                ;
   
424                  pxor    mm0, mm1                ; mm0 = |mm0|                  pxor    mm0, mm1                ; mm0 = |mm0|
425                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
426                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
427                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
428                  psllw   mm0, 4                  psllw   mm0, 4
429                  psllw   mm3, 4                  psllw   mm3, 4
430      movq mm2, [ebx + 512 + 8*ecx]
                 movq    mm2, [inter_matrix + 8*ecx]  
431                  psrlw   mm2, 1                  psrlw   mm2, 1
432                  paddw   mm0, mm2                  paddw   mm0, mm2
433      movq mm2, [ebx + 768 + ecx*8]
                 movq    mm2, [inter_matrix_fix + ecx*8]  
434                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
435      movq mm2, [ebx + 512 + 8*ecx + 8]
                 movq    mm2, [inter_matrix + 8*ecx + 8]  
436                  psrlw   mm2, 1                  psrlw   mm2, 1
437                  paddw   mm3, mm2                  paddw   mm3, mm2
438      movq mm2, [ebx + 768 + ecx*8 + 8]
                 movq    mm2, [inter_matrix_fix + ecx*8 + 8]  
439                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
440                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)                  psrlw   mm0, 1                  ; mm0 >>= 1   (/2)
441                  psrlw   mm3, 1                  ;                  psrlw   mm3, 1                  ;
   
442                  paddw   mm5, mm0                ; sum += mm0                  paddw   mm5, mm0                ; sum += mm0
443                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
444                  paddw   mm5, mm3                ;                  paddw   mm5, mm3                ;
445                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
446                  psubw   mm0, mm1                ; undisplace                  psubw   mm0, mm1                ; undisplace
447                  psubw   mm3, mm4                  psubw   mm3, mm4
   
448                  movq    [edi + 8*ecx], mm0                  movq    [edi + 8*ecx], mm0
449                  movq    [edi + 8*ecx + 8], mm3                  movq    [edi + 8*ecx + 8], mm3
450    
# Line 615  Line 455 
455                  jmp     .done                  jmp     .done
456    
457    
458  align ALIGN  ALIGN 16
459  .q2loop  .q2loop
460                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]                  movq    mm0, [esi + 8*ecx]              ; mm0 = [1st]
461                  movq    mm3, [esi + 8*ecx+ 8]                  movq    mm3, [esi + 8*ecx+ 8]
                                 ;  
462                  pxor    mm1, mm1                ; mm1 = 0                  pxor    mm1, mm1                ; mm1 = 0
463                  pxor    mm4, mm4                ;                  pxor    mm4, mm4                ;
   
464                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)                  pcmpgtw mm1, mm0                ; mm1 = (0 > mm0)
465                  pcmpgtw mm4, mm3                ;                  pcmpgtw mm4, mm3                ;
   
466                  pxor    mm0, mm1                ; mm0 = |mm0|                  pxor    mm0, mm1                ; mm0 = |mm0|
467                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
468                  psubw   mm0, mm1                ; displace                  psubw   mm0, mm1                ; displace
469                  psubw   mm3, mm4                ;                  psubw   mm3, mm4                ;
   
470                  psllw   mm0, 4                  psllw   mm0, 4
471                  psllw   mm3, 4                  psllw   mm3, 4
472      movq mm2, [ebx + 512 + 8*ecx]
                 movq    mm2, [inter_matrix + 8*ecx]  
473                  psrlw   mm2, 1                  psrlw   mm2, 1
474                  paddw   mm0, mm2                  paddw   mm0, mm2
475      movq mm2, [ebx + 768 + ecx*8]
                 movq    mm2, [inter_matrix_fix + ecx*8]  
476                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]                  pmulhw  mm0, mm2                ; (level<<4 + inter_matrix[i]>>1) / inter_matrix[i]
477      movq mm2, [ebx + 512 + 8*ecx + 8]
                 movq    mm2, [inter_matrix + 8*ecx + 8]  
478                  psrlw   mm2, 1                  psrlw   mm2, 1
479                  paddw   mm3, mm2                  paddw   mm3, mm2
480      movq mm2, [ebx + 768 + ecx*8 + 8]
                 movq    mm2, [inter_matrix_fix + ecx*8 + 8]  
481                  pmulhw  mm3, mm2                  pmulhw  mm3, mm2
   
482                  psrlw   mm0, 2                  ; mm0 >>= 1   (/2)                  psrlw   mm0, 2                  ; mm0 >>= 1   (/2)
483                  psrlw   mm3, 2                  ;                  psrlw   mm3, 2                  ;
   
484                  paddw   mm5, mm0                ; sum += mm0                  paddw   mm5, mm0                ; sum += mm0
485                  pxor    mm0, mm1                ; mm0 *= sign(mm0)                  pxor    mm0, mm1                ; mm0 *= sign(mm0)
486                  paddw   mm5, mm3                ;                  paddw   mm5, mm3                ;
487                  pxor    mm3, mm4                ;                  pxor    mm3, mm4                ;
488                  psubw   mm0, mm1                ; undisplace                  psubw   mm0, mm1                ; undisplace
489                  psubw   mm3, mm4                  psubw   mm3, mm4
   
490                  movq    [edi + 8*ecx], mm0                  movq    [edi + 8*ecx], mm0
491                  movq    [edi + 8*ecx + 8], mm3                  movq    [edi + 8*ecx + 8], mm3
492    
# Line 668  Line 497 
497                  jmp     .done                  jmp     .done
498    
499    
500  ;===========================================================================  ;-----------------------------------------------------------------------------
501  ;  ;
502  ; void dequant4_intra_mmx(int16_t *data,  ; uint32_t dequant_mpeg_intra_mmx(int16_t *data,
503  ;                    const int16_t const *coeff,  ;                    const int16_t const *coeff,
504  ;                    const uint32_t quant,  ;                    const uint32_t quant,
505  ;                    const uint32_t dcscalar);  ;                                 const uint32_t dcscalar,
506    ;                                 const uint16_t *mpeg_matrices);
507  ;  ;
508  ;===========================================================================  ;-----------------------------------------------------------------------------
509    
510    ;   Note: in order to saturate 'easily', we pre-shift the quantifier    ;   Note: in order to saturate 'easily', we pre-shift the quantifier
511    ; 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 526 
526    psubw mm0, mm1    ; -> mm0 = abs(coeff[i]), mm1 = sign of coeff[i]    psubw mm0, mm1    ; -> mm0 = abs(coeff[i]), mm1 = sign of coeff[i]
527    
528    movq mm2, mm7     ; mm2 = quant    movq mm2, mm7     ; mm2 = quant
529    pmullw mm2,  [intra_matrix + 8*eax + 8*16 ]  ; matrix[i]*quant.    pmullw mm2, [ebx + 8*eax + 8*16 ]  ; matrix[i]*quant.
530    
531    movq mm6, mm2    movq mm6, mm2
532    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 546 
546    
547    ;********************************************************************    ;********************************************************************
548    
549  align 16  ALIGN 16
 cglobal dequant_mpeg_intra_mmx  
550  dequant_mpeg_intra_mmx:  dequant_mpeg_intra_mmx:
551    
552    mov edx, [esp+4]  ; data    push ebx
553    mov ecx, [esp+8]  ; coeff  
554    mov eax, [esp+12] ; quant    mov edx, [esp + 4 + 4]  ; data
555      mov ecx, [esp + 4 + 8]  ; coeff
556      mov eax, [esp + 4 + 12] ; quant
557      mov ebx, [esp + 4 + 20] ; mpeg_quant_matrices
558    
559    movq mm7, [mmx_mul_quant  + eax*8 - 8]    movq mm7, [mmx_mul_quant  + eax*8 - 8]
560    mov eax, -16   ; to keep aligned, we regularly process coeff[0]    mov eax, -16      ; to keep ALIGNed, we regularly process coeff[0]
561    psllw mm7, 2   ; << 2. See comment.    psllw mm7, 2   ; << 2. See comment.
562    pxor mm6, mm6   ; this is a NOP    pxor mm6, mm6   ; this is a NOP
563    
564  align 16  ALIGN 16
565  .loop  .loop
566    movq mm0, [ecx+8*eax + 8*16]   ; mm0 = c  = coeff[i]    movq mm0, [ecx+8*eax + 8*16]   ; mm0 = c  = coeff[i]
567    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 571 
571    movq mm2, mm7     ; mm2 = quant    movq mm2, mm7     ; mm2 = quant
572    
573    pcmpgtw mm4, mm3  ; mm4 = sgn(c')    pcmpgtw mm4, mm3  ; mm4 = sgn(c')
574    pmullw mm2,  [intra_matrix + 8*eax + 8*16 ]  ; matrix[i]*quant    pmullw mm2,  [ebx + 8*eax + 8*16 ]  ; matrix[i]*quant
575    
576    pxor mm0, mm1     ; negate if negative    pxor mm0, mm1     ; negate if negative
577    pxor mm3, mm4     ; negate if negative    pxor mm3, mm4     ; negate if negative
# Line 755  Line 587 
587    pmulhw mm0, mm5   ; high of coeff*(matrix*quant)    pmulhw mm0, mm5   ; high of coeff*(matrix*quant)
588    movq mm5, mm7     ; mm2 = quant    movq mm5, mm7     ; mm2 = quant
589    
590    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
591    
592    movq mm6, mm5    movq mm6, mm5
593    add eax,2   ; z-flag will be tested later    add eax,2   ; z-flag will be tested later
# Line 786  Line 618 
618    jnz near .loop    jnz near .loop
619    
620      ; deal with DC      ; deal with DC
   
621    movd mm0, [ecx]    movd mm0, [ecx]
622    pmullw mm0, [esp+16]  ; dcscalar    pmullw mm0, [esp + 4 + 16]  ; dcscalar
623    movq mm2, [mmx_32767_minus_2047]    movq mm2, [mmx_32767_minus_2047]
624    paddsw mm0, mm2    paddsw mm0, mm2
625    psubsw mm0, mm2    psubsw mm0, mm2
# Line 798  Line 629 
629    movd eax, mm0    movd eax, mm0
630    mov [edx], ax    mov [edx], ax
631    
632      xor eax, eax
633    
634      pop ebx
635    
636    ret    ret
637    
638  ;===========================================================================  ;-----------------------------------------------------------------------------
639  ;  ;
640  ; void dequant4_inter_mmx(int16_t * data,  ; uint32_t dequant_mpeg_inter_mmx(int16_t * data,
641  ;                    const int16_t * const coeff,  ;                    const int16_t * const coeff,
642  ;                    const uint32_t quant);  ;                                 const uint32_t quant,
643    ;                                 const uint16_t *mpeg_matrices);
644  ;  ;
645  ;===========================================================================  ;-----------------------------------------------------------------------------
646    
647      ; Note:  We use (2*c + sgn(c) - sgn(-c)) as multiplier      ; Note:  We use (2*c + sgn(c) - sgn(-c)) as multiplier
648      ; 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.
649      ; 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.
650      ; It's mixed with the extraction of the absolute value.      ; It's mixed with the extraction of the absolute value.
651    
652  align 16  ALIGN 16
 cglobal dequant_mpeg_inter_mmx  
653  dequant_mpeg_inter_mmx:  dequant_mpeg_inter_mmx:
654    
655    mov    edx, [esp+ 4]        ; data    push ebx
656    mov    ecx, [esp+ 8]        ; coeff  
657    mov    eax, [esp+12]        ; quant    mov edx, [esp + 4 + 4]        ; data
658      mov ecx, [esp + 4 + 8]        ; coeff
659      mov eax, [esp + 4 + 12]        ; quant
660      mov ebx, [esp + 4 + 16]                  ; mpeg_quant_matrices
661    
662    movq mm7, [mmx_mul_quant  + eax*8 - 8]    movq mm7, [mmx_mul_quant  + eax*8 - 8]
663    mov eax, -16    mov eax, -16
664    paddw mm7, mm7    ; << 1    paddw mm7, mm7    ; << 1
665    pxor mm6, mm6 ; mismatch sum    pxor mm6, mm6 ; mismatch sum
666    
667  align 16  ALIGN 16
668  .loop  .loop
669    movq mm0, [ecx+8*eax + 8*16   ]   ; mm0 = coeff[i]    movq mm0, [ecx+8*eax + 8*16   ]   ; mm0 = coeff[i]
670    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 693 
693      ; we're short on register, here. Poor pairing...      ; we're short on register, here. Poor pairing...
694    
695    movq mm4, mm7     ; (matrix*quant)    movq mm4, mm7     ; (matrix*quant)
696    pmullw mm4,  [inter_matrix + 8*eax + 8*16 -2*8]    pmullw mm4,  [ebx + 512 + 8*eax + 8*16 -2*8]
697    movq mm5, mm4    movq mm5, mm4
698    pmulhw mm5, mm0   ; high of c*(matrix*quant)    pmulhw mm5, mm0   ; high of c*(matrix*quant)
699    pmullw mm0, mm4   ; low  of c*(matrix*quant)    pmullw mm0, mm4   ; low  of c*(matrix*quant)
700    
701    movq mm4, mm7     ; (matrix*quant)    movq mm4, mm7     ; (matrix*quant)
702    pmullw mm4,  [inter_matrix + 8*eax + 8*16 -2*8 + 8]    pmullw mm4,  [ebx + 512 + 8*eax + 8*16 -2*8 + 8]
703    
704    pcmpgtw mm5, [zero]    pcmpgtw mm5, [zero]
705    paddusw mm0, mm5    paddusw mm0, mm5
# Line 903  Line 742 
742    xor eax, 1    xor eax, 1
743    xor word [edx + 2*63], ax    xor word [edx + 2*63], ax
744    
745    ret    xor eax, eax
746    
747      pop ebx
748    
749      ret

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

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